Telnet AUTHENTICATION option
[unix-history] / usr / src / usr.bin / telnet / network.c
index 95658a3..1601417 100644 (file)
@@ -1,3 +1,14 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)network.c  5.2 (Berkeley) %G%";
+#endif /* not lint */
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 
 #include <arpa/telnet.h>
 
 
 #include <arpa/telnet.h>
 
+#include "ring.h"
+
 #include "defines.h"
 #include "externs.h"
 #include "defines.h"
 #include "externs.h"
+#include "fdset.h"
 
 
-char   netobuf[2*BUFSIZ], *nfrontp, *nbackp;
-static char    *neturg;                /* one past last byte of urgent data */
+Ring           netoring, netiring;
+unsigned char  netobuf[2*BUFSIZ], netibuf[BUFSIZ];
 
 /*
  * Initialize internal network data structures.
  */
 
 
 /*
  * Initialize internal network data structures.
  */
 
+    void
 init_network()
 {
 init_network()
 {
-    nfrontp = nbackp = netobuf;
+    if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
+       exit(1);
+    }
+    if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
+       exit(1);
+    }
     NetTrace = stdout;
 }
 
     NetTrace = stdout;
 }
 
@@ -28,9 +48,8 @@ init_network()
  * Telnet "synch" processing).
  */
 
  * Telnet "synch" processing).
  */
 
