date and time created 87/09/11 15:40:50 by minshall
authorGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Sat, 12 Sep 1987 06:40:50 +0000 (22:40 -0800)
committerGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Sat, 12 Sep 1987 06:40:50 +0000 (22:40 -0800)
SCCS-vsn: usr.bin/telnet/terminal.c 1.1

usr/src/usr.bin/telnet/terminal.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/telnet/terminal.c b/usr/src/usr.bin/telnet/terminal.c
new file mode 100644 (file)
index 0000000..ea33ff7
--- /dev/null
@@ -0,0 +1,364 @@
+#include <arpa/telnet.h>
+
+#include "externs.h"
+#include "types.h"
+
+char   ttyobuf[2*BUFSIZ], *tfrontp, *tbackp;
+
+char
+    termEofChar,
+    termEraseChar,
+    termFlushChar,
+    termIntChar,
+    termKillChar,
+    termLiteralNextChar,
+    termQuitChar;
+
+/*
+ * initialize the terminal data structures.
+ */
+
+init_terminal()
+{
+    tfrontp = tbackp = ttyobuf;
+    autoflush = TerminalAutoFlush();
+}
+
+
+/*
+ *             Send as much data as possible to the terminal.
+ *
+ *             The return value indicates whether we did any
+ *     useful work.
+ */
+
+
+int
+ttyflush()
+{
+    int n;
+
+    if ((n = tfrontp - tbackp) > 0) {
+       if (!(SYNCHing||flushout)) {
+           n = TerminalWrite(tout, tbackp, n);
+       } else {
+           TerminalFlushOutput();
+           /* we leave 'n' alone! */
+       }
+    }
+    if (n >= 0) {
+       tbackp += n;
+       if (tbackp == tfrontp) {
+           tbackp = tfrontp = ttyobuf;
+       }
+    }
+    return n > 0;
+}
+
+#if    defined(TN3270)
+
+#if    defined(unix)
+static void
+inputAvailable()
+{
+    HaveInput = 1;
+}
+#endif /* defined(unix) */
+
+void
+outputPurge()
+{
+    int tmp = flushout;
+
+    flushout = 1;
+
+    ttyflush();
+
+    flushout = tmp;
+}
+
+#endif /* defined(TN3270) */
+\f
+#if    defined(unix)
+/*
+ * Various signal handling routines.
+ */
+
+void
+deadpeer()
+{
+       setcommandmode();
+       longjmp(peerdied, -1);
+}
+
+void
+intr()
+{
+    if (localchars) {
+       intp();
+       return;
+    }
+    setcommandmode();
+    longjmp(toplevel, -1);
+}
+
+void
+intr2()
+{
+    if (localchars) {
+       sendbrk();
+       return;
+    }
+}
+
+void
+doescape()
+{
+    command(0);
+}
+#endif /* defined(unix) */
+\f
+/*
+ * These routines decides on what the mode should be (based on the values
+ * of various global variables).
+ */
+
+
+int
+getconnmode()
+{
+    static char newmode[16] =
+                       { 4, 5, 3, 3, 2, 2, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6 };
+    int modeindex = 0;
+
+    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
+       modeindex += 1;
+    }
+    if (hisopts[TELOPT_ECHO]) {
+       modeindex += 2;
+    }
+    if (hisopts[TELOPT_SGA]) {
+       modeindex += 4;
+    }
+    if (In3270) {
+       modeindex += 8;
+    }
+    return newmode[modeindex];
+}
+
+void
+setconnmode()
+{
+    TerminalNewMode(tin, tout, getconnmode());
+}
+
+
+void
+setcommandmode()
+{
+    TerminalNewMode(tin, tout, 0);
+}
+
+#if    defined(TN3270)
+
+/*
+ * The following routines are places where the various tn3270
+ * routines make calls into telnet.c.
+ */
+
+/* TtyChars() - returns the number of characters in the TTY buffer */
+TtyChars()
+{
+    return(tfrontp-tbackp);
+}
+
+/*
+ * DataToNetwork - queue up some data to go to network.  If "done" is set,
+ * then when last byte is queued, we add on an IAC EOR sequence (so,
+ * don't call us with "done" until you want that done...)
+ *
+ * We actually do send all the data to the network buffer, since our
+ * only client needs for us to do that.
+ */
+
+int
+DataToNetwork(buffer, count, done)
+register char  *buffer;        /* where the data is */
+register int   count;          /* how much to send */
+int            done;           /* is this the last of a logical block */
+{
+    register int c;
+    int origCount;
+    fd_set o;
+
+    origCount = count;
+    FD_ZERO(&o);
+
+    while (count) {
+       if ((netobuf+sizeof netobuf - nfrontp) < 6) {
+           netflush();
+           while ((netobuf+sizeof netobuf - nfrontp) < 6) {
+               FD_SET(net, &o);
+               (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
+                                               (struct timeval *) 0);
+               netflush();
+           }
+       }
+       c = *buffer++;
+       count--;
+       if (c == IAC) {
+           *nfrontp++ = IAC;
+           *nfrontp++ = IAC;
+       } else {
+           *nfrontp++ = c;
+       }
+    }
+
+    if (done && !count) {
+       *nfrontp++ = IAC;
+       *nfrontp++ = EOR;
+       netflush();             /* try to move along as quickly as ... */
+    }
+    return(origCount - count);
+}
+
+/* DataToTerminal - queue up some data to go to terminal. */
+
+int
+DataToTerminal(buffer, count)
+register char  *buffer;                /* where the data is */
+register int   count;                  /* how much to send */
+{
+    int origCount;
+#if    defined(unix)
+    fd_set     o;
+
+    FD_ZERO(&o);
+#endif /* defined(unix) */
+    origCount = count;
+
+    while (count) {
+       if (tfrontp >= ttyobuf+sizeof ttyobuf) {
+           ttyflush();
+           while (tfrontp >= ttyobuf+sizeof ttyobuf) {
+#if    defined(unix)
+               FD_SET(tout, &o);
+               (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
+                                               (struct timeval *) 0);
+#endif /* defined(unix) */
+               ttyflush();
+           }
+       }
+       *tfrontp++ = *buffer++;
+       count--;
+    }
+    return(origCount - count);
+}
+
+/* EmptyTerminal - called to make sure that the terminal buffer is empty.
+ *                     Note that we consider the buffer to run all the
+ *                     way to the kernel (thus the select).
+ */
+
+void
+EmptyTerminal()
+{
+#if    defined(unix)
+    fd_set     o;
+
+    FD_ZERO(&o);
+#endif /* defined(unix) */
+
+    if (tfrontp == tbackp) {
+#if    defined(unix)
+       FD_SET(tout, &o);
+       (void) select(tout+1, (int *) 0, &o, (int *) 0,
+                       (struct timeval *) 0);  /* wait for TTLOWAT */
+#endif /* defined(unix) */
+    } else {
+       while (tfrontp != tbackp) {
+           ttyflush();
+#if    defined(unix)
+           FD_SET(tout, &o);
+           (void) select(tout+1, (int *) 0, &o, (int *) 0,
+                               (struct timeval *) 0);  /* wait for TTLOWAT */
+#endif /* defined(unix) */
+       }
+    }
+}
+\f
+
+/*
+ * Push3270 - Try to send data along the 3270 output (to screen) direction.
+ */
+
+static int
+Push3270()
+{
+    int save = scc;
+
+    if (scc) {
+       if (Ifrontp+scc > Ibuf+sizeof Ibuf) {
+           if (Ibackp != Ibuf) {
+               memcpy(Ibuf, Ibackp, Ifrontp-Ibackp);
+               Ifrontp -= (Ibackp-Ibuf);
+               Ibackp = Ibuf;
+           }
+       }
+       if (Ifrontp+scc < Ibuf+sizeof Ibuf) {
+           telrcv();
+       }
+    }
+    return save != scc;
+}
+
+
+/*
+ * Finish3270 - get the last dregs of 3270 data out to the terminal
+ *             before quitting.
+ */
+
+static void
+Finish3270()
+{
+    while (Push3270() || !DoTerminalOutput()) {
+#if    defined(unix)
+       HaveInput = 0;
+#endif /* defined(unix) */
+       ;
+    }
+}
+
+
+/* StringToTerminal - output a null terminated string to the terminal */
+
+void
+StringToTerminal(s)
+char *s;
+{
+    int count;
+
+    count = strlen(s);
+    if (count) {
+       (void) DataToTerminal(s, count);        /* we know it always goes... */
+    }
+}
+
+
+#if    ((!defined(NOT43)) || defined(PUTCHAR))
+/* _putchar - output a single character to the terminal.  This name is so that
+ *     curses(3x) can call us to send out data.
+ */
+
+void
+_putchar(c)
+char c;
+{
+    if (tfrontp >= ttyobuf+sizeof ttyobuf) {
+       (void) DataToTerminal(&c, 1);
+    } else {
+       *tfrontp++ = c;         /* optimize if possible. */
+    }
+}
+#endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */
+#endif /* defined(TN3270) */