first cut at new makefile; file reorg, new depend
[unix-history] / usr / src / usr.bin / telnet / sys_bsd.c
index 7bd03ae..e4b2bbc 100644 (file)
@@ -1,3 +1,24 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sys_bsd.c  1.17 (Berkeley) %G%";
+#endif /* not lint */
+
 /*
  * The following routines try to encapsulate what is system dependent
  * (at least between 4.x and dos) which is used in telnet.c.
 /*
  * The following routines try to encapsulate what is system dependent
  * (at least between 4.x and dos) which is used in telnet.c.
@@ -5,6 +26,7 @@
 
 #if    defined(unix)
 
 
 #if    defined(unix)
 
+#include <fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/time.h>
 
 #include "ring.h"
 
 
 #include "ring.h"
 
+#include "fdset.h"
+
 #include "defines.h"
 #include "externs.h"
 #include "types.h"
 
 #include "defines.h"
 #include "externs.h"
 #include "types.h"
 
-#ifndef        FD_SETSIZE
-/*
- * The following is defined just in case someone should want to run
- * this telnet on a 4.2 system.
- *
- */
-
-#define        FD_SET(n, p)    ((p)->fds_bits[0] |= (1<<(n)))
-#define        FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1<<(n)))
-#define        FD_ISSET(n, p)  ((p)->fds_bits[0] & (1<<(n)))
-#define FD_ZERO(p)     ((p)->fds_bits[0] = 0)
-
-#endif
-
 int
        tout,                   /* Output file descriptor */
        tin,                    /* Input file descriptor */
 int
        tout,                   /* Output file descriptor */
        tin,                    /* Input file descriptor */
-       net,
-       HaveInput;              /* There is input available to scan */
-
-#if    defined(TN3270)
-static char    tline[200];
-char   *transcom = 0;  /* transparent mode command (default: none) */
-#endif /* defined(TN3270) */
+       net;
 
 static struct  tchars otc = { 0 }, ntc = { 0 };
 static struct  ltchars oltc = { 0 }, nltc = { 0 };
 
 static struct  tchars otc = { 0 }, ntc = { 0 };
 static struct  ltchars oltc = { 0 }, nltc = { 0 };
@@ -62,20 +66,18 @@ init_sys()
 }
 
 
 }
 
 
-TerminalWrite(fd, buf, n)
-int    fd;
+TerminalWrite(buf, n)
 char   *buf;
 int    n;
 {
 char   *buf;
 int    n;
 {
-    return write(fd, buf, n);
+    return write(tout, buf, n);
 }
 
 }
 
