From 06816cf07df480876f8d6d1a0730318e41ce7092 Mon Sep 17 00:00:00 2001 From: akool Date: Sun, 8 Mar 1998 18:54:01 +0000 Subject: [PATCH] New Version of "xisdnload" by Frank Strauss (strauss@escape.de) --- xisdnload/Imakefile | 5 +- xisdnload/XISDNLoad.ad | 7 +- xisdnload/xisdnload.c | 270 ++++++++++++++++++++++++++++++++++------ xisdnload/xisdnload.man | 58 ++++++--- 4 files changed, 289 insertions(+), 51 deletions(-) diff --git a/xisdnload/Imakefile b/xisdnload/Imakefile index 327e1299..25d2fabc 100644 --- a/xisdnload/Imakefile +++ b/xisdnload/Imakefile @@ -21,7 +21,7 @@ LOCAL_LIBRARIES = XawClientLibs OBJS = xisdnload.o OSMAJORVERSION = OSMajorVersion OSMINORVERSION = OSMinorVersion - DEFINES = -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) + DEFINES = -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) -DREGEX_NUMBER AllTarget(xisdnload) NormalProgramTarget(xisdnload,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),NullParameter) @@ -31,3 +31,6 @@ InstallAppDefaults(XISDNLoad) InstallManPage(xisdnload,$(MANDIR)) DependTarget() + +dist: + tar cvzCf .. ../`basename \`pwd\``.tar.gz `basename \`pwd\`` diff --git a/xisdnload/XISDNLoad.ad b/xisdnload/XISDNLoad.ad index 7761881e..3f12e2c2 100644 --- a/xisdnload/XISDNLoad.ad +++ b/xisdnload/XISDNLoad.ad @@ -1,6 +1,6 @@ XISDNLoad.geometry: 250x100 *Label*Justify: left -*Label*Label: %7s %3d:%02d %4.0fcps %ldkB +*Label*Label: %7s %3d:%02d %4.0fcps %ldkB - %-100s ! *minScale: 8 *minScale: 1 *JumpScroll: 1 @@ -8,3 +8,8 @@ XISDNLoad.geometry: 250x100 *internalBorderWidth: 0 *showGrip: FALSE *onlineColor: red +*tryingColor: yellow +*activeColor: green +! *activate: sudo route add default dev isdn2 & +! *deactivate: sudo route del default ; root isdnctrl hangup isdn2 & +*number: .* diff --git a/xisdnload/xisdnload.c b/xisdnload/xisdnload.c index d7a3d124..33e2d304 100644 --- a/xisdnload/xisdnload.c +++ b/xisdnload/xisdnload.c @@ -51,6 +51,10 @@ from the X Consortium. #include #include +#ifdef REGEX_NUMBER +#include +#endif + #include "xisdnload.bit" char *ProgramName; @@ -64,6 +68,13 @@ static void quit(); typedef struct _XISDNLoadResources { Boolean show_label; char *online_color; + char *active_color; + char *trying_color; + char *activate; + char *deactivate; +#ifdef REGEX_NUMBER + char *number; +#endif } XISDNLoadResources; /* @@ -80,6 +91,13 @@ static XrmOptionDescRec options[] = { {"-nolabel", "*showLabel", XrmoptionNoArg, "False"}, {"-jumpscroll", "*load.jumpScroll", XrmoptionSepArg, NULL}, {"-online", "*onlineColor", XrmoptionSepArg, NULL}, + {"-trying", "*tryingColor", XrmoptionSepArg, NULL}, + {"-active", "*activeColor", XrmoptionSepArg, NULL}, + {"-activate", "*activate", XrmoptionSepArg, NULL}, + {"-deactivate", "*deactivate", XrmoptionSepArg, NULL}, +#ifdef REGEX_NUMBER + {"-number", "*number", XrmoptionSepArg, NULL}, +#endif }; /* @@ -94,6 +112,18 @@ static XtResource my_resources[] = { Offset(show_label), XtRImmediate, (XtPointer) TRUE}, {"onlineColor", "OnlineColor", XtRString, sizeof(char *), Offset(online_color), XtRString, NULL}, + {"activeColor", "ActiveColor", XtRString, sizeof(char *), + Offset(active_color), XtRString, NULL}, + {"tryingColor", "TryingColor", XtRString, sizeof(char *), + Offset(trying_color), XtRString, NULL}, + {"activate", "Activate", XtRString, sizeof(char *), + Offset(activate), XtRString, NULL}, + {"deactivate", "Deactivate", XtRString, sizeof(char *), + Offset(deactivate), XtRString, NULL}, +#ifdef REGEX_NUMBER + {"number", "Number", XtRString, sizeof(char *), + Offset(number), XtRString, NULL}, +#endif }; #undef Offset @@ -111,18 +141,23 @@ typedef struct { } Siobytes; static Siobytes iobytes[ISDN_MAX_CHANNELS]; -static Pixel onlinecolor, bgcolor; +static Pixel onlinecolor, activecolor, tryingcolor, bgcolor; static long last[ISDN_MAX_CHANNELS]; static int usageflags[ISDN_MAX_CHANNELS]; +static int flags[ISDN_MAX_CHANNELS]; static char phone[ISDN_MAX_CHANNELS][20]; -static int fd; +static int fd_isdninfo; static Widget label_wid; static char label_format[80]; static int online_now, online_last; +static int trying_now, trying_last; static struct timeval tv_start, tv_last; static long bytes_last, bytes_total, bytes_now; static int secs_running; -static char num[20]; +static char num[100], history[160]; +#ifdef REGEX_NUMBER +static regex_t preg; +#endif /* * Exit with message describing command line format. @@ -152,36 +187,72 @@ void usage() " -hl color scale and text color\n"); fprintf (stderr, " -online color background color when online\n"); + fprintf (stderr, + " -active color background color when active for demand dialing\n"); fprintf (stderr, " -nolabel removes the label from above the chart.\n"); fprintf (stderr, " -jumpscroll value number of pixels to scroll on overflow\n"); + fprintf (stderr, + " -activate string exec this to activate demand dialing\n"); + fprintf (stderr, + " -deactivate string exec this to deactivate demand dialing\n"); +#ifdef REGEX_NUMBER + fprintf (stderr, + " -number string regexp to match against number to watch\n"); +#endif fprintf (stderr, "\n"); exit(1); } +int get_active() +{ + static char buf[8192]; + int l; + int fd_route; + int res = 0; + + fd_route = open("/proc/net/route", O_RDONLY | O_NDELAY); + if (fd_route < 0) { + perror("/proc/net/route"); + exit(1); + } + if ((l = read(fd_route, buf, sizeof(buf))) > 0) { + buf[l] = 0; + if (strstr(buf, "isdn") || strstr(buf, "ippp")) + res = 1; + } + close(fd_route); + + return res; +} + + + void InitLoadPoint() { int i; - fd = open("/dev/isdninfo", O_RDONLY | O_NDELAY); - if (fd < 0) { + fd_isdninfo = open("/dev/isdninfo", O_RDONLY | O_NDELAY); + if (fd_isdninfo < 0) { perror("/dev/isdninfo"); exit(1); } - for (i=0; i < ISDN_MAX_CHANNELS; i++) { + for (i = 0; i < ISDN_MAX_CHANNELS; i++) { iobytes[i].ibytes = 0; iobytes[i].obytes = 0; strcpy(phone[i], "???"); last[i] = 0; usageflags[i] = 0; } - online_last = -1; + online_last = 0; online_now = -1; + trying_last = -1; + trying_now = -1; gettimeofday(&tv_last, NULL); tv_last.tv_sec--; /* avoid devision by zero */ tv_start = tv_last; @@ -189,7 +260,7 @@ InitLoadPoint() bytes_total = 0; bytes_now = 0; secs_running = 0; - strcpy(num, "???"); + strcpy(num, ""); } @@ -201,30 +272,39 @@ XtPointer closure; XtPointer call_data; /* pointer to (double) return value */ { double *loadavg = (double *)call_data; - double cps = 0.0; + double cps; int idx; - int get_iobytes; + int get_iobytes, l; char buf[4096]; char s[120]; + char f[80]; + time_t t; struct timeval tv_now, tv; + struct tm *tm; + char now[20]; long bytes_delta; fd_set fds; int secs_delta; Arg args[1]; - int res; gettimeofday(&tv_now, NULL); secs_delta = (tv_now.tv_sec + tv_now.tv_usec / 1000000) - (tv_last.tv_sec + tv_last.tv_usec / 1000000); tv_last = tv_now; - if (read(fd, buf, sizeof(buf))> 0) { + if (read(fd_isdninfo, buf, sizeof(buf)) > 0) { sscanf(strstr(buf, "usage:"), "usage: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", &usageflags[0], &usageflags[1], &usageflags[2], &usageflags[3], &usageflags[4], &usageflags[5], &usageflags[6], &usageflags[7], &usageflags[8], &usageflags[9], &usageflags[10], &usageflags[11], &usageflags[12], &usageflags[13], &usageflags[14], &usageflags[15]); + sscanf(strstr(buf, "flags:"), + "flags: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", + &flags[0], &flags[1], &flags[2], &flags[3], + &flags[4], &flags[5], &flags[6], &flags[7], + &flags[8], &flags[8], &flags[10], &flags[11], + &flags[12], &flags[13], &flags[14], &flags[15]); sscanf(strstr(buf, "phone:"), "phone: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", phone[0], phone[1], phone[2], phone[3], @@ -234,19 +314,47 @@ XtPointer call_data; /* pointer to (double) return value */ } get_iobytes = 1; - for (online_now = 0, bytes_now = 0, idx = 0; idx < 16; idx++) { + strcpy(num, ""); + for (online_now = 0, trying_now = 0, bytes_now = 0, idx = 0; idx < 16; idx++) { if (usageflags[idx]) { - online_now = 1; - if (get_iobytes) { - if (ioctl(fd,IIOCGETCPS,&iobytes)) - perror("IIOCGETCPS"); - get_iobytes = 0; +#ifdef REGEX_NUMBER + if (!regexec(&preg, phone[idx], 0, NULL, 0)) { +#endif + if (flags[idx]) { + online_now++; + if (get_iobytes) { + if (ioctl(fd_isdninfo, IIOCGETCPS, &iobytes)) + perror("IIOCGETCPS"); + get_iobytes = 0; + } + bytes_now += iobytes[idx].ibytes + iobytes[idx].obytes; + if (!strlen(num)) { + strcpy(num, phone[idx]); + } else { + strcat(num, " "); + strcat(num, phone[idx]); + } + } else { + trying_now++; + if (!strlen(num)) { + strcpy(num, "("); + strcat(num, phone[idx]); + strcat(num, ")"); + } else { + strcat(num, " ("); + strcat(num, phone[idx]); + strcat(num, ")"); + } + } +#ifdef REGEX_NUMBER } - bytes_now += iobytes[idx].ibytes + iobytes[idx].obytes; - strcpy(num, phone[idx]); +#endif } } + if (!online_now) + online_now = - get_active(); + bytes_delta = bytes_now - bytes_last; bytes_last = bytes_now; @@ -255,47 +363,80 @@ XtPointer call_data; /* pointer to (double) return value */ (tv_start.tv_sec + tv_start.tv_usec / 1000000); cps = (double)bytes_delta / (double)secs_delta; if (cps < 0.0) cps = 0.0; - if (cps > 8000.0) cps = 8000.0; + /* if (cps > 8000.0) cps = 8000.0; */ bytes_total = bytes_now; - if (online_last != 1) { + if (online_last < 1) { + t = time(NULL); + tm = localtime(&t); + sprintf(now, "%.2d:%.2d:%.2d", tm->tm_hour, tm->tm_min, tm->tm_sec); + strcpy(history, now); + strcat(history, "-"); tv_start = tv_now; - online_last = 1; - XtSetArg(args[0], XtNbackground, onlinecolor); + XtSetArg(args[0], XtNbackground, trying_now ? tryingcolor : onlinecolor); XtSetValues(w, args, 1); } if (resources.show_label) { - sprintf(s, label_format, num, - secs_running / 60, secs_running % 60, cps, bytes_total / 1024); + t = time(NULL); + tm = localtime(&t); + sprintf(now, "%.2d:%.2d:%.2d", tm->tm_hour, tm->tm_min, tm->tm_sec); + sprintf(f, "%s%%s", label_format); + sprintf(s, f, num, + secs_running / 60, secs_running % 60, cps, + bytes_total / 1024, history, now); XtSetArg (args[0], XtNlabel, s); XtSetValues (label_wid, args, ONE); } - } else { - if (online_last != 0) { - online_last = 0; - XtSetArg(args[0], XtNbackground, bgcolor); - XtSetValues(w, args, 1); + } else if ((online_now != online_last) || (trying_now != trying_last)) { + if (online_last >= 1) { if (resources.show_label) { if (secs_running > 0) { + t = time(NULL); + tm = localtime(&t); + sprintf(now, "%.2d:%.2d:%.2d", tm->tm_hour, tm->tm_min, tm->tm_sec); + strcat(history, now); + strcat(history, " "); sprintf(s, label_format, "offline", secs_running / 60, secs_running % 60, (double)bytes_total / (double)secs_running, - bytes_total / 1024); + bytes_total / 1024, history); } else { - sprintf(s, "uninitialized"); + sprintf(s, "uninitialized %s", history); } XtSetArg (args[0], XtNlabel, s); XtSetValues (label_wid, args, ONE); } } + if (online_now == 0) { + XtSetArg(args[0], XtNbackground, trying_now ? tryingcolor : bgcolor); + XtSetValues(w, args, 1); + } else { + XtSetArg(args[0], XtNbackground, trying_now ? tryingcolor : activecolor); + XtSetValues(w, args, 1); + } } + online_last = online_now; + trying_last = trying_now; *loadavg = cps / 1000.0; /* unit: 1000Bytes/sec */ } -void main(argc, argv) +void ToggleActive(Widget w, XtPointer p, XEvent *e, Boolean *c) +{ + if (e->type == ButtonPress) { + if (get_active()) { + system(resources.deactivate); + } else { + system(resources.activate); + } + } +} + + + +int main(argc, argv) int argc; char **argv; { @@ -305,7 +446,15 @@ void main(argc, argv) Pixmap icon_pixmap = None; char *label, host[256]; XrmValue namein, pixelout; + time_t t; + struct tm *tm; + char now[20]; + int a; + t = time(NULL); + tm = localtime(&t); + sprintf(now, "%.2d:%.2d:%.2d", tm->tm_hour, tm->tm_min, tm->tm_sec); + sprintf(history, "(%s) ", now); ProgramName = argv[0]; @@ -324,6 +473,18 @@ void main(argc, argv) my_resources, XtNumber(my_resources), NULL, (Cardinal) 0); +#ifdef REGEX_NUMBER + if (resources.number) { + a = regcomp(&preg, resources.number, REG_EXTENDED); + } else { + a = regcomp(&preg, "", REG_EXTENDED); + } + if (a) { + fprintf(stderr, "illegal number regexp `%s'.\n", resources.number); + exit(1); + } +#endif + /* * This is a hack so that f.delete will do something useful in this * single-window application. @@ -355,7 +516,8 @@ void main(argc, argv) strcpy(label_format, label); - XtSetArg (args[0], XtNlabel, "uninitialized"); + sprintf(now, "uninitialized %s", history); + XtSetArg (args[0], XtNlabel, now); XtSetValues (label_wid, args, ONE); load_parent = pane; @@ -373,13 +535,49 @@ void main(argc, argv) namein.addr = resources.online_color; namein.size = strlen(resources.online_color) + 1; XtConvert(load, XtRString, &namein, XtRPixel, &pixelout); + if (!pixelout.addr) { + fprintf(stderr, "could not convert online color `%s'.\n", + resources.online_color); + exit(1); + } onlinecolor = *(Pixel*)(pixelout.addr); } else { onlinecolor = bgcolor; } + if (resources.trying_color) { + namein.addr = resources.trying_color; + namein.size = strlen(resources.trying_color) + 1; + XtConvert(load, XtRString, &namein, XtRPixel, &pixelout); + if (!pixelout.addr) { + fprintf(stderr, "could not convert trying color `%s'.\n", + resources.online_color); + exit(1); + } + tryingcolor = *(Pixel*)(pixelout.addr); + } else { + tryingcolor = bgcolor; + } + + if (resources.active_color) { + namein.addr = resources.active_color; + namein.size = strlen(resources.active_color) + 1; + XtConvert(load, XtRString, &namein, XtRPixel, &pixelout); + if (!pixelout.addr) { + fprintf(stderr, "could not convert active color `%s'.\n", + resources.online_color); + exit(1); + } + activecolor = *(Pixel*)(pixelout.addr); + } else { + activecolor = bgcolor; + } + XtAddCallback(load, XtNgetValue, GetLoadPoint, NULL); + XtAddEventHandler(toplevel, ButtonPressMask, ButtonPressMask, + ToggleActive, NULL); + XtRealizeWidget (toplevel); wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW", @@ -388,6 +586,8 @@ void main(argc, argv) &wm_delete_window, 1); XtAppMainLoop(app_con); + + return 0; } static void quit (w, event, params, num_params) diff --git a/xisdnload/xisdnload.man b/xisdnload/xisdnload.man index 7ab5bbf6..490f807c 100644 --- a/xisdnload/xisdnload.man +++ b/xisdnload/xisdnload.man @@ -4,9 +4,7 @@ xisdnload \- ISDN load average display for X .SH SYNOPSIS .ta 6n -\fBxisdnload\fP [-\fItoolkitoption\fP ...] [-scale \fIinteger\fP] [-update \fIseconds\fP] [-hl \fIcolor\fP] [-highlight \fIcolor\fP] [-online \fIcolor\fP] -.br - [-jumpscroll \fIpixels\fP] [-label \fIstring\fP] [-nolabel] +\fBxisdnload\fP [-\fItoolkitoption\fP ...] [-scale \fIinteger\fP] [-update \fIseconds\fP] [-hl \fIcolor\fP] [-highlight \fIcolor\fP] [-online \fIcolor\fP] [-active \fIcolor\fP] [-trying \fIcolor\fP] [-activate \fIcommand\fP] [-deactivate \fIcommand\fP] [-jumpscroll \fIpixels\fP] [-number \fIregexp\fP] [-label \fIstring\fP] [-nolabel] .SH DESCRIPTION The .I xisdnload @@ -26,6 +24,14 @@ This option specifies the color of the scale lines. This option specifies the background color when one or more ISDN channels are online. .TP 8 +.B \-active \fIcolor\fP +This option specifies the background color when any route is found that is +directed to an interface named isdn* or ippp*. +.TP 8 +.B \-trying \fIcolor\fP +This option specifies the background color when at least one attempt +to setup a cennection is pending. +.TP 8 .B \-jumpscroll \fPnumber of pixels\fP The number of pixels to shift the graph to the left when the graph reaches the right edge of the window. The default value is 1/2 the width @@ -35,8 +41,8 @@ of the current window. Smooth scrolling can be achieved by setting it to 1. The string to put into the label above the load average when beeing online. It is interpreted as a standard format string and may contain the dialed number (%s), the minutes (%d) and seconds (%d) being -online, the actual cps rate (%f) and the amount of kbytes transfered -(%d) in this sequence. +online, the actual cps rate (%f), the amount of kbytes transfered +(%d) and a connection history (%s) in this sequence. .TP 8 .B \-nolabel If this command line option is specified then no label will be @@ -53,12 +59,27 @@ use fewer than this number. The default is 1. This option specifies the interval in seconds at which \fIxisdnload\fP updates its display. The minimum amount of time allowed between updates is 1 second. The default is 10. -.SH RESOURCES -In addition to the resources available to each of the widgets used by -\fIxisdnload\fP there is one resource defined by the application itself. +.PP .TP 8 -.B showLabel (\fPclass\fB Boolean) -If False then no label will be displayed. +.B \-activate \fIcommand\fP +This option specifies a command to be executed when +dial-on-demand is not active and you clicked on the xisdnload +stripchart. A typical command might be something like +`sudo /etc/init.d/isdn start' to start up your connection. +.PP +.TP 8 +.B \-deactivate \fIcommand\fP +This option specifies a command to be executed when +dial-on-demand is active and you clicked on the xisdnload +stripchart. A typical command might be something like +`sudo /etc/init.d/isdn stop' to shut down your connection. +.PP +.TP 8 +.B \-number \fIregexp\fP +The supplied regular expression is used to limit the set numbers +to be observed by \fIxisdnload\fP. +.SH RESOURCES +See the resource file for the available resources. .SH WIDGETS In order to specify resources, it is useful to know the hierarchy of the widgets which compose \fIxisdnload\fR. In the notation below, @@ -83,7 +104,11 @@ to get the default host and display number. to get the name of a resource file that overrides the global resources stored in the RESOURCE_MANAGER property. .SH FILES -/lib/X11/app-defaults/XISDNLoad - specifies required resources +/lib/X11/app-defaults/XISDNLoad - specifies required resources. +.br +/proc/net/route - kernel routing table. The proc filesystem is needed +by xisdnload to detect wheather a dial-on-demand is active. +.br .SH SEE ALSO X(1), xrdb(1), xload(1), mem(4), Athena StripChart Widget. .SH BUGS @@ -95,6 +120,11 @@ See \fIX(1)\fP for a full statement of rights and permissions. .SH AUTHORS Besides the basic xload stuff, the ISDN parts are added by .br -Frank Strauss (escape e.V., Braunschweig, Germany). -.br -strauss@escape.de +Frank Strauss +(escape e.V., Braunschweig, Germany). In January 1998 +Michael Deindl contributed the `yellow' +patch to make xisdnload recognize the phase of trying to connect +and show this by a different background color. +Markus Pilzecker detected a bug in +the color assignment code resulting in seg faults which has been +fixed in January 1998.