BSD 4_3_Reno release
[unix-history] / usr / src / usr.bin / telnet / network.c
index e1e110c..204f3ee 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement:  ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * Neither the name of the University nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)network.c  1.15 (Berkeley) 6/28/90";
+#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 "defines.h"
 #include "externs.h"
 
 #include "defines.h"
 #include "externs.h"
+#include "fdset.h"
 
 
-Ring   netoring;
-char   netobuf[2*BUFSIZ];
+Ring   netoring, netiring;
+char   netobuf[2*BUFSIZ], netibuf[BUFSIZ];
 
 /*
  * Initialize internal network data structures.
 
 /*
  * Initialize internal network data structures.
@@ -20,7 +44,12 @@ char netobuf[2*BUFSIZ];
 
 init_network()
 {
 
 init_network()
 {
-    ring_init(&netoring, netobuf, sizeof 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;
 }
 
@@ -31,8 +60,7 @@ init_network()
  */
 
 int
  */
 
 int
-stilloob(s)
-int    s;              /* socket number */
+stilloob()
 {
     static struct timeval timeout = { 0 };
     fd_set     excepts;
 {
     static struct timeval timeout = { 0 };
     fd_set     excepts;
@@ -40,15 +68,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;
@@ -82,9 +111,9 @@ setneturg()
 int
 netflush()
 {
 int
 netflush()
 {
-    int n;
+    register int n, n1;
 
 
-    if ((n = ring_full_consecutive(&netoring)) > 0) {
+    if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
        if (!ring_at_mark(&netoring)) {
            n = send(net, netoring.consume, n, 0);      /* normal write */
        } else {
        if (!ring_at_mark(&netoring)) {
            n = send(net, netoring.consume, n, 0);      /* normal write */
        } else {
@@ -103,7 +132,7 @@ netflush()
        if (errno != ENOBUFS && errno != EWOULDBLOCK) {
            setcommandmode();
            perror(hostname);
        if (errno != ENOBUFS && errno != EWOULDBLOCK) {
            setcommandmode();
            perror(hostname);
-           NetClose(net);
+           (void)NetClose(net);
            ring_clear_mark(&netoring);
            longjmp(peerdied, -1);
            /*NOTREACHED*/
            ring_clear_mark(&netoring);
            longjmp(peerdied, -1);
            /*NOTREACHED*/
@@ -113,149 +142,17 @@ netflush()
     if (netdata && n) {
        Dump('>', netoring.consume, n);
     }
     if (netdata && n) {
        Dump('>', netoring.consume, n);
     }
-    ring_consumed(&netoring, n);
-    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;
-    }
-}
-
-/*
- * 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()
-{
-#if    0       /* XXX */
-    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)) <= netobuf.send) {
-       thisitem = next;
-    }
-
-    /* Now, thisitem is first before/at boundary. */
-
-    good = netobuf;    /* where the good bytes go */
-
-    while (netoring.add > 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);
-       }
-    }
-
-#endif /* 0 */
-    ring_init(&netoring, netobuf, sizeof netobuf);
-}
-
-#include <varargs.h>
-
-void
-netoprint(va_alist)
-va_dcl
-{
-    va_list ap;
-    char buffer[100];          /* where things go */
-    char *ptr;
-    char *format;
-    char *string;
-    int i;
-
-    va_start(ap);
-
-    format = va_arg(ap, char *);
-    ptr = buffer;
-
-    while ((i = *format++) != 0) {
-       if (i == '%') {
-           i = *format++;
-           switch (i) {
-           case 'c':
-               *ptr++ = va_arg(ap, int);
-               break;
-           case 's':
-               string = va_arg(ap, char *);
-               ring_supply_data(&netoring, buffer, ptr-buffer);
-               ring_supply_data(&netoring, string, strlen(string));
-               ptr = buffer;
-               break;
-           case 0:
-               ExitString("netoprint: trailing %%.\n", 1);
-               /*NOTREACHED*/
-           default:
-               ExitString("netoprint: unknown format character.\n", 1);
-               /*NOTREACHED*/
-           }
-       } else {
-           *ptr++ = i;
+    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;
     }
     }
-    ring_supply_data(&netoring, buffer, ptr-buffer);
 }
 }