-TerminalRead(fd, buf, n)
-int    fd;
+TerminalRead(buf, n)
 char   *buf;
 int    n;
 {
 char   *buf;
 int    n;
 {
-    return read(fd, buf, n);
+    return read(tin, buf, n);
 }
 
 /*
 }
 
 /*
@@ -83,7 +85,7 @@ int   n;
  */
 
 int
  */
 
 int
-TerminalAutoFlush()                                    /* unix */
+TerminalAutoFlush()
 {
 #if    defined(LNOFLSH)
     int flush;
 {
 #if    defined(LNOFLSH)
     int flush;
@@ -108,10 +110,10 @@ TerminalAutoFlush()                                       /* unix */
  */
 
 int
  */
 
 int
-TerminalSpecialChars(c)                        /* unix */
+TerminalSpecialChars(c)
 int    c;
 {
 int    c;
 {
-    void doflush(), intp(), sendbrk();
+    void xmitAO(), xmitEL(), xmitEC(), intp(), sendbrk();
 
     if (c == ntc.t_intrc) {
        intp();
 
     if (c == ntc.t_intrc) {
        intp();
@@ -140,13 +142,13 @@ int       c;
  */
  
 void
  */
  
 void
-TerminalFlushOutput()                          /* unix */
+TerminalFlushOutput()
 {
     (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
 }
 
 void
 {
     (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
 }
 
 void
-TerminalSaveState()                            /* unix */
+TerminalSaveState()
 {
     ioctl(0, TIOCGETP, (char *)&ottyb);
     ioctl(0, TIOCGETC, (char *)&otc);
 {
     ioctl(0, TIOCGETP, (char *)&ottyb);
     ioctl(0, TIOCGETC, (char *)&otc);
@@ -165,7 +167,7 @@ TerminalSaveState()                         /* unix */
 }
 
 void
 }
 
 void
-TerminalRestoreState()                         /* unix */
+TerminalRestoreState()
 {
 }
 
 {
 }
 
@@ -175,8 +177,7 @@ TerminalRestoreState()                              /* unix */
 
 
 void
 
 
 void
-TerminalNewMode(fd_in, fd_out, f)                      /* unix */
-int    fd_in, fd_out;          /* File descriptor */
+TerminalNewMode(f)
 register int f;
 {
     static int prevmode = 0;
 register int f;
 {
     static int prevmode = 0;
@@ -217,7 +218,7 @@ register int f;
                sb.sg_flags |= ECHO|CRMOD;
            }
            sb.sg_erase = sb.sg_kill = -1;
                sb.sg_flags |= ECHO|CRMOD;
            }
            sb.sg_erase = sb.sg_kill = -1;
-           if (f == 6) {
+           if (localflow || (f == 6)) {
                tc = &tc3;
                tc3 = notc;
                    /* get XON, XOFF characters */
                tc = &tc3;
                tc3 = notc;
                    /* get XON, XOFF characters */
@@ -277,40 +278,80 @@ register int f;
     default:
            return;
     }
     default:
            return;
     }
-    ioctl(fd_in, TIOCSLTC, (char *)ltc);
-    ioctl(fd_in, TIOCSETC, (char *)tc);
-    ioctl(fd_in, TIOCSETP, (char *)&sb);
+    ioctl(tin, TIOCSLTC, (char *)ltc);
+    ioctl(tin, TIOCSETC, (char *)tc);
+    ioctl(tin, TIOCSETP, (char *)&sb);
 #if    (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))
 #if    (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))
-    ioctl(fd_in, FIONBIO, (char *)&onoff);
-    ioctl(fd_out, FIONBIO, (char *)&onoff);
+    ioctl(tin, FIONBIO, (char *)&onoff);
+    ioctl(tout, FIONBIO, (char *)&onoff);
 #endif /* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */
 #if    defined(TN3270)
 #endif /* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */
 #if    defined(TN3270)
-    if (noasynch == 0) {
-       ioctl(fd_in, FIOASYNC, (char *)&onoff);
+    if (noasynchtty == 0) {
+       ioctl(tin, FIOASYNC, (char *)&onoff);
     }
 #endif /* defined(TN3270) */
 
     if (MODE_LINE(f)) {
        void doescape();
 
     }
 #endif /* defined(TN3270) */
 
     if (MODE_LINE(f)) {
        void doescape();
 
-       signal(SIGTSTP, doescape);
+       (void) signal(SIGTSTP, (int (*)())doescape);
     } else if (MODE_LINE(old)) {
     } else if (MODE_LINE(old)) {
-       signal(SIGTSTP, SIG_DFL);
+       (void) signal(SIGTSTP, SIG_DFL);
        sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
     }
 }
 
        sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
     }
 }
 
+void
+TerminalSpeeds(ispeed, ospeed)
+long *ispeed;
+long *ospeed;
+{
+    /*
+     * The order here is important.  The index of each speed needs to
+     * correspond with the sgtty structure value for that speed.
+     *
+     * Additionally, the search algorithm assumes the table is in
+     * ascending sequence.
+     */
+    static int ttyspeeds[] = {
+           0, 50, 75, 110, 134, 150, 200, 300,
+           600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 };
+#define NUMSPEEDS sizeof ttyspeeds/sizeof ttyspeeds[0]
+
+    if ((ottyb.sg_ospeed < 0) || (ottyb.sg_ospeed > NUMSPEEDS) ||
+       (ottyb.sg_ispeed < 0) || (ottyb.sg_ispeed > NUMSPEEDS)) {
+       ExitString("Invalid terminal speed.");
+       /*NOTREACHED*/
+    } else {
+       *ispeed = ttyspeeds[ottyb.sg_ispeed];
+       *ospeed = ttyspeeds[ottyb.sg_ospeed];
+    }
+}
+
+int
+TerminalWindowSize(rows, cols)
+long *rows, *cols;
+{
+    struct winsize ws;
+
+    if (ioctl(fileno(stdin), TIOCGWINSZ, (char *)&ws) < 0) {
+       return 0;
+    }
+    *rows = ws.ws_row;
+    *cols = ws.ws_col;
+    return 1;
+}
 
 int
 
 int
-NetClose(net)
-int    net;
+NetClose(fd)
+int    fd;
 {
 {
-    return close(net);
+    return close(fd);
 }
 
 
 void
 }
 
 
 void
-NetNonblockingIO(fd, onoff)                            /* unix */
+NetNonblockingIO(fd, onoff)
 int
        fd,
        onoff;
 int
        fd,
        onoff;
@@ -318,8 +359,9 @@ int
     ioctl(fd, FIONBIO, (char *)&onoff);
 }
 
     ioctl(fd, FIONBIO, (char *)&onoff);
 }
 
+#if    defined(TN3270)
 void
 void
-NetSigIO(fd, onoff)                            /* unix */
+NetSigIO(fd, onoff)
 int
        fd,
        onoff;
 int
        fd,
        onoff;
@@ -328,39 +370,84 @@ int
 }
 
 void
 }
 
 void
-NetSetPgrp(fd)                         /* unix */
+NetSetPgrp(fd)
 int fd;
 {
     int myPid;
 
     myPid = getpid();
 int fd;
 {
     int myPid;
 
     myPid = getpid();
-#if    defined(NOT43)
-    myPid = -myPid;
-#endif /* defined(NOT43) */
-    ioctl(fd, SIOCSPGRP, (char *)&myPid);      /* set my pid */
+    fcntl(fd, F_SETOWN, myPid);
+}
+#endif /*defined(TN3270)*/
+\f
+/*
+ * Various signal handling routines.
+ */
+
+static void
+deadpeer()
+{
+       setcommandmode();
+       longjmp(peerdied, -1);
 }
 
 }
 
+static void
+intr()
+{
+    if (localchars) {
+       intp();
+       return;
+    }
+    setcommandmode();
+    longjmp(toplevel, -1);
+}
 
 
+static void
+intr2()
+{
+    if (localchars) {
+       sendbrk();
+       return;
+    }
+}
+
+static void
+sendwin()
+{
+    if (connected) {
+       sendnaws();
+    }
+}
+
+static void
+doescape()
+{
+    command(0);
+}
+\f
 void
 sys_telnet_init()
 {
 void
 sys_telnet_init()
 {
-#if    defined(TN3270) && defined(unix)
-    int myPid;
-#endif /* defined(TN3270) */
+    (void) signal(SIGINT, (int (*)())intr);
+    (void) signal(SIGQUIT, (int (*)())intr2);
+    (void) signal(SIGPIPE, (int (*)())deadpeer);
+    (void) signal(SIGWINCH, (int (*)())sendwin);
 
     setconnmode();
 
     NetNonblockingIO(net, 1);
 
 #if    defined(TN3270)
 
     setconnmode();
 
     NetNonblockingIO(net, 1);
 
 #if    defined(TN3270)
-    if (noasynch == 0) {                       /* DBX can't handle! */
+    if (noasynchnet == 0) {                    /* DBX can't handle! */
        NetSigIO(net, 1);
        NetSetPgrp(net);
     }
 #endif /* defined(TN3270) */
 
 #if    defined(SO_OOBINLINE)
        NetSigIO(net, 1);
        NetSetPgrp(net);
     }
 #endif /* defined(TN3270) */
 
 #if    defined(SO_OOBINLINE)
-    SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1);
+    if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1) {
+       perror("SetSockOpt");
+    }
 #endif /* defined(SO_OOBINLINE) */
 }
 
 #endif /* defined(SO_OOBINLINE) */
 }
 
@@ -445,9 +532,7 @@ int poll;           /* If 0, then block until something to do */
 #          endif /* defined(TN3270) */
                    /* I don't like this, does it ever happen? */
            printf("sleep(5) from telnet, after select\r\n");
 #          endif /* defined(TN3270) */
                    /* I don't like this, does it ever happen? */
            printf("sleep(5) from telnet, after select\r\n");
-#if    defined(unix)
            sleep(5);
            sleep(5);
-#endif /* defined(unix) */
        }
        return 0;
     }
        }
        return 0;
     }
