* - plot the process table, by process size, cpu usage, or total time;
* - plot the logged on users by idle time or cpu usage.
*
- * Copyright (C) 1998 by Stephen Martin (smartin@canada.com).
+ * Copyright (C) 1998, 2001
+ * by Stephen Martin (smartin@vanderfleet-martin.net).
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
- * $Revision: 1.7 $
+ * $Revision: 1.18 $
*
* Version 1.0 April 27, 1998.
* - Initial version
* - Now need to define HAVE_PING to compile in the ping stuff.
*/
-/* Define one of these, as appropriate.
- We should make configure detect this, one of these days.
+/* These are computed by configure now:
+ #define HAVE_ICMP
+ #define HAVE_ICMPHDR
*/
-/* #define HAVE_ICMP */
-/* #define HAVE_ICMPHDR */
/* Include Files */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
+#include <sys/stat.h>
+
+#include "screenhack.h"
+#include "colors.h"
+#include "hsv.h"
#if defined(HAVE_ICMP) || defined(HAVE_ICMPHDR)
# include <unistd.h>
# include <netdb.h>
#endif /* HAVE_ICMP || HAVE_ICMPHDR */
-#include "screenhack.h"
-#include "colors.h"
-#include "hsv.h"
-
-#include <X11/extensions/XShm.h>
-
/* Defines */
#undef MY_MIN
#define MY_MIN(a,b) ((a)<(b)?(a - 50):(b - 10))
+#ifndef LINE_MAX
+# define LINE_MAX 2048
+#endif
+
/* Frigging icmp */
#if defined(HAVE_ICMP)
#endif
static long delta(struct timeval *, struct timeval *);
+
/* Data Structures */
/*
centrex, centrey, radius; /* Parts of the scope circle */
Bogie *visable; /* List of visable objects */
int current; /* Current position of sweep */
-
+ int sweepnum; /* The current id of the sweep */
int delay; /* how long between each frame of the anim */
+ int TTL; /* The number of ticks that bogies are visible
+ on the screen before they fade away. */
} sonar_info;
+static Bool debug_p = False;
+
+
/*
* Variables to support the differnt Sonar modes.
*/
* A list of targets to ping.
*/
-#ifdef HAVE_PING
typedef struct ping_target {
char *name; /* The name of the target */
struct sockaddr address; /* The address of the target */
struct ping_target *next; /* The next one in the list */
} ping_target;
+
+#ifdef HAVE_PING
/*
* Ping Information.
*
static int timer_expired;
-
#endif /* HAVE_PING */
/*
char *name; /* The name of the target */
int nexttick; /* The next tick that this will be seen */
int nextdist; /* The distance on that tick */
- int movedlasttick; /* Flag to indicate we just moved this one */
+ int movedonsweep; /* The number of the sweep this last moved */
} sim_target;
/*
"*textSteps: 80", /* npixels */
"*sweepSegments: 80", /* npixels */
-#ifdef HAVE_PING
"*pingTimeout: 3000",
- "*pingSource: file",
- "*pingFile: /etc/hosts",
- "*pingList: localhost",
-#endif /* HAVE_PING */
+
"*teamAName: F18",
"*teamBName: MIG",
"*teamACount: 4",
"*teamBCount: 4",
+
+ "*ping: default",
+ ".debug: false",
0
};
{"-grid-color", ".gridColor", XrmoptionSepArg, 0 },
{"-text-color", ".textColor", XrmoptionSepArg, 0 },
{"-ttl", ".ttl", XrmoptionSepArg, 0 },
- {"-mode", ".mode", XrmoptionSepArg, 0 },
{"-font", ".font", XrmoptionSepArg, 0 },
#ifdef HAVE_PING
{"-ping-timeout", ".pingTimeout", XrmoptionSepArg, 0 },
- {"-ping-source", ".pingSource", XrmoptionSepArg, 0 },
- {"-ping-file", ".pingFile", XrmoptionSepArg, 0 },
- {"-ping-list", ".pingList", XrmoptionSepArg, 0 },
#endif /* HAVE_PING */
{"-team-a-name", ".teamAName", XrmoptionSepArg, 0 },
{"-team-b-name", ".teamBName", XrmoptionSepArg, 0 },
{"-team-a-count", ".teamACount", XrmoptionSepArg, 0 },
{"-team-b-count", ".teamBCount", XrmoptionSepArg, 0 },
+
+ {"-ping", ".ping", XrmoptionSepArg, 0 },
+ {"-debug", ".debug", XrmoptionNoArg, "True" },
{ 0, 0, 0, 0 }
};
-/*
- * The number of ticks that bogies are visable on the screen before they
- * fade away.
- */
-
-static int TTL;
-
/*
* Create a new Bogie and set some initial values.
*
/* Allocate a bogie and initialize it */
if ((new = (Bogie *) calloc(1, sizeof(Bogie))) == NULL) {
- fprintf(stderr, "Out of Memory\n");
+ fprintf(stderr, "%s: Out of Memory\n", progname);
return NULL;
}
new->name = name;
* b - The bogie to free.
*/
+
static void
freeBogie(Bogie *b)
{
lookupHost(ping_target *target)
{
+ struct hostent *hent;
+
/* Local Variables */
struct sockaddr_in *iaddr;
iaddr = (struct sockaddr_in *) &(target->address);
iaddr->sin_family = AF_INET;
- if ((iaddr->sin_addr.s_addr = inet_addr(target->name)) == -1) {
+ if ((iaddr->sin_addr.s_addr = inet_addr(target->name)) >= 0) {
+ char ip[4];
+ ip[3] = iaddr->sin_addr.s_addr >> 24 & 255;
+ ip[2] = iaddr->sin_addr.s_addr >> 16 & 255;
+ ip[1] = iaddr->sin_addr.s_addr >> 8 & 255;
+ ip[0] = iaddr->sin_addr.s_addr & 255;
+ hent = gethostbyaddr (ip, 4, AF_INET);
+ if (hent && hent->h_name && *hent->h_name) {
+ target->name = strdup (hent->h_name);
+ return 1;
+ }
+ }
- /* Conversion of IP address failed, try to look the host up by name */
+ /* Conversion of IP address failed, try to look the host up by name */
- struct hostent *hent = gethostbyname(target->name);
- if (hent == NULL) {
- fprintf(stderr, "Could not resolve host %s\n", target->name);
- return 0;
- }
- memcpy(&iaddr->sin_addr, hent->h_addr_list[0],
- sizeof(iaddr->sin_addr));
+ hent = gethostbyname(target->name);
+ if (hent == NULL) {
+ fprintf(stderr, "%s: could not resolve host %s\n",
+ progname, target->name);
+ return 0;
}
+ memcpy(&iaddr->sin_addr, hent->h_addr_list[0],
+ sizeof(iaddr->sin_addr));
/* Done */
/* Create the target */
if ((target = calloc(1, sizeof(ping_target))) == NULL) {
- fprintf(stderr, "Out of Memory\n");
+ fprintf(stderr, "%s: Out of Memory\n", progname);
goto target_init_error;
}
if ((target->name = strdup(name)) == NULL) {
- fprintf(stderr, "Out of Memory\n");
+ fprintf(stderr, "%s: Out of Memory\n", progname);
goto target_init_error;
}
/* Done */
+ if (debug_p)
+ {
+ struct sockaddr_in *iaddr = (struct sockaddr_in *) &(target->address);
+ unsigned long ip = iaddr->sin_addr.s_addr;
+ fprintf (stderr, "%s: added host %d.%d.%d.%d (%s)\n", progname,
+ ip & 255, ip >> 8 & 255, ip >> 16 & 255, ip >> 24 & 255,
+ target->name);
+ }
+
return target;
/* Handle errors here */
static ping_target *
readPingHostsFile(char *fname)
{
-
/* Local Variables */
FILE *fp;
/* Make sure we in fact have a file to process */
if ((fname == NULL) || (fname[0] == '\0')) {
- fprintf(stderr, "Invalid ping host file name\n");
+ fprintf(stderr, "%s: invalid ping host file name\n", progname);
return NULL;
}
if ((fp = fopen(fname, "r")) == NULL) {
char msg[1024];
- sprintf(msg, "Unable to open host file %s", fname);
+ sprintf(msg, "%s: unable to open host file %s", progname, fname);
perror(msg);
return NULL;
}
+ if (debug_p)
+ fprintf (stderr, "%s: reading file %s\n", progname, fname);
+
/* Read the file line by line */
while ((p = fgets(buf, LINE_MAX, fp)) != NULL) {
else
continue;
+ /* Check to see if the addr looks like an addr. If not, assume
+ the addr is a name and there is no addr. This way, we can
+ handle files whose lines have "xx.xx.xx.xx hostname" as their
+ first two tokens, and also files that have a hostname as their
+ first token (like .ssh/known_hosts and .rhosts.)
+ */
+ {
+ int i; char c;
+ if (4 != sscanf(addr, "%d.%d.%d.%d%c", &i, &i, &i, &i, &c))
+ {
+ name = addr;
+ addr = NULL;
+ }
+ }
+ /*printf ("\"%s\" \"%s\"\n", name, addr);*/
+
/* Create a new target using first the name then the address */
new = NULL;
if (name != NULL)
new = newHost(name);
- if (new == NULL)
+ if (new == NULL && addr != NULL)
new = newHost(addr);
/* Add it to the list if we got one */
return list;
}
-/*
- * Generate a list of ping targets from the entries in a string.
- *
- * Args:
- * list - A list of comma separated host names.
- *
- * Returns:
- * A list of targets to ping or null if an error occured.
- */
static ping_target *
-readPingHostsList(char *list)
+delete_duplicate_hosts (ping_target *list)
{
+ ping_target *head = list;
+ ping_target *rest;
- /* Local Variables */
+ for (rest = head; rest; rest = rest->next)
+ {
+ struct sockaddr_in *i1 = (struct sockaddr_in *) &(rest->address);
+ unsigned long ip1 = i1->sin_addr.s_addr;
- char *host;
- ping_target *hostlist = NULL;
- ping_target *new;
+ static ping_target *rest2;
+ for (rest2 = rest; rest2; rest2 = rest2->next)
+ {
+ if (rest2 && rest2->next)
+ {
+ struct sockaddr_in *i2 = (struct sockaddr_in *)
+ &(rest2->next->address);
+ unsigned long ip2 = i2->sin_addr.s_addr;
- /* Check that there is a list */
+ if (ip1 == ip2)
+ {
+ if (debug_p)
+ fprintf (stderr, "%s: deleted duplicate: %s\n",
+ progname, rest2->next->name);
+ rest2->next = rest2->next->next;
+ }
+ }
+ }
+ }
- if ((list == NULL) || (list[0] == '\0'))
- return NULL;
+ return head;
+}
- /* Loop through the hosts and add them to the list to return */
- host = strtok(list, ",");
- while (host != NULL) {
- new = newHost(host);
- if (new != NULL) {
- new->next = hostlist;
- hostlist = new;
- }
- host = strtok(NULL, ",");
- }
- /* Done */
-
- return hostlist;
-}
/*
* Generate a list ping targets consisting of all of the entries on
*/
static ping_target *
-subnetHostsList(void)
+subnetHostsList(int base, int subnet_width)
{
+ unsigned long mask;
/* Local Variables */
ping_target *new;
ping_target *list = NULL;
+ if (subnet_width < 24)
+ {
+ fprintf (stderr,
+ "%s: pinging %u hosts is a bad idea; please use a subnet mask of 24 bits\n"
+ " or more (255 hosts max.)\n",
+ progname, (1L << (32 - subnet_width)) - 1);
+ exit (1);
+ }
+ else if (subnet_width > 30)
+ {
+ fprintf (stderr, "%s: a subnet of %d bits doesn't make sense:"
+ " try \"subnet/24\" or \"subnet/29\".\n",
+ progname, subnet_width);
+ exit (1);
+ }
+
+
+ if (debug_p)
+ fprintf (stderr, "%s: adding %d-bit subnet\n", progname, subnet_width);
+
/* Get our hostname */
if (gethostname(hostname, BUFSIZ)) {
- fprintf(stderr, "Unable to get local hostname\n");
+ fprintf(stderr, "%s: unable to get local hostname\n", progname);
return NULL;
}
/* Get our IP address and convert it to a string */
if ((hent = gethostbyname(hostname)) == NULL) {
- fprintf(stderr, "Unable to lookup our IP address\n");
+ fprintf(stderr, "%s: unable to lookup our IP address\n", progname);
return NULL;
}
strcpy(address, inet_ntoa(*((struct in_addr *)hent->h_addr_list[0])));
- /* Get a pointer to the last "." in the string */
-
- if ((p = strrchr(address, '.')) == NULL) {
- fprintf(stderr, "Can't parse IP address %s\n", address);
- return NULL;
- }
- p++;
-
/* Construct targets for all addresses in this subnet */
- for (i = 254; i > 0; i--) {
+ mask = 0;
+ for (i = 0; i < subnet_width; i++)
+ mask |= (1L << (31-i));
+
+ /* If no base IP specified, assume localhost. */
+ if (base == 0)
+ base = ((((unsigned char) hent->h_addr_list[0][0]) << 24) |
+ (((unsigned char) hent->h_addr_list[0][1]) << 16) |
+ (((unsigned char) hent->h_addr_list[0][2]) << 8) |
+ (((unsigned char) hent->h_addr_list[0][3])));
+
+ for (i = 255; i >= 0; i--) {
+ int ip = (base & 0xFFFFFF00) | i;
+
+ if ((ip & mask) != (base & mask)) /* not in the mask range at all */
+ continue;
+ if ((ip & ~mask) == 0) /* broadcast address */
+ continue;
+ if ((ip & ~mask) == ~mask) /* broadcast address */
+ continue;
+
+ sprintf (address, "%d.%d.%d.%d",
+ (ip>>24)&255, (ip>>16)&255, (ip>>8)&255, (ip)&255);
+
+ if (debug_p > 1)
+ fprintf(stderr, "%s: subnet: %s (%d.%d.%d.%d & %d.%d.%d.%d / %d)\n",
+ progname,
+ address,
+ (base>>24)&255, (base>>16)&255, (base>>8)&255, base&mask&255,
+ (mask>>24)&255, (mask>>16)&255, (mask>>8)&255, mask&255,
+ subnet_width);
+
+ p = address + strlen(address) + 1;
sprintf(p, "%d", i);
+
new = newHost(address);
if (new != NULL) {
new->next = list;
list = new;
}
}
-
+
/* Done */
return list;
* A newly allocated ping_info structure or null if an error occured.
*/
+static ping_target *parse_mode (Bool ping_works_p);
+
static ping_info *
init_ping(void)
{
+ Bool socket_initted_p = False;
+
/* Local Variables */
ping_info *pi = NULL; /* The new ping_info struct */
- char *src; /* The source of the ping hosts */
ping_target *pt; /* Used to count the targets */
/* Create the ping info structure */
if ((pi = (ping_info *) calloc(1, sizeof(ping_info))) == NULL) {
- fprintf(stderr, "Out of memory\n");
+ fprintf(stderr, "%s: Out of memory\n", progname);
goto ping_init_error;
}
- /* Create the ICMP socket and turn off SUID */
+ /* Create the ICMP socket */
- if ((pi->icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
- perror("Can't create ICMP socket");
- fprintf(stderr,
- "%s: this program must be setuid to root for `ping mode' to work.\n",
- progname);
- goto ping_init_error;
+ if ((pi->icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) >= 0) {
+ socket_initted_p = True;
}
+
+ /* Disavow privs */
+
setuid(getuid());
+
+
pi->pid = getpid() & 0xFFFF;
pi->seq = 0;
pi->timeout = get_integer_resource("pingTimeout", "PingTimeout");
/* Generate a list of targets */
- src = get_string_resource("pingSource", "PingSource");
- if (strcmp(src, "file") == 0) {
-
- /*
- * The list of ping targets is to come from a file in
- * /etc/hosts format
- */
-
- pi->targets = readPingHostsFile(get_string_resource("pingFile",
- "PingFile"));
-
- } else if (strcmp(src, "list") == 0) {
-
- /* The list of hosts is to come from the pinghostlist resource */
-
- pi->targets = readPingHostsList(get_string_resource("pingList",
- "PingList"));
-
- } else if (strcmp(src, "subnet") == 0) {
+ pi->targets = parse_mode (socket_initted_p);
+ pi->targets = delete_duplicate_hosts (pi->targets);
- pi->targets = subnetHostsList();
-
- } else {
-
- /* Unknown source */
-
- fprintf(stderr, "Illegal pingSource: %s\n", src);
- goto ping_init_error;
- }
/* Make sure there is something to ping */
if (pi->targets == NULL) {
- fprintf(stderr, "Nothing to ping");
- goto ping_init_error;
+ goto ping_init_error;
}
/* Count the targets */
return NULL;
}
+
/*
* Ping a host.
*
&pt->address, sizeof(pt->address))) != pcktsiz) {
#if 0
char errbuf[BUFSIZ];
- sprintf(errbuf, "Error sending ping to %s", pt->name);
+ sprintf(errbuf, "%s: error sending ping to %s", progname, pt->name);
perror(errbuf);
#endif
}
*/
static Bogie *
-getping(sonar_info *si, ping_info *pi, int ttl)
+getping(sonar_info *si, ping_info *pi)
{
/* Local Variables */
sa.sa_flags = 0;
sa.sa_handler = sigcatcher;
if (sigaction(SIGALRM, &sa, 0) == -1) {
- perror("Unable to trap sigalarm");
+ char msg[1024];
+ sprintf(msg, "%s: unable to trap SIGALRM", progname);
+ perror(msg);
exit(1);
}
gettimeofday(&now, (struct timezone *) 0);
ip = (struct ip *) packet;
+
iphdrlen = ip->ip_hl << 2;
+ /* On DEC OSF1 4.0, the preceeding line needs to be
+ iphdrlen = (ip->ip_vhl & 0x0F) << 2;
+ but I don't know how to do this portably. -- jwz.
+ */
+
icmph = (struct ICMP *) &packet[iphdrlen];
/* Was the packet a reply?? */
strdup((char *) &packet[iphdrlen +
+ sizeof(struct ICMP)
+ sizeof(struct timeval)])) == NULL) {
- fprintf(stderr, "Out of memory\n");
+ fprintf(stderr, "%s: Out of memory\n", progname);
return bl;
}
/* Create the new Bogie and add it to the list we are building */
- if ((new = newBogie(name, 0, si->current, ttl)) == NULL)
+ if ((new = newBogie(name, 0, si->current, si->TTL)) == NULL)
return bl;
new->next = bl;
bl = new;
ping(sonar_info *si, void *vpi)
{
+ /*
+ * This tries to distribute the targets evely around the field of the
+ * sonar.
+ */
+
ping_info *pi = (ping_info *) vpi;
static ping_target *ptr = NULL;
/* Get the results */
- return getping(si, pi, TTL);
+ return getping(si, pi);
}
#endif /* HAVE_PING */
/* Create the simulation info structure */
if ((si = (sim_info *) calloc(1, sizeof(sim_info))) == NULL) {
- fprintf(stderr, "Out of memory\n");
+ fprintf(stderr, "%s: Out of memory\n", progname);
return NULL;
}
if ((si->teamA = (sim_target *)calloc(si->numA, sizeof(sim_target)))
== NULL) {
free(si);
- fprintf(stderr, "Out of Memory\n");
+ fprintf(stderr, "%s: Out of Memory\n", progname);
return NULL;
}
si->teamAID = get_string_resource("teamAName", "TeamAName");
if ((si->teamA[i].name = (char *) malloc(strlen(si->teamAID) + 4))
== NULL) {
free(si);
- fprintf(stderr, "Out of Memory\n");
+ fprintf(stderr, "%s: Out of Memory\n", progname);
return NULL;
}
sprintf(si->teamA[i].name, "%s%03d", si->teamAID, i+1);
si->teamA[i].nexttick = (int) (90.0 * random() / RAND_MAX);
si->teamA[i].nextdist = (int) (100.0 * random() / RAND_MAX);
+ si->teamA[i].movedonsweep = -1;
}
/* Team B */
if ((si->teamB = (sim_target *)calloc(si->numB, sizeof(sim_target)))
== NULL) {
free(si);
- fprintf(stderr, "Out of Memory\n");
+ fprintf(stderr, "%s: Out of Memory\n", progname);
return NULL;
}
si->teamBID = get_string_resource("teamBName", "TeamBName");
if ((si->teamB[i].name = (char *) malloc(strlen(si->teamBID) + 4))
== NULL) {
free(si);
- fprintf(stderr, "Out of Memory\n");
+ fprintf(stderr, "%s: Out of Memory\n", progname);
return NULL;
}
sprintf(si->teamB[i].name, "%s%03d", si->teamBID, i+1);
si->teamB[i].nexttick = (int) (90.0 * random() / RAND_MAX);
si->teamB[i].nextdist = (int) (100.0 * random() / RAND_MAX);
+ si->teamB[i].movedonsweep = -1;
}
/* Done */
/* Create the Sonar information structure */
if ((si = (sonar_info *) calloc(1, sizeof(sonar_info))) == NULL) {
- fprintf(stderr, "Out of memory\n");
+ fprintf(stderr, "%s: Out of memory\n", progname);
return NULL;
}
si->miny = si->centrey - MY_MIN(si->centrex, si->centrey) + 10;
si->radius = si->maxx - si->centrex;
si->current = 0;
+ si->sweepnum = 0;
/* Get the font */
if (((si->font = XLoadQueryFont(dpy, get_string_resource ("font", "Font")))
== NULL) &&
((si->font = XLoadQueryFont(dpy, "fixed")) == NULL)) {
- fprintf(stderr, "Can't load an appropriate font\n");
+ fprintf(stderr, "%s: can't load an appropriate font\n", progname);
return NULL;
}
/* Get the delay between animation frames */
si->delay = get_integer_resource ("delay", "Integer");
+
if (si->delay < 0) si->delay = 0;
+ si->TTL = get_integer_resource("ttl", "TTL");
/* Create the Graphics Contexts that will be used to draw things */
int xdist, xtick;
- t->movedlasttick = 1;
xtick = (int) (3.0 * random() / RAND_MAX) - 1;
xdist = (int) (11.0 * random() / RAND_MAX) - 5;
if (((t->nexttick + xtick) < 90) && ((t->nexttick + xtick) >= 0))
for (i = 0; i < info->numA; i++) {
t = &info->teamA[i];
- if (!t->movedlasttick && (t->nexttick == (si->current * -1))) {
- new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
+ if ((t->movedonsweep != si->sweepnum) &&
+ (t->nexttick == (si->current * -1))) {
+ new = newBogie(strdup(t->name), t->nextdist, si->current, si->TTL);
if (list != NULL)
new->next = list;
list = new;
updateLocation(t);
- } else
- t->movedlasttick = 0;
+ t->movedonsweep = si->sweepnum;
+ }
}
/* Team B */
for (i = 0; i < info->numB; i++) {
t = &info->teamB[i];
- if (!t->movedlasttick && (t->nexttick == (si->current * -1))) {
- new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
+ if ((t->movedonsweep != si->sweepnum) &&
+ (t->nexttick == (si->current * -1))) {
+ new = newBogie(strdup(t->name), t->nextdist, si->current, si->TTL);
if (list != NULL)
new->next = list;
list = new;
- t->movedlasttick = 1;
updateLocation(t);
- } else
- t->movedlasttick = 0;
+ t->movedonsweep = si->sweepnum;
+ }
}
/* Done */
/* Compute the coordinates of the object */
- distance = (log((double) distance) / 10.0) * si->radius;
+ if (distance != 0)
+ distance = (log((double) distance) / 10.0) * si->radius;
x = ox + ((double) distance * cos(4.0 * ((double) degrees)/57.29578));
y = oy - ((double) distance * sin(4.0 * ((double) degrees)/57.29578));
else
prev->next = bp->next;
freeBogie(bp);
+ bp = prev;
} else
prev = bp;
}
drawGrid(si);
}
+
+static ping_target *
+parse_mode (Bool ping_works_p)
+{
+ char *source = get_string_resource ("ping", "Ping");
+ char *token, *end;
+
+ ping_target *hostlist = 0;
+
+ if (!source) source = strdup("");
+
+ if (!*source || !strcmp (source, "default"))
+ {
+# ifdef HAVE_PING
+ if (ping_works_p) /* if root or setuid, ping will work. */
+ source = strdup("subnet/29,/etc/hosts");
+ else
+# endif
+ source = strdup("simulation");
+ }
+
+ token = source;
+ end = source + strlen(source);
+ while (token < end)
+ {
+ char *next;
+ ping_target *new;
+ struct stat st;
+ unsigned int n0=0, n1=0, n2=0, n3=0, m=0;
+ char d;
+
+ for (next = token;
+ *next != ',' && *next != ' ' && *next != '\t' && *next != '\n';
+ next++)
+ ;
+ *next = 0;
+
+
+ if (debug_p)
+ fprintf (stderr, "%s: parsing %s\n", progname, token);
+
+ if (!strcmp (token, "simulation"))
+ return 0;
+
+ if (!ping_works_p)
+ {
+ fprintf(stderr,
+ "%s: this program must be setuid to root for `ping mode' to work.\n"
+ " Running in `simulation mode' instead.\n",
+ progname);
+ return 0;
+ }
+
+ if ((4 == sscanf (token, "%d.%d.%d/%d %c", &n0,&n1,&n2, &m,&d)) ||
+ (5 == sscanf (token, "%d.%d.%d.%d/%d %c", &n0,&n1,&n2,&n3,&m,&d)))
+ {
+ /* subnet: A.B.C.D/M
+ subnet: A.B.C/M
+ */
+ unsigned long ip = (n0 << 24) | (n1 << 16) | (n2 << 8) | n3;
+ new = subnetHostsList(ip, m);
+ }
+ else if (4 == sscanf (token, "%d.%d.%d.%d %c", &n0, &n1, &n2, &n3, &d))
+ {
+ /* IP: A.B.C.D
+ */
+ new = newHost (token);
+ }
+ else if (!strcmp (token, "subnet"))
+ {
+ new = subnetHostsList(0, 24);
+ }
+ else if (1 == sscanf (token, "subnet/%d %c", &m))
+ {
+ new = subnetHostsList(0, m);
+ }
+ else if (*token == '.' || *token == '/' || !stat (token, &st))
+ {
+ /* file name
+ */
+ new = readPingHostsFile (token);
+ }
+ else
+ {
+ /* not an existant file - must be a host name
+ */
+ new = newHost (token);
+ }
+
+ if (new)
+ {
+ ping_target *nn = new;
+ while (nn && nn->next)
+ nn = nn->next;
+ nn->next = hostlist;
+ hostlist = new;
+
+ sensor = ping;
+ }
+
+ token = next + 1;
+ while (token < end &&
+ (*token == ',' || *token == ' ' ||
+ *token == '\t' || *token == '\n'))
+ token++;
+ }
+
+ return hostlist;
+}
+
+
+
/*
* Main screen saver hack.
*
struct timeval start, finish;
Bogie *bl;
long sleeptime;
- char *mode;
- /*
- * Initialize
- * Adding new sensors would involve supporting more modes other than
- * ping and initiailizing the sensor in the same way.
- */
+ debug_p = get_boolean_resource ("debug", "Debug");
- mode = get_string_resource("mode", "Mode");
+ sensor = 0;
+ sensor_info = (void *) init_ping();
- if (!mode || !*mode || !strcmp(mode, "default")) /* Pick a good default. */
+ if (sensor == 0)
{
-#ifdef HAVE_PING
- if (geteuid() == 0) /* we're root or setuid -- ping will work. */
- mode = "ping";
- else
-#endif
- mode = "simulation";
+ sensor = simulator;
+ if ((sensor_info = (void *) init_sim()) == NULL)
+ exit(1);
}
-#ifdef HAVE_PING
- if (strcmp(mode, "ping") == 0) {
- sensor = ping;
- if ((sensor_info = (void *) init_ping()) == (void *) 0)
- {
- fprintf (stderr, "%s: running in `simulation mode' instead.\n",
- progname);
- goto SIM;
- }
- } else
-#endif /* HAVE_PING */
- if (strcmp(mode, "simulation") == 0) {
-#ifdef HAVE_PING
- SIM:
-#endif
- sensor = simulator;
- if ((sensor_info = (void *) init_sim()) == NULL)
- exit(1);
- } else {
- fprintf(stderr, "Unsupported Sonar mode: %s\n", mode);
- fprintf(stderr,
- "\tCurrently supported modes are `ping' and `simulation'\n");
- exit(1);
- }
if ((si = init_sonar(dpy, win)) == (sonar_info *) 0)
exit(1);
-
- /* Sonar loop */
- TTL = get_integer_resource("ttl", "TTL");
+
+ /* Sonar loop */
while (1) {
/* Set up and sleep for the next one */
si->current = (si->current - 1) % 90;
+ if (si->current == 0)
+ si->sweepnum++;
XSync (dpy, False);
gettimeofday(&finish, (struct timezone *) 0);
sleeptime = si->delay - delta(&start, &finish);
screenhack_handle_events (dpy);
if (sleeptime > 0L)
usleep(sleeptime);
+
}
}