+#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) */