@@ -534,7 +619,8 @@ int poll;           /* If 0, then block until something to do */
        if (netdata) {
            Dump('<', netiring.supply, c);
        }
        if (netdata) {
            Dump('<', netiring.supply, c);
        }
-       ring_supplied(&netiring, c);
+       if (c)
+           ring_supplied(&netiring, c);
        returnValue = 1;
     }
 
        returnValue = 1;
     }
 
@@ -543,24 +629,21 @@ int poll;         /* If 0, then block until something to do */
      */
     if (FD_ISSET(tin, &ibits)) {
        FD_CLR(tin, &ibits);
      */
     if (FD_ISSET(tin, &ibits)) {
        FD_CLR(tin, &ibits);
-       c = TerminalRead(tin, ttyiring.supply,
-                       ring_empty_consecutive(&ttyiring));
+       c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));
        if (c < 0 && errno == EWOULDBLOCK) {
            c = 0;
        } else {
        if (c < 0 && errno == EWOULDBLOCK) {
            c = 0;
        } else {
-#if    defined(unix)
            /* EOF detection for line mode!!!! */
            /* EOF detection for line mode!!!! */
-           if (c == 0 && MODE_LOCAL_CHARS(globalmode)) {
+           if ((c == 0) && MODE_LOCAL_CHARS(globalmode) && isatty(tin)) {
                        /* must be an EOF... */
                *ttyiring.supply = termEofChar;
                c = 1;
            }
                        /* must be an EOF... */
                *ttyiring.supply = termEofChar;
                c = 1;
            }
-#endif /* defined(unix) */
            if (c <= 0) {
                return -1;
            }
            if (c <= 0) {
                return -1;
            }
+           ring_supplied(&ttyiring, c);
        }
        }
-       ring_supplied(&ttyiring, c);
        returnValue = 1;                /* did something useful */
     }
 
        returnValue = 1;                /* did something useful */
     }