-int
-stilloob(s)
-int    s;              /* socket number */
+    int
+stilloob()
 {
     static struct timeval timeout = { 0 };
     fd_set     excepts;
 {
     static struct timeval timeout = { 0 };
     fd_set     excepts;
@@ -38,15 +57,16 @@ int s;              /* socket number */
 
     do {
        FD_ZERO(&excepts);
 
     do {
        FD_ZERO(&excepts);
-       FD_SET(s, &excepts);
-       value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
+       FD_SET(net, &excepts);
+       value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
     } while ((value == -1) && (errno == EINTR));
 
     if (value < 0) {
        perror("select");
     } while ((value == -1) && (errno == EINTR));
 
     if (value < 0) {
        perror("select");
-       quit();
+       (void) quit();
+       /* NOTREACHED */
     }
     }
-    if (FD_ISSET(s, &excepts)) {
+    if (FD_ISSET(net, &excepts)) {
        return 1;
     } else {
        return 0;
        return 1;
     } else {
        return 0;
@@ -60,10 +80,10 @@ int s;              /* socket number */
  *     Sets "neturg" to the current location.
  */
 
  *     Sets "neturg" to the current location.
  */
 
-void
+    void
 setneturg()
 {
 setneturg()
 {
-    neturg = NETLOC()-1;       /* Some systems are off by one XXX */
+    ring_mark(&netoring);
 }
 
 
 }
 
 
@@ -77,16 +97,19 @@ setneturg()
  */
 
 
  */
 
 
-int
+    int
 netflush()
 {
 netflush()
 {
-    int n;
-
-    if ((n = nfrontp - nbackp) > 0) {
-       if (!neturg) {
-           n = send(net, nbackp, n, 0);        /* normal write */
+    register int n, n1;
+
+#if    defined(ENCRYPT)
+    if (encrypt_output)
+       ring_encrypt(&netoring, encrypt_output);
+#endif
+    if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
+       if (!ring_at_mark(&netoring)) {
+           n = send(net, netoring.consume, n, 0);      /* normal write */
        } else {
        } else {
-           n = neturg - nbackp;
            /*
             * In 4.2 (and 4.3) systems, there is some question about
             * what byte in a sendOOB operation is the "OOB" data.
            /*
             * In 4.2 (and 4.3) systems, there is some question about
             * what byte in a sendOOB operation is the "OOB" data.
@@ -95,130 +118,34 @@ netflush()
             * we really have more the TCP philosophy of urgent data
             * rather than the Unix philosophy of OOB data).
             */
             * we really have more the TCP philosophy of urgent data
             * rather than the Unix philosophy of OOB data).
             */
-           if (n > 1) {
-               n = send(net, nbackp, n-1, 0);  /* send URGENT all by itself */
-           } else {
-               n = send(net, nbackp, n, MSG_OOB);      /* URGENT data */
-           }
+           n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */
        }
     }
     if (n < 0) {
        if (errno != ENOBUFS && errno != EWOULDBLOCK) {
            setcommandmode();
            perror(hostname);
        }
     }
     if (n < 0) {
        if (errno != ENOBUFS && errno != EWOULDBLOCK) {
            setcommandmode();
            perror(hostname);
-           NetClose(net);
-           neturg = 0;
+           (void)NetClose(net);
+           ring_clear_mark(&netoring);
            longjmp(peerdied, -1);
            /*NOTREACHED*/
        }
        n = 0;
     }
     if (netdata && n) {
            longjmp(peerdied, -1);
            /*NOTREACHED*/
        }
        n = 0;
     }
     if (netdata && n) {
-       Dump('>', nbackp, n);
-    }
-    nbackp += n;
-    if (nbackp >= neturg) {
-       neturg = 0;
-    }
-    if (nbackp == nfrontp) {
-       nbackp = nfrontp = netobuf;
-    }
-    return n > 0;
-}
-\f
-/*
- * nextitem()
- *
- *     Return the address of the next "item" in the TELNET data
- * stream.  This will be the address of the next character if
- * the current address is a user data character, or it will
- * be the address of the character following the TELNET command
- * if the current address is a TELNET IAC ("I Am a Command")
- * character.
- */
-
-static char *
-nextitem(current)
-char   *current;
-{
-    if ((*current&0xff) != IAC) {
-       return current+1;
-    }
-    switch (*(current+1)&0xff) {
-    case DO:
-    case DONT:
-    case WILL:
-    case WONT:
-       return current+3;
-    case SB:           /* loop forever looking for the SE */
-       {
-           register char *look = current+2;
-
-           for (;;) {
-               if ((*look++&0xff) == IAC) {
-                   if ((*look++&0xff) == SE) {
-                       return look;
-                   }
-               }
-           }
-       }
-    default:
-       return current+2;
+       Dump('>', netoring.consume, n);
     }
     }
-}
-/*
- * netclear()
- *
- *     We are about to do a TELNET SYNCH operation.  Clear
- * the path to the network.
- *
- *     Things are a bit tricky since we may have sent the first
- * byte or so of a previous TELNET command into the network.
- * So, we have to scan the network buffer from the beginning
- * until we are up to where we want to be.
- *
- *     A side effect of what we do, just to keep things
- * simple, is to clear the urgent data pointer.  The principal
- * caller should be setting the urgent data pointer AFTER calling
- * us in any case.
- */
-
-void
-netclear()
-{
-    register char *thisitem, *next;
-    char *good;
-#define        wewant(p)       ((nfrontp > p) && ((*p&0xff) == IAC) && \
-                               ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
-
-    thisitem = netobuf;
-
-    while ((next = nextitem(thisitem)) <= nbackp) {
-       thisitem = next;
-    }
-
-    /* Now, thisitem is first before/at boundary. */
-
-    good = netobuf;    /* where the good bytes go */
-
-    while (nfrontp > thisitem) {
-       if (wewant(thisitem)) {
-           int length;
-
-           next = thisitem;
-           do {
-               next = nextitem(next);
-           } while (wewant(next) && (nfrontp > next));
-           length = next-thisitem;
-           memcpy(good, thisitem, length);
-           good += length;
-           thisitem = next;
-       } else {
-           thisitem = nextitem(thisitem);
+    if (n) {
+       ring_consumed(&netoring, n);
+       /*
+        * If we sent all, and more to send, then recurse to pick
+        * up the other half.
+        */
+       if ((n1 == n) && ring_full_consecutive(&netoring)) {
+           (void) netflush();
        }
        }
+       return 1;
+    } else {
+       return 0;
     }
     }
-
-    nbackp = netobuf;
-    nfrontp = good;            /* next byte to be sent */
-    neturg = 0;
 }
 }