-/* sonar, Copyright (c) 1998-2012 Jamie Zawinski and Stephen Martin
+/* sonar, Copyright (c) 1998-2018 Jamie Zawinski and Stephen Martin
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#include "screenhackI.h"
#include "sonar.h"
#include "version.h"
+#include "async_netdb.h"
#undef usleep /* conflicts with unistd.h on OSX */
*/
#endif
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define READ_FILES
#endif
# include <sys/types.h>
# include <sys/time.h>
# include <sys/ipc.h>
-# include <sys/shm.h>
+# ifndef HAVE_ANDROID
+# include <sys/shm.h>
+# endif
# include <sys/socket.h>
# include <netinet/in_systm.h>
# include <netinet/in.h>
# include <netinet/udp.h>
# include <arpa/inet.h>
# include <netdb.h>
+# include <errno.h>
# ifdef HAVE_GETIFADDRS
# include <ifaddrs.h>
# endif
# undef HAVE_PING
#endif
-#ifndef USE_IPHONE
+#ifndef HAVE_MOBILE
# define LOAD_FILES
#endif
typedef struct {
+ Display *dpy; /* Only used to get *useThreads. */
+
char *version; /* short version number of xscreensaver */
int icmpsock; /* socket for sending pings */
int pid; /* our process ID */
} ping_data;
typedef struct {
- struct sockaddr address; /* ip address */
+ async_name_from_addr_t lookup_name;
+ async_addr_from_name_t lookup_addr;
+ async_netdb_sockaddr_storage_t address; /* ip address */
+ socklen_t addrlen;
+ char *fallback;
} ping_bogie;
/* Packs an IP address quad into bigendian network order. */
-static unsigned long
+static in_addr_t
pack_addr (unsigned int a, unsigned int b, unsigned int c, unsigned int d)
{
unsigned long i = (((a & 255) << 24) |
/* Resolves the bogie's name (either a hostname or ip address string)
- to a hostent. Returns 1 if successful, 0 if it failed to resolve.
+ to a hostent. Returns 1 if successful, 0 if something went wrong.
*/
static int
resolve_bogie_hostname (ping_data *pd, sonar_bogie *sb, Bool resolve_p)
{
ping_bogie *pb = (ping_bogie *) sb->closure;
- struct hostent *hent;
- struct sockaddr_in *iaddr;
unsigned int ip[4];
char c;
- iaddr = (struct sockaddr_in *) &(pb->address);
- iaddr->sin_family = AF_INET;
-
if (4 == sscanf (sb->name, " %u.%u.%u.%u %c",
&ip[0], &ip[1], &ip[2], &ip[3], &c))
{
/* It's an IP address.
*/
+ struct sockaddr_in *iaddr = (struct sockaddr_in *) &(pb->address);
+
if (ip[3] == 0)
{
if (pd->debug_p > 1)
return 0;
}
+ iaddr->sin_family = AF_INET;
iaddr->sin_addr.s_addr = pack_addr (ip[0], ip[1], ip[2], ip[3]);
- if (resolve_p)
- hent = gethostbyaddr ((const char *) &iaddr->sin_addr.s_addr,
- sizeof(iaddr->sin_addr.s_addr),
- AF_INET);
- else
- hent = 0;
-
- if (pd->debug_p > 1)
- fprintf (stderr, "%s: %s => %s\n",
- progname, sb->name,
- ((hent && hent->h_name && *hent->h_name)
- ? hent->h_name : "<unknown>"));
+ pb->addrlen = sizeof(struct sockaddr_in);
- if (hent && hent->h_name && *hent->h_name)
- sb->name = strdup (hent->h_name);
+ if (resolve_p)
+ {
+ pb->lookup_name =
+ async_name_from_addr_start (pd->dpy,
+ (const struct sockaddr *)&pb->address,
+ pb->addrlen);
+ if (!pb->lookup_name)
+ {
+ fprintf (stderr, "%s: unable to start host resolution.\n",
+ progname);
+ }
+ }
}
else
{
if (!strcmp (sb->name, "ssh-rsa") ||
!strcmp (sb->name, "ssh-dsa") ||
!strcmp (sb->name, "ssh-dss") ||
+ !strncmp (sb->name, "ecdsa-", 6) ||
strlen (sb->name) >= 80)
return 0;
return 0;
}
- hent = gethostbyname (sb->name);
- if (!hent)
+ pb->lookup_addr = async_addr_from_name_start(pd->dpy, sb->name);
+ if (!pb->lookup_addr)
{
if (pd->debug_p)
- fprintf (stderr, "%s: could not resolve host: %s\n",
- progname, sb->name);
+ /* Either address space exhaustion or RAM exhaustion. */
+ fprintf (stderr, "%s: unable to start host resolution.\n",
+ progname);
return 0;
}
+ }
+ return 1;
+}
- memcpy (&iaddr->sin_addr, hent->h_addr_list[0],
- sizeof(iaddr->sin_addr));
- if (pd->debug_p > 1)
+static void
+print_address (FILE *out, int width, const void *sockaddr, socklen_t addrlen)
+{
+#ifdef HAVE_GETADDRINFO
+ char buf[NI_MAXHOST];
+#else
+ char buf[50];
+#endif
+
+ const struct sockaddr *addr = (const struct sockaddr *)sockaddr;
+ const char *ips = buf;
+
+ if (!addr->sa_family)
+ ips = "<no address>";
+ else
+ {
+#ifdef HAVE_GETADDRINFO
+ int gai_error = getnameinfo (sockaddr, addrlen, buf, sizeof(buf),
+ NULL, 0, NI_NUMERICHOST);
+ if (gai_error == EAI_SYSTEM)
+ ips = strerror(errno);
+ else if (gai_error)
+ ips = gai_strerror(gai_error);
+#else
+ switch (addr->sa_family)
{
- unsigned int a, b, c, d;
- unpack_addr (iaddr->sin_addr.s_addr, &a, &b, &c, &d);
- fprintf (stderr, "%s: %s => %d.%d.%d.%d\n",
- progname, sb->name, a, b, c, d);
+ case AF_INET:
+ {
+ u_long ip = ((struct sockaddr_in *)sockaddr)->sin_addr.s_addr;
+ unsigned int a, b, c, d;
+ unpack_addr (ip, &a, &b, &c, &d); /* ip is in network order */
+ sprintf (buf, "%u.%u.%u.%u", a, b, c, d);
+ }
+ break;
+ default:
+ ips = "<unknown>";
+ break;
}
+#endif
}
- return 1;
+
+ fprintf (out, "%-*s", width, ips);
}
static void
-print_host (FILE *out, unsigned long ip, const char *name)
+print_host (FILE *out, const sonar_bogie *sb)
{
- char ips[50];
- unsigned int a, b, c, d;
- unpack_addr (ip, &a, &b, &c, &d); /* ip is in network order */
- sprintf (ips, "%u.%u.%u.%u", a, b, c, d);
+ const ping_bogie *pb = (const ping_bogie *) sb->closure;
+ const char *name = sb->name;
if (!name || !*name) name = "<unknown>";
- fprintf (out, "%-16s %s\n", ips, name);
+ print_address (out, 16, &pb->address, pb->addrlen);
+ fprintf (out, " %s\n", name);
+}
+
+
+static Bool
+is_address_ok(Bool debug_p, const sonar_bogie *b)
+{
+ const ping_bogie *pb = (const ping_bogie *) b->closure;
+ const struct sockaddr *addr = (const struct sockaddr *)&pb->address;
+
+ switch (addr->sa_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *iaddr = (struct sockaddr_in *) addr;
+
+ /* Don't ever use loopback (127.0.0.x) hosts */
+ unsigned long ip = iaddr->sin_addr.s_addr;
+ if ((ntohl (ip) & 0xFFFFFF00L) == 0x7f000000L) /* 127.0.0.x */
+ {
+ if (debug_p)
+ fprintf (stderr, "%s: ignoring loopback host %s\n",
+ progname, b->name);
+ return False;
+ }
+
+ /* Don't ever use broadcast (255.x.x.x) hosts */
+ if ((ntohl (ip) & 0xFF000000L) == 0xFF000000L) /* 255.x.x.x */
+ {
+ if (debug_p)
+ fprintf (stderr, "%s: ignoring broadcast host %s\n",
+ progname, b->name);
+ return False;
+ }
+ }
+
+ break;
+ }
+
+ return True;
}
Returns NULL if the name could not be resolved.
*/
static sonar_bogie *
-bogie_for_host (sonar_sensor_data *ssd, const char *name, Bool resolve_p)
+bogie_for_host (sonar_sensor_data *ssd, const char *name, const char *fallback)
{
ping_data *pd = (ping_data *) ssd->closure;
sonar_bogie *b = (sonar_bogie *) calloc (1, sizeof(*b));
ping_bogie *pb = (ping_bogie *) calloc (1, sizeof(*pb));
- struct sockaddr_in *iaddr;
- unsigned long ip;
+ Bool resolve_p = pd->resolve_p;
b->name = strdup (name);
b->closure = pb;
if (! resolve_bogie_hostname (pd, b, resolve_p))
goto FAIL;
- iaddr = (struct sockaddr_in *) &(pb->address);
-
- /* Don't ever use loopback (127.0.0.x) hosts */
- ip = iaddr->sin_addr.s_addr;
- if ((ntohl (ip) & 0xFFFFFF00L) == 0x7f000000L) /* 127.0.0.x */
- {
- if (pd->debug_p)
- fprintf (stderr, "%s: ignoring loopback host %s\n",
- progname, b->name);
- goto FAIL;
- }
-
- /* Don't ever use broadcast (255.x.x.x) hosts */
- if ((ntohl (ip) & 0xFF000000L) == 0xFF000000L) /* 255.x.x.x */
- {
- if (pd->debug_p)
- fprintf (stderr, "%s: ignoring broadcast host %s\n",
- progname, b->name);
- goto FAIL;
- }
+ if (! pb->lookup_addr && ! is_address_ok (pd->debug_p, b))
+ goto FAIL;
if (pd->debug_p > 1)
{
fprintf (stderr, "%s: added ", progname);
- print_host (stderr, ip, b->name);
+ print_host (stderr, b);
}
+ if (fallback)
+ pb->fallback = strdup (fallback);
return b;
FAIL:
if (b) sonar_free_bogie (ssd, b);
+
+ if (fallback)
+ return bogie_for_host (ssd, fallback, NULL);
+
return 0;
}
fp = fopen(filename, "r");
if (!fp)
{
- char buf[1024];
- sprintf(buf, "%s: %s", progname, filename);
-#ifdef HAVE_COCOA
+ char buf2[1024];
+ sprintf(buf2, "%s: %s", progname, filename);
+#ifdef HAVE_JWXYZ
if (pd->debug_p) /* on OSX don't syslog this */
#endif
- perror (buf);
+ perror (buf2);
return 0;
}
/* Create a new target using first the name then the address */
- new = 0;
- if (name)
- new = bogie_for_host (ssd, name, pd->resolve_p);
- if (!new && addr)
- new = bogie_for_host (ssd, addr, pd->resolve_p);
+ if (!name)
+ {
+ name = addr;
+ addr = NULL;
+ }
+
+ new = bogie_for_host (ssd, name, addr);
if (new)
{
#endif /* READ_FILES */
+static sonar_bogie **
+found_duplicate_host (const ping_data *pd, sonar_bogie **list,
+ sonar_bogie *bogie)
+{
+ if (pd->debug_p)
+ {
+ fprintf (stderr, "%s: deleted duplicate: ", progname);
+ print_host (stderr, bogie);
+ }
+
+ return list;
+}
+
+
+static sonar_bogie **
+find_duplicate_host (const ping_data *pd, sonar_bogie **list,
+ sonar_bogie *bogie)
+{
+ const ping_bogie *pb = (const ping_bogie *) bogie->closure;
+ const struct sockaddr *addr1 = (const struct sockaddr *) &(pb->address);
+
+ while(*list)
+ {
+ const ping_bogie *pb2 = (const ping_bogie *) (*list)->closure;
+
+ if (!pb2->lookup_addr)
+ {
+ const struct sockaddr *addr2 =
+ (const struct sockaddr *) &(pb2->address);
+
+ if (addr1->sa_family == addr2->sa_family)
+ {
+ switch (addr1->sa_family)
+ {
+ case AF_INET:
+ {
+ unsigned long ip1 =
+ ((const struct sockaddr_in *)addr1)->sin_addr.s_addr;
+ const struct sockaddr_in *i2 =
+ (const struct sockaddr_in *)addr2;
+ unsigned long ip2 = i2->sin_addr.s_addr;
+
+ if (ip1 == ip2)
+ return found_duplicate_host (pd, list, bogie);
+ }
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ {
+ if (! memcmp(
+ &((const struct sockaddr_in6 *)addr1)->sin6_addr,
+ &((const struct sockaddr_in6 *)addr2)->sin6_addr,
+ 16))
+ return found_duplicate_host (pd, list, bogie);
+ }
+ break;
+#endif
+ default:
+ {
+ /* Fallback behavior: Just memcmp the two addresses.
+
+ For this to work, unused space in the sockaddr must be
+ set to zero. Which may actually be the case:
+ - async_addr_from_name_finish won't put garbage into
+ sockaddr_in.sin_zero or elsewhere unless getaddrinfo
+ does.
+ - ping_bogie is allocated with calloc(). */
+
+ if (pb->addrlen == pb2->addrlen &&
+ ! memcmp(addr1, addr2, pb->addrlen))
+ return found_duplicate_host (pd, list, bogie);
+ }
+ break;
+ }
+ }
+ }
+
+ list = &(*list)->next;
+ }
+
+ return NULL;
+}
+
+
static sonar_bogie *
delete_duplicate_hosts (sonar_sensor_data *ssd, sonar_bogie *list)
{
ping_data *pd = (ping_data *) ssd->closure;
sonar_bogie *head = list;
- sonar_bogie *sb;
+ sonar_bogie *sb = head;
- for (sb = head; sb; sb = sb->next)
+ while (sb)
{
ping_bogie *pb = (ping_bogie *) sb->closure;
- struct sockaddr_in *i1 = (struct sockaddr_in *) &(pb->address);
- unsigned long ip1 = i1->sin_addr.s_addr;
- sonar_bogie *sb2;
- for (sb2 = sb; sb2; sb2 = sb2->next)
+ if (!pb->lookup_addr)
{
- if (sb2 && sb2->next)
- {
- ping_bogie *pb2 = (ping_bogie *) sb2->next->closure;
- struct sockaddr_in *i2 = (struct sockaddr_in *) &(pb2->address);
- unsigned long ip2 = i2->sin_addr.s_addr;
-
- if (ip1 == ip2)
- {
- if (pd->debug_p)
- {
- fprintf (stderr, "%s: deleted duplicate: ", progname);
- print_host (stderr, ip2, sb2->next->name);
- }
- sb2->next = sb2->next->next;
- /* #### sb leaked */
- }
- }
+ sonar_bogie **sb2 = find_duplicate_host (pd, &sb->next, sb);
+ if (sb2)
+ *sb2 = (*sb2)->next;
+ /* #### sb leaked */
+ else
+ sb = sb->next;
}
+ else
+ sb = sb->next;
}
return head;
}
-static unsigned int
-width_mask (int width)
+static unsigned long
+width_mask (unsigned long width)
{
- unsigned int m = 0;
+ unsigned long m = 0;
int i;
for (i = 0; i < width; i++)
m |= (1L << (31-i));
#ifdef HAVE_GETIFADDRS
-static int
-mask_width (unsigned int mask)
+static unsigned int
+mask_width (unsigned long mask)
{
int i;
for (i = 0; i < 32; i++)
{
struct in_addr in2;
unsigned long mask;
- if (ifa->ifa_addr->sa_family != AF_INET)
+ if (! ifa->ifa_addr)
+ continue;
+ else if (ifa->ifa_addr->sa_family != AF_INET)
{
if (pd->debug_p)
fprintf (stderr, "%s: if: %4s: %s\n", progname,
h_base = ntohl (n_base);
if (desc_ret && !*desc_ret) {
- char buf[255];
+ char buf2[255];
unsigned int a, b, c, d;
unsigned long bb = n_base & htonl(h_mask);
unpack_addr (bb, &a, &b, &c, &d);
if (subnet_width > 24)
- sprintf (buf, "%u.%u.%u.%u/%d", a, b, c, d, subnet_width);
+ sprintf (buf2, "%u.%u.%u.%u/%d", a, b, c, d, subnet_width);
else
- sprintf (buf, "%u.%u.%u/%d", a, b, c, subnet_width);
- *desc_ret = strdup (buf);
+ sprintf (buf2, "%u.%u.%u/%d", a, b, c, subnet_width);
+ *desc_ret = strdup (buf2);
}
for (i = 255; i >= 0; i--) {
p = address + strlen(address) + 1;
sprintf(p, "%d", i);
- new = bogie_for_host (ssd, address, pd->resolve_p);
+ new = bogie_for_host (ssd, address, NULL);
if (new)
{
new->next = list;
u_char *packet;
struct ICMP *icmph;
const char *token = "org.jwz.xscreensaver.sonar";
+ char *host_id;
- int pcktsiz = (sizeof(struct ICMP) + sizeof(struct timeval) +
- strlen(b->name) + 1 +
- strlen(token) + 1 +
+ unsigned long pcktsiz = (sizeof(struct ICMP) + sizeof(struct timeval) +
+ sizeof(socklen_t) + pb->addrlen +
+ strlen(token) + 1 +
strlen(pd->version) + 1);
/* Create the ICMP packet */
gettimeofday((struct timeval *) &packet[sizeof(struct ICMP)]);
# endif
- /* We store the name of the host we're pinging in the packet, and parse
+ /* We store the sockaddr of the host we're pinging in the packet, and parse
that out of the return packet later (see get_ping() for why).
After that, we also include the name and version of this program,
just to give a clue to anyone sniffing and wondering what's up.
*/
- sprintf ((char *) &packet[sizeof(struct ICMP) + sizeof(struct timeval)],
- "%.100s%c%.20s %.20s",
- b->name, 0, token, pd->version);
+ host_id = (char *) &packet[sizeof(struct ICMP) + sizeof(struct timeval)];
+ *(socklen_t *)host_id = pb->addrlen;
+ host_id += sizeof(socklen_t);
+ memcpy(host_id, &pb->address, pb->addrlen);
+ host_id += pb->addrlen;
+ sprintf (host_id, "%.20s %.20s", token, pd->version);
ICMP_CHECKSUM(icmph) = checksum((u_short *)packet, pcktsiz);
/* Send it */
if (sendto(pd->icmpsock, packet, pcktsiz, 0,
- &pb->address, sizeof(pb->address))
+ (struct sockaddr *)&pb->address, sizeof(pb->address))
!= pcktsiz)
{
#if 0
{
ping_data *pd = (ping_data *) ssd->closure;
struct sockaddr from;
- unsigned int fromlen; /* Posix says socklen_t, but that's not portable */
+ socklen_t fromlen;
int result;
u_char packet[1024];
struct timeval now;
From Valentijn Sessink <valentyn@openoffice.nl> */
if (select(pd->icmpsock + 1, &rfds, 0, 0, &tv) >0)
{
- result = recvfrom (pd->icmpsock, packet, sizeof(packet),
+ result = (int)recvfrom (pd->icmpsock, packet, sizeof(packet),
0, &from, &fromlen);
/* Check the packet */
pb->address, but it is possible that, in certain weird router
or NAT situations, that the reply will come back from a
different address than the one we sent it to. So instead,
- we parse the name out of the reply packet payload.
+ we parse the sockaddr out of the reply packet payload.
*/
{
- const char *name = (char *) &packet[iphdrlen +
- sizeof(struct ICMP) +
- sizeof(struct timeval)];
+ const socklen_t *host_id = (socklen_t *) &packet[
+ iphdrlen + sizeof(struct ICMP) + sizeof(struct timeval)];
+
sonar_bogie *b;
/* Ensure that a maliciously-crafted return packet can't
- make us overflow in strcmp. */
- packet[sizeof(packet)-1] = 0;
+ make us overflow in memcmp. */
+ if (result > 0 && (const u_char *)(host_id + 1) <= packet + result)
+ {
+ const u_char *host_end = (const u_char *)(host_id + 1) +
+ *host_id;
- for (b = pd->targets; b; b = b->next)
- if (!strcmp (name, b->name))
- {
- new = copy_ping_bogie (ssd, b);
- break;
- }
+ if ((const u_char *)(host_id + 1) <= host_end &&
+ host_end <= packet + result)
+ {
+ for (b = pd->targets; b; b = b->next)
+ {
+ ping_bogie *pb = (ping_bogie *)b->closure;
+ if (*host_id == pb->addrlen &&
+ !memcmp(&pb->address, host_id + 1, pb->addrlen) )
+ {
+ /* Check to see if the name lookup is done. */
+ if (pb->lookup_name &&
+ async_name_from_addr_is_done (pb->lookup_name))
+ {
+ char *host = NULL;
+
+ async_name_from_addr_finish (pb->lookup_name,
+ &host, NULL);
+
+ if (pd->debug_p > 1)
+ fprintf (stderr, "%s: %s => %s\n",
+ progname, b->name,
+ host ? host : "<unknown>");
+
+ if (host)
+ {
+ free(b->name);
+ b->name = host;
+ }
+
+ pb->lookup_name = NULL;
+ }
+
+ new = copy_ping_bogie (ssd, b);
+ break;
+ }
+ }
+ }
+ }
}
if (! new) /* not in targets? */
static void
ping_free_bogie_data (sonar_sensor_data *sd, void *closure)
{
+ ping_bogie *pb = (ping_bogie *) closure;
+
+ if (pb->lookup_name)
+ async_name_from_addr_cancel (pb->lookup_name);
+ if (pb->lookup_addr)
+ async_addr_from_name_cancel (pb->lookup_addr);
+ free (pb->fallback);
+
free (closure);
}
}
+static void
+free_bogie_after_lookup(sonar_sensor_data *ssd, sonar_bogie **sbp,
+ sonar_bogie **sb)
+{
+ ping_bogie *pb = (ping_bogie *)(*sb)->closure;
+
+ *sbp = (*sb)->next;
+ pb->lookup_addr = NULL; /* Prevent double-free in sonar_free_bogie. */
+ sonar_free_bogie (ssd, *sb);
+ *sb = NULL;
+}
+
+
/* Pings the next bogie, if it's time.
Returns all outstanding ping replies.
*/
if (now > pd->last_ping_time + ping_interval) /* time to ping someone */
{
+ struct sonar_bogie **sbp;
+
if (pd->last_pinged)
- pd->last_pinged = pd->last_pinged->next;
- if (! pd->last_pinged)
- pd->last_pinged = pd->targets;
- send_ping (pd, pd->last_pinged);
+ {
+ sbp = &pd->last_pinged->next;
+ if (!*sbp)
+ sbp = &pd->targets;
+ }
+ else
+ sbp = &pd->targets;
+
+ if (!*sbp)
+ /* Aaaaand we're out of bogies. */
+ pd->last_pinged = NULL;
+ else
+ {
+ sonar_bogie *sb = *sbp;
+ ping_bogie *pb = (ping_bogie *)sb->closure;
+ if (pb->lookup_addr &&
+ async_addr_from_name_is_done (pb->lookup_addr))
+ {
+ if (async_addr_from_name_finish (pb->lookup_addr, &pb->address,
+ &pb->addrlen, NULL))
+ {
+ char *fallback = pb->fallback;
+ pb->fallback = NULL;
+
+ if (pd->debug_p)
+ fprintf (stderr, "%s: could not resolve host: %s\n",
+ progname, sb->name);
+
+ free_bogie_after_lookup (ssd, sbp, &sb);
+
+ /* Insert the fallback bogie right where the old one was. */
+ if (fallback)
+ {
+ sonar_bogie *new_bogie = bogie_for_host (ssd, fallback,
+ NULL);
+ if (new_bogie) {
+ new_bogie->next = *sbp;
+
+ if (! ((ping_bogie *)new_bogie->closure)->lookup_addr &&
+ ! find_duplicate_host(pd, &pd->targets, new_bogie))
+ *sbp = new_bogie;
+ else
+ sonar_free_bogie (ssd, new_bogie);
+ }
+
+ free (fallback);
+ }
+ }
+ else
+ {
+ if (pd->debug_p > 1)
+ {
+ fprintf (stderr, "%s: %s => ", progname, sb->name);
+ print_address (stderr, 0, &pb->address, pb->addrlen);
+ putc('\n', stderr);
+ }
+
+ if (! is_address_ok (pd->debug_p, sb))
+ free_bogie_after_lookup (ssd, sbp, &sb);
+ else if (find_duplicate_host (pd, &pd->targets, sb))
+ /* Tricky: find_duplicate_host skips the current bogie when
+ scanning the targets list because pb->lookup_addr hasn't
+ been NULL'd yet.
+
+ Not that it matters much, but behavior here is to
+ keep the existing address.
+ */
+ free_bogie_after_lookup (ssd, sbp, &sb);
+ }
+
+ if (sb)
+ pb->lookup_addr = NULL;
+ }
+
+ if (sb && !pb->lookup_addr)
+ {
+ if (!pb->addrlen) abort();
+ send_ping (pd, sb);
+ pd->last_pinged = sb;
+ }
+ }
+
pd->last_ping_time = now;
}
{
/* IP: A.B.C.D
*/
- new = bogie_for_host (ssd, token, pd->resolve_p);
+ new = bogie_for_host (ssd, token, NULL);
}
else if (!strcmp (token, "subnet"))
{
{
/* not an existant file - must be a host name
*/
- new = bogie_for_host (ssd, token, pd->resolve_p);
+ new = bogie_for_host (ssd, token, NULL);
}
if (new)
const char *subnet, int timeout,
Bool resolve_p, Bool times_p, Bool debug_p)
{
+ /* Important! Do not return from this function without disavowing privileges
+ with setuid(getuid()).
+ */
sonar_sensor_data *ssd = (sonar_sensor_data *) calloc (1, sizeof(*ssd));
ping_data *pd = (ping_data *) calloc (1, sizeof(*pd));
sonar_bogie *b;
Bool socket_initted_p = False;
Bool socket_raw_p = False;
+ pd->dpy = dpy;
+
pd->resolve_p = resolve_p;
pd->times_p = times_p;
pd->debug_p = debug_p;
fprintf (stderr, "%s: Target list:\n", progname);
for (b = pd->targets; b; b = b->next)
{
- ping_bogie *pb = (ping_bogie *) b->closure;
- struct sockaddr_in *iaddr = (struct sockaddr_in *) &(pb->address);
- unsigned long ip = iaddr->sin_addr.s_addr;
fprintf (stderr, "%s: ", progname);
- print_host (stderr, ip, b->name);
+ print_host (stderr, b);
}
}