X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fsonar.c;h=c4169f663dbd362d0a02dc8d492f40fb951d38c9;hb=72c1f4c1dc6ab07fe121a327ff1c30bf51ef74c1;hp=4b3aae08652d3cb9a5d0cc590d9e6efd1ecfeb39;hpb=f54438ea00f152166e68073e98000fd3a00f65cd;p=xscreensaver diff --git a/hacks/sonar.c b/hacks/sonar.c index 4b3aae08..c4169f66 100644 --- a/hacks/sonar.c +++ b/hacks/sonar.c @@ -28,7 +28,7 @@ * - 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 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 @@ -37,7 +37,7 @@ * software for any purpose. It is provided "as is" without express or * implied warranty. * - * $Revision: 1.7 $ + * $Revision: 1.14 $ * * Version 1.0 April 27, 1998. * - Initial version @@ -75,11 +75,10 @@ * - 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 */ @@ -88,6 +87,10 @@ #include #include +#include "screenhack.h" +#include "colors.h" +#include "hsv.h" + #if defined(HAVE_ICMP) || defined(HAVE_ICMPHDR) # include # include @@ -107,18 +110,16 @@ # include #endif /* HAVE_ICMP || HAVE_ICMPHDR */ -#include "screenhack.h" -#include "colors.h" -#include "hsv.h" - -#include - /* 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) @@ -191,7 +192,7 @@ typedef struct { 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 */ } sonar_info; @@ -233,7 +234,6 @@ typedef struct { static int timer_expired; - #endif /* HAVE_PING */ /* @@ -244,7 +244,7 @@ typedef struct sim_target { 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; /* @@ -351,7 +351,7 @@ newBogie(char *name, int distance, int tick, int ttl) /* 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; @@ -449,7 +449,8 @@ lookupHost(ping_target *target) struct hostent *hent = gethostbyname(target->name); if (hent == NULL) { - fprintf(stderr, "Could not resolve host %s\n", target->name); + fprintf(stderr, "%s: could not resolve host %s\n", + progname, target->name); return 0; } memcpy(&iaddr->sin_addr, hent->h_addr_list[0], @@ -482,11 +483,11 @@ newHost(char *name) /* 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; } @@ -534,7 +535,7 @@ readPingHostsFile(char *fname) /* 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; } @@ -542,7 +543,7 @@ readPingHostsFile(char *fname) 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; } @@ -571,12 +572,28 @@ readPingHostsFile(char *fname) 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 */ @@ -660,14 +677,14 @@ subnetHostsList(void) /* 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]))); @@ -675,13 +692,17 @@ subnetHostsList(void) /* Get a pointer to the last "." in the string */ if ((p = strrchr(address, '.')) == NULL) { - fprintf(stderr, "Can't parse IP address %s\n", address); + fprintf(stderr, "%s: can't parse IP address %s\n", progname, address); return NULL; } p++; /* Construct targets for all addresses in this subnet */ + /* #### jwz: actually, this is wrong, since it assumes a + netmask of 255.255.255.0. But I'm not sure how to find + the local netmask. + */ for (i = 254; i > 0; i--) { sprintf(p, "%d", i); new = newHost(address); @@ -716,14 +737,16 @@ init_ping(void) /* 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 */ if ((pi->icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { - perror("Can't create ICMP socket"); + char msg[1024]; + sprintf(msg, "%s: can't create ICMP socket", progname); + perror(msg); fprintf(stderr, "%s: this program must be setuid to root for `ping mode' to work.\n", progname); @@ -762,14 +785,16 @@ init_ping(void) /* Unknown source */ - fprintf(stderr, "Illegal pingSource: %s\n", src); - goto ping_init_error; + fprintf(stderr, + "%s: pingSource must be `file', `list', or `subnet', not: %s\n", + progname, src); + exit (1); } /* Make sure there is something to ping */ if (pi->targets == NULL) { - fprintf(stderr, "Nothing to ping"); + fprintf(stderr, "%s: nothing to ping", progname); goto ping_init_error; } @@ -843,7 +868,7 @@ sendping(ping_info *pi, ping_target *pt) &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 } @@ -956,7 +981,9 @@ getping(sonar_info *si, ping_info *pi, int ttl) 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); } @@ -980,7 +1007,13 @@ getping(sonar_info *si, ping_info *pi, int ttl) 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?? */ @@ -1003,7 +1036,7 @@ getping(sonar_info *si, ping_info *pi, int ttl) 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; } @@ -1062,6 +1095,11 @@ static Bogie * 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; @@ -1126,7 +1164,7 @@ init_sim(void) /* 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; } @@ -1136,7 +1174,7 @@ init_sim(void) 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"); @@ -1144,12 +1182,13 @@ init_sim(void) 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 */ @@ -1158,7 +1197,7 @@ init_sim(void) 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"); @@ -1166,12 +1205,13 @@ init_sim(void) 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 */ @@ -1206,7 +1246,7 @@ init_sonar(Display *dpy, Window win) /* 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; } @@ -1227,13 +1267,14 @@ init_sonar(Display *dpy, Window win) 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; } @@ -1314,7 +1355,6 @@ updateLocation(sim_target *t) 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)) @@ -1353,29 +1393,30 @@ simulator(sonar_info *si, void *vinfo) for (i = 0; i < info->numA; i++) { t = &info->teamA[i]; - if (!t->movedlasttick && (t->nexttick == (si->current * -1))) { + if ((t->movedonsweep != si->sweepnum) && + (t->nexttick == (si->current * -1))) { new = newBogie(strdup(t->name), t->nextdist, si->current, 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))) { + if ((t->movedonsweep != si->sweepnum) && + (t->nexttick == (si->current * -1))) { new = newBogie(strdup(t->name), t->nextdist, si->current, TTL); if (list != NULL) new->next = list; list = new; - t->movedlasttick = 1; updateLocation(t); - } else - t->movedlasttick = 0; + t->movedonsweep = si->sweepnum; + } } /* Done */ @@ -1452,7 +1493,8 @@ DrawBogie(sonar_info *si, int draw, char *name, int degrees, /* 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)); @@ -1685,7 +1727,7 @@ screenhack(Display *dpy, Window win) if ((sensor_info = (void *) init_sim()) == NULL) exit(1); } else { - fprintf(stderr, "Unsupported Sonar mode: %s\n", mode); + fprintf(stderr, "%s: unsupported Sonar mode: %s\n", progname, mode); fprintf(stderr, "\tCurrently supported modes are `ping' and `simulation'\n"); exit(1); @@ -1708,11 +1750,14 @@ screenhack(Display *dpy, Window win) /* 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); + } }