* - 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@vanderfleet-martin.net).
+ * 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.16 $
+ * $Revision: 1.23 $
*
* Version 1.0 April 27, 1998.
* - Initial version
# undef HAVE_PING
#endif
+
+#ifdef HAVE_PING
+# if defined(__DECC) || defined(_IP_VHL)
+ /* This is how you do it on DEC C, and possibly some BSD systems. */
+# define IP_HDRLEN(ip) ((ip)->ip_vhl & 0x0F)
+# else
+ /* This is how you do it on everything else. */
+# define IP_HDRLEN(ip) ((ip)->ip_hl)
+# endif
+#endif /* HAVE_PING */
+
+
/* Forward References */
#ifdef HAVE_PING
* A list of targets to ping.
*/
-#ifdef HAVE_PING
typedef struct ping_target {
char *name; /* The name of the target */
+#ifdef HAVE_PING
struct sockaddr address; /* The address of the target */
+#endif /* HAVE_PING */
struct ping_target *next; /* The next one in the list */
} ping_target;
+
+#ifdef HAVE_PING
/*
* Ping Information.
*
static int
lookupHost(ping_target *target)
{
-
struct hostent *hent;
+ struct sockaddr_in *iaddr;
- /* Local Variables */
+ int iip[4];
+ char c;
+
+ iaddr = (struct sockaddr_in *) &(target->address);
+ iaddr->sin_family = AF_INET;
- struct sockaddr_in *iaddr;
+ if (4 == sscanf(target->name, "%d.%d.%d.%d%c",
+ &iip[0], &iip[1], &iip[2], &iip[3], &c))
+ {
+ /* It's an IP address.
+ */
+ unsigned char ip[4];
- /* Set up the target address we first assume that the name is the
- IP address as a string */
+ ip[0] = iip[0];
+ ip[1] = iip[1];
+ ip[2] = iip[2];
+ ip[3] = iip[3];
- iaddr = (struct sockaddr_in *) &(target->address);
- iaddr->sin_family = AF_INET;
- 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;
+ if (ip[3] == 0)
+ {
+ if (debug_p > 1)
+ fprintf (stderr, "%s: ignoring bogus IP %s\n",
+ progname, target->name);
+ return 0;
+ }
+
+ iaddr->sin_addr.s_addr = ((ip[3] << 24) |
+ (ip[2] << 16) |
+ (ip[1] << 8) |
+ (ip[0]));
hent = gethostbyaddr (ip, 4, AF_INET);
- if (hent && hent->h_name && *hent->h_name) {
+
+ if (debug_p > 1)
+ fprintf (stderr, "%s: %s => %s\n",
+ progname, target->name,
+ ((hent && hent->h_name && *hent->h_name)
+ ? hent->h_name : "<unknown>"));
+
+ if (hent && hent->h_name && *hent->h_name)
target->name = strdup (hent->h_name);
- return 1;
- }
}
+ else
+ {
+ /* It's a host name.
+ */
+ hent = gethostbyname (target->name);
+ if (!hent)
+ {
+ fprintf (stderr, "%s: could not resolve host: %s\n",
+ progname, target->name);
+ return 0;
+ }
- /* Conversion of IP address failed, try to look the host up by name */
+ 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;
+ if (debug_p > 1)
+ fprintf (stderr, "%s: %s => %d.%d.%d.%d\n",
+ progname, target->name,
+ iaddr->sin_addr.s_addr & 255,
+ iaddr->sin_addr.s_addr >> 8 & 255,
+ iaddr->sin_addr.s_addr >> 16 & 255,
+ iaddr->sin_addr.s_addr >> 24 & 255);
}
- memcpy(&iaddr->sin_addr, hent->h_addr_list[0],
- sizeof(iaddr->sin_addr));
+ return 1;
+}
- /* Done */
- return 1;
+static void
+print_host (FILE *out, unsigned long ip, const char *name)
+{
+ char ips[50];
+ sprintf (ips, "%lu.%lu.%lu.%lu",
+ (ip) & 255,
+ (ip >> 8) & 255,
+ (ip >> 16) & 255,
+ (ip >> 24) & 255);
+ if (!name || !*name) name = "<unknown>";
+ fprintf (out, "%-16s %s\n", ips, name);
}
+
/*
* Create a target for a host.
*
if (! lookupHost(target))
goto target_init_error;
+ /* Don't ever use loopback (127.0.0) hosts */
+ {
+ struct sockaddr_in *iaddr = (struct sockaddr_in *) &(target->address);
+ unsigned long ip = iaddr->sin_addr.s_addr;
+ if ((ip & 255) == 127 &&
+ ((ip >> 8) & 255) == 0 &&
+ ((ip >> 16) & 255) == 0)
+ {
+ if (debug_p)
+ fprintf (stderr, "%s: ignoring loopback host %s\n",
+ progname, target->name);
+ 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);
+ fprintf (stderr, "%s: added ", progname);
+ print_host (stderr, ip, target->name);
}
return target;
/* Get the name and address */
name = addr = NULL;
- if ((addr = strtok(buf, " \t\n")) != NULL)
- name = strtok(NULL, " \t\n");
+ if ((addr = strtok(buf, " ,;\t\n")) != NULL)
+ name = strtok(NULL, " ,;\t\n");
else
continue;
addr = NULL;
}
}
- /*printf ("\"%s\" \"%s\"\n", name, addr);*/
+
+ /* If the name is all digits, it's not a name. */
+ if (name)
+ {
+ const char *s;
+ for (s = name; *s; s++)
+ if (*s < '0' || *s > '9')
+ break;
+ if (! *s)
+ {
+ if (debug_p > 1)
+ fprintf (stderr, "%s: skipping bogus name \"%s\" (%s)\n",
+ progname, name, addr);
+ name = NULL;
+ }
+ }
/* Create a new target using first the name then the address */
if (ip1 == ip2)
{
if (debug_p)
- fprintf (stderr, "%s: deleted duplicate: %s\n",
- progname, rest2->next->name);
+ {
+ fprintf (stderr, "%s: deleted duplicate: ", progname);
+ print_host (stderr, ip2, rest2->next->name);
+ }
rest2->next = rest2->next->next;
}
}
if (subnet_width < 24)
{
fprintf (stderr,
- "%s: pinging %u hosts is a bad idea; please use a subnet mask of 24 bits\n"
+ "%s: pinging %lu 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));
+ progname, (unsigned long) (1L << (32 - subnet_width)) - 1);
exit (1);
}
else if (subnet_width > 30)
(((unsigned char) hent->h_addr_list[0][2]) << 8) |
(((unsigned char) hent->h_addr_list[0][3])));
+ if (base == ((127 << 24) | 1))
+ {
+ fprintf (stderr,
+ "%s: unable to determine local subnet address: \"%s\"\n"
+ " resolves to loopback address %d.%d.%d.%d.\n",
+ progname, hostname,
+ (base >> 24) & 255, (base >> 16) & 255,
+ (base >> 8) & 255, (base ) & 255);
+ return NULL;
+ }
+
for (i = 255; i >= 0; i--) {
int ip = (base & 0xFFFFFF00) | i;
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);
+ (int) (base>>24)&255,
+ (int) (base>>16)&255,
+ (int) (base>> 8)&255,
+ (int) (base&mask&255),
+ (int) (mask>>24)&255,
+ (int) (mask>>16)&255,
+ (int) (mask>> 8)&255,
+ (int) (mask&255),
+ (int) subnet_width);
p = address + strlen(address) + 1;
sprintf(p, "%d", i);
pi->targets = delete_duplicate_hosts (pi->targets);
+ if (debug_p)
+ {
+ ping_target *t;
+ fprintf (stderr, "%s: Target list:\n", progname);
+ for (t = pi->targets; t; t = t->next)
+ {
+ struct sockaddr_in *iaddr = (struct sockaddr_in *) &(t->address);
+ unsigned long ip = iaddr->sin_addr.s_addr;
+ fprintf (stderr, "%s: ", progname);
+ print_host (stderr, ip, t->name);
+ }
+ }
+
/* Make sure there is something to ping */
if (pi->targets == NULL) {
char *name;
struct sigaction sa;
struct itimerval it;
+ fd_set rfds;
+ struct timeval tv;
/* Set up a signal to interupt our wait for a packet */
/* Wait for a result packet */
fromlen = sizeof(from);
- while (! timer_expired &&
- (result = recvfrom(pi->icmpsock, packet, sizeof(packet),
- 0, &from, &fromlen)) > 0) {
+ while (! timer_expired) {
+ tv.tv_usec=pi->timeout;
+ tv.tv_sec=0;
+#if 0
+ /* This breaks on BSD, which uses bzero() in the definition of FD_ZERO */
+ FD_ZERO(&rfds);
+#else
+ memset (&rfds, 0, sizeof(rfds));
+#endif
+ FD_SET(pi->icmpsock,&rfds);
+ /* only wait a little while, in case we raced with the timer expiration.
+ From Valentijn Sessink <valentyn@openoffice.nl> */
+ if (select(pi->icmpsock+1, &rfds, NULL, NULL, &tv) >0) {
+ result = recvfrom(pi->icmpsock, packet, sizeof(packet),
+ 0, &from, &fromlen);
/* Check the packet */
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.
- */
-
+ iphdrlen = IP_HDRLEN(ip) << 2;
icmph = (struct ICMP *) &packet[iphdrlen];
/* Was the packet a reply?? */
new->distance = delta(then, &now) / 100;
if (new->distance == 0)
new->distance = 2; /* HACK */
+ }
}
/* Done */
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].nexttick = random() % 90;
+ si->teamA[i].nextdist = random() % 100;
si->teamA[i].movedonsweep = -1;
}
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].nexttick = random() % 90;
+ si->teamB[i].nextdist = random() % 100;
si->teamB[i].movedonsweep = -1;
}
si->sweep_colors, &si->sweep_segs,
False, True, False);
+ if (si->sweep_segs <= 0)
+ si->sweep_segs = 1;
+
/* Done */
return si;
int xdist, xtick;
- xtick = (int) (3.0 * random() / RAND_MAX) - 1;
- xdist = (int) (11.0 * random() / RAND_MAX) - 5;
+ xtick = (int) (random() % 3) - 1;
+ xdist = (int) (random() % 11) - 5;
if (((t->nexttick + xtick) < 90) && ((t->nexttick + xtick) >= 0))
t->nexttick += xtick;
else
/* Check for expired tagets and remove them from the visable list */
prev = NULL;
- for (bp = si->visable; bp != NULL; bp = bp->next) {
+ for (bp = si->visable; bp != NULL; bp = (bp ? bp->next : 0)) {
/*
* Remove it from the visable list if it's expired or we have
else
prev->next = bp->next;
freeBogie(bp);
+ bp = prev;
} else
prev = bp;
}
{
char *source = get_string_resource ("ping", "Ping");
char *token, *end;
+ char dummy;
ping_target *hostlist = 0;
while (token < end)
{
char *next;
+# ifdef HAVE_PING
ping_target *new;
struct stat st;
unsigned int n0=0, n1=0, n2=0, n3=0, m=0;
char d;
+# endif /* HAVE_PING */
for (next = token;
*next != ',' && *next != ' ' && *next != '\t' && *next != '\n';
return 0;
}
+#ifdef HAVE_PING
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)))
{
{
new = subnetHostsList(0, 24);
}
- else if (1 == sscanf (token, "subnet/%d %c", &m))
+ else if (1 == sscanf (token, "subnet/%d %c", &m, &dummy))
{
new = subnetHostsList(0, m);
}
sensor = ping;
}
+#endif /* HAVE_PING */
token = next + 1;
while (token < end &&
debug_p = get_boolean_resource ("debug", "Debug");
sensor = 0;
+# ifdef HAVE_PING
sensor_info = (void *) init_ping();
+# else /* !HAVE_PING */
+ sensor_info = 0;
+ parse_mode (0); /* just to check argument syntax */
+# endif /* !HAVE_PING */
if (sensor == 0)
{