http://ftp.x.org/contrib/applications/xscreensaver-3.20.tar.gz
[xscreensaver] / hacks / sonar.c
index 5f6510ccce553baec7a6674ad8ee3e1785ae84c5..c4169f663dbd362d0a02dc8d492f40fb951d38c9 100644 (file)
@@ -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.9 $
+ * $Revision: 1.14 $
  *
  * Version 1.0 April 27, 1998.
  * - Initial version
 #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)
@@ -188,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;
@@ -230,7 +234,6 @@ typedef struct {
 
 static int timer_expired;
 
-
 #endif /* HAVE_PING */
 
 /*
@@ -241,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;
 
 /*
@@ -569,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 */
@@ -680,6 +699,10 @@ subnetHostsList(void)
 
     /* 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);
@@ -762,8 +785,10 @@ init_ping(void)
 
        /* Unknown source */
 
-       fprintf(stderr, "%s: illegal pingSource: %s\n", progname, 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 */
@@ -982,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?? */
@@ -1064,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;
 
@@ -1152,6 +1188,7 @@ init_sim(void)
        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 */
@@ -1174,6 +1211,7 @@ init_sim(void)
        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 */
@@ -1229,6 +1267,7 @@ 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 */
 
@@ -1316,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))
@@ -1355,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 */
@@ -1454,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));
 
@@ -1710,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);
+
     }
 }