http://gimel.esc.cam.ac.uk/james/rpld/src/rpld-1.5.tar.gz
[rpld.git] / client.c
index a884d8c..ebf7ef8 100644 (file)
--- a/client.c
+++ b/client.c
@@ -2,9 +2,9 @@
 *     rpld - an IBM style RIPL server            *
 *************************************************/
 
-/* Copyright (c) 1999, James McKenzie.
+/* Copyright (c) 1999,2000, James McKenzie.
  *                      All rights reserved
- * Copyright (c) 1998, Christopher Lightfoot.
+ * Copyright (c) 1998,2000, Christopher Lightfoot.
  *                      All rights reserved
  *
  * By using this file, you agree to the terms and conditions set
  */
 
 
-static char rcsid[] = "$Id: client.c,v 1.11 2000/07/16 13:18:10 root Exp root $";
+static char rcsid[] =
+  "$Id: client.c,v 1.20 2000/07/29 23:25:25 root Exp root $";
 
 /*
  * $Log: client.c,v $
+ * Revision 1.20  2000/07/29 23:25:25  root
+ * #
+ *
+ * Revision 1.19  2000/07/23 19:14:19  root
+ * #
+ *
+ * Revision 1.18  2000/07/23 19:07:49  root
+ * #
+ *
+ * Revision 1.17  2000/07/17 10:49:20  root
+ * #
+ *
+ * Revision 1.16  2000/07/17 10:45:38  root
+ * #
+ *
+ * Revision 1.15  2000/07/17 10:43:54  root
+ * #
+ *
+ * Revision 1.14  2000/07/17 10:43:34  root
+ * #
+ *
+ * Revision 1.13  2000/07/16 14:22:06  root
+ * #
+ *
+ * Revision 1.12  2000/07/16 14:05:28  root
+ * #
+ *
  * Revision 1.11  2000/07/16 13:18:10  root
  * #
  *
@@ -89,11 +117,29 @@ find_client_by_mac (unsigned char *mac)
 {
   struct client *pc = NULL, *c = clients;
 
+/* We need to match clients by a (possibly partial) MAC address; however
+ * this struct client is also used to transmit to them, so we need to return
+ * a struct client containing a _real_ MAC address; this is a first and
+ * pretty ugly implementation of this idea.
+ */
   while (c)
     {
-
-      if (memcmp (mac, c->mac, ETH_ALEN) == 0)
+      if (memcmp (mac, c->mac, c->partial_mac_len) == 0)
         {
+          /* if partial match, create new struct client */
+          if (c->partial_mac_len != ETH_ALEN)
+            {
+              pc = (struct client *) malloc (sizeof (struct client));
+              memcpy (pc, c, sizeof (struct client));
+
+              pc->next = c->next;
+              c->next = clients;
+              clients = c;
+
+              return pc;
+            }
+
+          /* else reorder the tree for speed, and return the found client */
           if (pc)
             {                   /*Short circuit for next time */
               pc->next = c->next;
@@ -182,6 +228,10 @@ client_get_block (struct client *c, struct rpl_packet *p)
 
   f = c->file;
 
+  p->datalen = 0;               /* Some buggy clients request
+                                   * blocks after the end when
+                                   * they get confused */
+
   if ((!f) || (NOTINRANGE (f->sblock, c->blocknum, f->eblock)))
     {
       if ((f) && (f->f))
@@ -303,11 +353,16 @@ clients_check_status ()
   struct client *c = clients;
 
   downloading = 0;
+  pacing = 0;
 
   while (c)
     {
-      if (c->state == ST_FILEDATA)
-        downloading++;
+      if ((c->state == ST_FILEDATA) && (!c->nospew))
+        {
+          downloading++;
+          if (pacing < c->pacing)
+            pacing = c->pacing;
+        }
       c = c->next;
     }
 
@@ -319,7 +374,7 @@ client_dispatch (struct nit *n)
 
   while (c)
     {
-      if (c->state == ST_FILEDATA)
+      if ((c->state == ST_FILEDATA) && (!c->nospew))
         {
           file_data_frame (n, c);
         }