Latest round of bug fixes. See the README file
authorPaul Borman <borman@ucbvax.Berkeley.EDU>
Sat, 15 Sep 1990 02:26:41 +0000 (18:26 -0800)
committerPaul Borman <borman@ucbvax.Berkeley.EDU>
Sat, 15 Sep 1990 02:26:41 +0000 (18:26 -0800)
in src/usr.bin/telnet/README for the details.

SCCS-vsn: libexec/telnetd/telnetd.c 5.47
SCCS-vsn: libexec/telnetd/defs.h 5.9
SCCS-vsn: libexec/telnetd/slc.c 5.5
SCCS-vsn: libexec/telnetd/state.c 5.8
SCCS-vsn: libexec/telnetd/sys_term.c 5.11
SCCS-vsn: libexec/telnetd/termstat.c 5.7

usr/src/libexec/telnetd/defs.h
usr/src/libexec/telnetd/slc.c
usr/src/libexec/telnetd/state.c
usr/src/libexec/telnetd/sys_term.c
usr/src/libexec/telnetd/telnetd.c
usr/src/libexec/telnetd/termstat.c

index ea760ca..d69c216 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)defs.h      5.8 (Berkeley) %G%
+ *     @(#)defs.h      5.9 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
 typedef unsigned char cc_t;
 #endif
 
 typedef unsigned char cc_t;
 #endif
 
+#ifndef _POSIX_VDISABLE
+# ifdef VDISABLE
+#  define _POSIX_VDISABLE VDISABLE
+# else
+#  define _POSIX_VDISABLE ((unsigned char)'\377')
+# endif
+#endif
+
+
 #ifdef CRAY
 #include <sys/fcntl.h>
 # ifdef        CRAY1
 #ifdef CRAY
 #include <sys/fcntl.h>
 # ifdef        CRAY1
index d1fde04..b23654a 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)slc.c      5.4 (Berkeley) %G%";
+static char sccsid[] = "@(#)slc.c      5.5 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -36,10 +36,10 @@ send_slc()
         * that are currently supported.
         */
        for (i = 1; i <= NSLC; i++) {
         * that are currently supported.
         */
        for (i = 1; i <= NSLC; i++) {
-               if ((slctab[i].current.flag & SLC_LEVELBITS) != SLC_NOSUPPORT) {
-                       add_slc((unsigned char)i, slctab[i].current.flag,
+               if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT)
+                       continue;
+               add_slc((unsigned char)i, slctab[i].current.flag,
                                                        slctab[i].current.val);
                                                        slctab[i].current.val);
-               }
        }
 
 }  /* end of send_slc */
        }
 
 }  /* end of send_slc */
@@ -54,8 +54,11 @@ default_slc()
        register int i;
 
        for (i = 1; i <= NSLC; i++) {
        register int i;
 
        for (i = 1; i <= NSLC; i++) {
-               slctab[i].current.flag = slctab[i].defset.flag;
                slctab[i].current.val = slctab[i].defset.val;
                slctab[i].current.val = slctab[i].defset.val;
+               if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE))
+                       slctab[i].current.flag = SLC_NOSUPPORT;
+               else
+                       slctab[i].current.flag = slctab[i].defset.flag;
                if (slctab[i].sptr) {
                        *(slctab[i].sptr) = slctab[i].defset.val;
                }
                if (slctab[i].sptr) {
                        *(slctab[i].sptr) = slctab[i].defset.val;
                }
@@ -198,9 +201,9 @@ process_slc(func, flag, val)
        if (func == 0) {
                if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {
                        default_slc();
        if (func == 0) {
                if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {
                        default_slc();
-               }
-               if (flag == SLC_DEFAULT || flag == SLC_VARIABLE) {
-                       send_slc();
+                       send_slc(1);
+               } else if (flag == SLC_VARIABLE) {
+                       send_slc(0);
                }
                return;
        }
                }
                return;
        }
@@ -220,6 +223,15 @@ process_slc(func, flag, val)
         */
        if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {
                return;
         */
        if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {
                return;
+       } else if (ack) {
+               /*
+                * If we get here, we got an ack, but the levels don't match.
+                * This shouldn't happen.  If it does, it is probably because
+                * we have sent two requests to set a variable without getting
+                * a response between them, and this is the first response.
+                * So, ignore it, and wait for the next response.
+                */
+               return;
        } else {
                change_slc(func, flag, val);
        }
        } else {
                change_slc(func, flag, val);
        }
@@ -247,7 +259,7 @@ change_slc(func, flag, val)
         */
        if (hislevel == SLC_NOSUPPORT) {
                slctab[func].current.flag = flag;
         */
        if (hislevel == SLC_NOSUPPORT) {
                slctab[func].current.flag = flag;
-               slctab[func].current.val = val;
+               slctab[func].current.val = (cc_t)_POSIX_VDISABLE;
                flag |= SLC_ACK;
                add_slc(func, flag, val);
                return;
                flag |= SLC_ACK;
                add_slc(func, flag, val);
                return;
@@ -330,7 +342,7 @@ change_slc(func, flag, val)
 
 }  /* end of change_slc */
 
 
 }  /* end of change_slc */
 
-#if    defined(USE_TERMIO) && defined(SYSV_TERMIO)
+#if    defined(USE_TERMIO) && (VEOF == VMIN)
 cc_t oldeofc = '\004';
 #endif
 
 cc_t oldeofc = '\004';
 #endif
 
@@ -347,7 +359,7 @@ check_slc()
        register int i;
 
        for (i = 1; i <= NSLC; i++) {
        register int i;
 
        for (i = 1; i <= NSLC; i++) {
-#if    defined(USE_TERMIO) && defined(SYSV_TERMIO)
+#if    defined(USE_TERMIO) && (VEOF == VMIN)
                /*
                 * In a perfect world this would be a neat little
                 * function.  But in this world, we should not notify
                /*
                 * In a perfect world this would be a neat little
                 * function.  But in this world, we should not notify
@@ -365,7 +377,10 @@ check_slc()
                if (slctab[i].sptr &&
                                (*(slctab[i].sptr) != slctab[i].current.val)) {
                        slctab[i].current.val = *(slctab[i].sptr);
                if (slctab[i].sptr &&
                                (*(slctab[i].sptr) != slctab[i].current.val)) {
                        slctab[i].current.val = *(slctab[i].sptr);
-                       slctab[i].current.flag = slctab[i].defset.flag;
+                       if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE)
+                               slctab[i].current.flag = SLC_NOSUPPORT;
+                       else
+                               slctab[i].current.flag = slctab[i].defset.flag;
                        add_slc((unsigned char)i, slctab[i].current.flag,
                                                slctab[i].current.val);
                }
                        add_slc((unsigned char)i, slctab[i].current.flag,
                                                slctab[i].current.val);
                }
index 98f2e73..5daabbb 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)state.c    5.7 (Berkeley) %G%";
+static char sccsid[] = "@(#)state.c    5.8 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -132,8 +132,7 @@ gotiac:                     switch (c) {
                                if (diagnostic & TD_OPTIONS)
                                        printoption("td: recv IAC", c);
 #endif /* DIAGNOSTICS */
                                if (diagnostic & TD_OPTIONS)
                                        printoption("td: recv IAC", c);
 #endif /* DIAGNOSTICS */
-                               (void) strcpy(nfrontp, "\r\n[Yes]\r\n");
-                               nfrontp += 9;
+                               recv_ayt();
                                break;
 
                        /*
                                break;
 
                        /*
@@ -149,7 +148,7 @@ gotiac:                     switch (c) {
                                init_termbuf();
 
                                if (slctab[SLC_AO].sptr &&
                                init_termbuf();
 
                                if (slctab[SLC_AO].sptr &&
-                                   *slctab[SLC_AO].sptr != (cc_t)-1) {
+                                   *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) {
                                    *pfrontp++ =
                                        (unsigned char)*slctab[SLC_AO].sptr;
                                }
                                    *pfrontp++ =
                                        (unsigned char)*slctab[SLC_AO].sptr;
                                }
@@ -184,7 +183,7 @@ gotiac:                     switch (c) {
                                        ch = *slctab[SLC_EC].sptr;
                                else
                                        ch = *slctab[SLC_EL].sptr;
                                        ch = *slctab[SLC_EC].sptr;
                                else
                                        ch = *slctab[SLC_EL].sptr;
-                               if (ch != (cc_t)-1)
+                               if (ch != (cc_t)(_POSIX_VDISABLE))
                                        *pfrontp++ = (unsigned char)ch;
                                break;
                            }
                                        *pfrontp++ = (unsigned char)ch;
                                break;
                            }
@@ -730,7 +729,7 @@ wontoption(option)
                                lmodetype = NO_LINEMODE;
                                clientstat(TELOPT_LINEMODE, WONT, 0);
                                send_will(TELOPT_SGA, 1);
                                lmodetype = NO_LINEMODE;
                                clientstat(TELOPT_LINEMODE, WONT, 0);
                                send_will(TELOPT_SGA, 1);
-/*@*/                          send_will(TELOPT_ECHO, 1);
+                               send_will(TELOPT_ECHO, 1);
                        }
 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
                default:
                        }
 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
                default:
@@ -764,6 +763,17 @@ send_will(option, init)
 #endif /* DIAGNOSTICS */
 }
 
 #endif /* DIAGNOSTICS */
 }
 
+#if    !defined(LINEMODE) || !defined(KLUDGELINEMODE)
+/*
+ * When we get a DONT SGA, we will try once to turn it
+ * back on.  If the other side responds DONT SGA, we
+ * leave it at that.  This is so that when we talk to
+ * clients that understand KLUDGELINEMODE but not LINEMODE,
+ * we'll keep them in char-at-a-time mode.
+ */
+int turn_on_sga = 0;
+#endif
+
 dooption(option)
        int option;
 {
 dooption(option)
        int option;
 {
@@ -791,14 +801,17 @@ dooption(option)
                switch (option) {
                case TELOPT_ECHO:
 #ifdef LINEMODE
                switch (option) {
                case TELOPT_ECHO:
 #ifdef LINEMODE
-                       if (lmodetype == NO_LINEMODE) {
+# ifdef        KLUDGELINEMODE
+                       if (lmodetype == NO_LINEMODE)
+# else
+                       if (his_state_is_wont(TELOPT_LINEMODE))
+# endif
 #endif
 #endif
+                       {
                                init_termbuf();
                                tty_setecho(1);
                                set_termbuf();
                                init_termbuf();
                                tty_setecho(1);
                                set_termbuf();
-#ifdef LINEMODE
                        }
                        }
-#endif
                        changeok++;
                        break;
 
                        changeok++;
                        break;
 
@@ -833,6 +846,8 @@ dooption(option)
                                if (linemode)
                                        break;
                        }
                                if (linemode)
                                        break;
                        }
+#else
+                       turn_on_sga = 0;
 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
                        changeok++;
                        break;
 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
                        changeok++;
                        break;
@@ -925,14 +940,17 @@ dontoption(option)
 
                case TELOPT_ECHO:       /* we should stop echoing */
 #ifdef LINEMODE
 
                case TELOPT_ECHO:       /* we should stop echoing */
 #ifdef LINEMODE
-                       if (lmodetype == NO_LINEMODE) {
+# ifdef        KLUDGELINEMODE
+                       if (lmodetype == NO_LINEMODE)
+# else
+                       if (his_state_is_wont(TELOPT_LINEMODE))
+# endif
 #endif
 #endif
+                       {
                                init_termbuf();
                                tty_setecho(0);
                                set_termbuf();
                                init_termbuf();
                                tty_setecho(0);
                                set_termbuf();
-#ifdef LINEMODE
                        }
                        }
-#endif
                        break;
 
                case TELOPT_SGA:
                        break;
 
                case TELOPT_SGA:
@@ -955,6 +973,15 @@ dontoption(option)
                                 * Gross.  Very Gross.
                                 */
                        }
                                 * Gross.  Very Gross.
                                 */
                        }
+                       break;
+#else
+                       set_my_want_state_wont(option);
+                       if (my_state_is_will(option))
+                               send_wont(option, 0);
+                       set_my_state_wont(option);
+                       if (turn_on_sga ^= 1)
+                               send_will(option);
+                       return;
 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
 
                default:
 #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
 
                default:
index 09cd993..cd32373 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)sys_term.c 5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)sys_term.c 5.11 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -62,19 +62,39 @@ struct termbuf {
        int state;
        int lflags;
 } termbuf, termbuf2;
        int state;
        int lflags;
 } termbuf, termbuf2;
+# define       cfsetospeed(tp, val)    (tp)->sg.sg_ospeed = (val)
+# define       cfsetispeed(tp, val)    (tp)->sg.sg_ispeed = (val)
 #else  /* USE_TERMIO */
 # ifdef        SYSV_TERMIO
 #      define termios termio
 # endif
 #else  /* USE_TERMIO */
 # ifdef        SYSV_TERMIO
 #      define termios termio
 # endif
-# ifndef TCSETA
+# ifndef       TCSANOW
 #  ifdef TCSETS
 #  ifdef TCSETS
-#   define TCSETA TCSETS
-#   define TCGETA TCGETS
+#   define     TCSANOW         TCSETS
+#   define     TCSADRAIN       TCSETSW
+#   define     tcgetattr(f, t) iotcl(f, TCGETS, t)
 #  else
 #  else
-#   define TCSETA TIOCSETAW
-#   define TCGETA TIOCGETA
+#   ifdef TCSETA
+#    define    TCSANOW         TCSETA
+#    define    TCSADRAIN       TCSETAW
+#    define    tcgetattr(f, t) ioctl(f, TCGETA, t)
+#   else
+#    define    TCSANOW         TIOCSETA
+#    define    TCSADRAIN       TIOCSETAW
+#    define    tcgetattr(f, t) iotcl(f, TIOCGETA, t)
+#   endif
 #  endif
 #  endif
-# endif /* 4.4BSD */
+#  define      tcsetattr(f, a, t)      ioctl(f, a, t)
+#  define      cfsetospeed(tp, val)    (tp)->c_cflag &= ~CBAUD; \
+                                       (tp)->c_cflag |= (val)
+#  ifdef CIBAUD
+#   define     cfsetispeed(tp, val)    (tp)->c_cflag &= ~CIBAUD; \
+                                       (tp)->c_cflag |= ((val)<<IBSHIFT)
+#  else
+#   define     cfsetispeed(tp, val)    (tp)->c_cflag &= ~CBAUD; \
+                                       (tp)->c_cflag |= (val)
+#  endif
+# endif /* TCSANOW */
 struct termios termbuf, termbuf2;      /* pty control structure */
 #endif /* USE_TERMIO */
 
 struct termios termbuf, termbuf2;      /* pty control structure */
 #endif /* USE_TERMIO */
 
@@ -99,7 +119,7 @@ init_termbuf()
        (void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);
 # endif
 #else
        (void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);
 # endif
 #else
-       (void) ioctl(pty, TCGETA, (char *)&termbuf);
+       (void) tcgetattr(pty, (char *)&termbuf);
 #endif
        termbuf2 = termbuf;
 }
 #endif
        termbuf2 = termbuf;
 }
@@ -123,7 +143,7 @@ set_termbuf()
         */
 #ifndef        USE_TERMIO
        if (bcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg)))
         */
 #ifndef        USE_TERMIO
        if (bcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg)))
-               (void) ioctl(pty, TIOCSETP, (char *)&termbuf.sg);
+               (void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg);
        if (bcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc)))
                (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc);
        if (bcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
        if (bcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc)))
                (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc);
        if (bcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
@@ -133,7 +153,7 @@ set_termbuf()
                (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);
 #else  /* USE_TERMIO */
        if (bcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
                (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);
 #else  /* USE_TERMIO */
        if (bcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
-               (void) ioctl(pty, TCSETA, (char *)&termbuf);
+               (void) tcsetattr(pty, TCSADRAIN, (char *)&termbuf);
 # if   defined(CRAY2) && defined(UNCIOS5)
        needtermstat = 1;
 # endif
 # if   defined(CRAY2) && defined(UNCIOS5)
        needtermstat = 1;
 # endif
@@ -280,8 +300,11 @@ cc_t **valpp;
                defval(0);
 #endif
        case SLC_AO:
                defval(0);
 #endif
        case SLC_AO:
-#ifdef VFLUSHO
-               setval(VFLUSHO, SLC_VARIABLE|SLC_FLUSHOUT);
+#if    !defined(VDISCARD) && defined(VFLUSHO)
+# define VDISCARD VFLUSHO
+#endif
+#ifdef VDISCARD
+               setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
 #else
                defval(0);
 #endif
 #else
                defval(0);
 #endif
@@ -299,10 +322,15 @@ cc_t **valpp;
        case SLC_FORW2:
                setval(VEOL2, SLC_VARIABLE);
 #endif
        case SLC_FORW2:
                setval(VEOL2, SLC_VARIABLE);
 #endif
+       case SLC_AYT:
+#ifdef VSTATUS
+               setval(VSTATUS, SLC_VARIABLE);
+#else
+               defval(0);
+#endif
 
        case SLC_BRK:
        case SLC_SYNCH:
 
        case SLC_BRK:
        case SLC_SYNCH:
-       case SLC_AYT:
        case SLC_EOR:
                defval(0);
 
        case SLC_EOR:
                defval(0);
 
@@ -330,6 +358,7 @@ getnpty()
 }
 #endif /* CRAY */
 
 }
 #endif /* CRAY */
 
+#ifndef        convex
 /*
  * getpty()
  *
 /*
  * getpty()
  *
@@ -338,7 +367,15 @@ getnpty()
  *
  * Returns the file descriptor of the opened pty.
  */
  *
  * Returns the file descriptor of the opened pty.
  */
+#ifndef        __GNUC__
 char *line = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 char *line = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+#else
+static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+char *line = Xline;
+#endif
+#ifdef CRAY
+char *myline = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+#endif /* CRAY */
 
 getpty()
 {
 
 getpty()
 {
@@ -370,13 +407,33 @@ getpty()
 #else  /* CRAY */
        register int npty;
        extern lowpty, highpty;
 #else  /* CRAY */
        register int npty;
        extern lowpty, highpty;
+       struct stat sb;
 
        for (npty = lowpty; npty <= highpty; npty++) {
 
        for (npty = lowpty; npty <= highpty; npty++) {
-               (void) sprintf(line, "/dev/pty/%03d", npty);
-               p = open(line, 2);
+               (void) sprintf(myline, "/dev/pty/%03d", npty);
+               p = open(myline, 2);
                if (p < 0)
                        continue;
                (void) sprintf(line, "/dev/ttyp%03d", npty);
                if (p < 0)
                        continue;
                (void) sprintf(line, "/dev/ttyp%03d", npty);
+               /*
+                * Here are some shenanigans to make sure that there
+                * are no listeners lurking on the line.
+                */
+               if(stat(line, &sb) < 0) {
+                       (void) close(p);
+                       continue;
+               }
+               if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
+                       chown(line, 0, 0);
+                       chmod(line, 0600);
+                       (void)close(p);
+                       p = open(myline, 2);
+                       if (p < 0)
+                               continue;
+               }
+               /*
+                * Now it should be safe...check for accessability.
+                */
                if (access(line, 6) == 0)
                        return(p);
                else {
                if (access(line, 6) == 0)
                        return(p);
                else {
@@ -387,6 +444,7 @@ getpty()
 #endif /* CRAY */
        return(-1);
 }
 #endif /* CRAY */
        return(-1);
 }
+#endif /* convex */
 
 #ifdef LINEMODE
 /*
 
 #ifdef LINEMODE
 /*
@@ -419,28 +477,43 @@ tty_flowmode()
 #endif
 }
 
 #endif
 }
 
+#ifdef convex
+static int linestate;
+#endif
+
 tty_linemode()
 {
 tty_linemode()
 {
+#ifndef convex
 #ifndef        USE_TERMIO
        return(termbuf.state & TS_EXTPROC);
 #else
        return(termbuf.c_lflag & EXTPROC);
 #endif
 #ifndef        USE_TERMIO
        return(termbuf.state & TS_EXTPROC);
 #else
        return(termbuf.c_lflag & EXTPROC);
 #endif
+#else
+       return(linestate);
+#endif
 }
 
 tty_setlinemode(on)
 int on;
 {
 #ifdef TIOCEXT
 }
 
 tty_setlinemode(on)
 int on;
 {
 #ifdef TIOCEXT
+# ifndef convex
+       set_termbuf();
+# else
+       linestate = on;
+# endif
        (void) ioctl(pty, TIOCEXT, (char *)&on);
        (void) ioctl(pty, TIOCEXT, (char *)&on);
+# ifndef convex
+       init_termbuf();
+# endif
 #else  /* !TIOCEXT */
 #else  /* !TIOCEXT */
-#ifdef EXTPROC
+# ifdef        EXTPROC
        if (on)
                termbuf.c_lflag |= EXTPROC;
        else
                termbuf.c_lflag &= ~EXTPROC;
        if (on)
                termbuf.c_lflag |= EXTPROC;
        else
                termbuf.c_lflag &= ~EXTPROC;
-#endif
-       set_termbuf();
+# endif
 #endif /* TIOCEXT */
 }
 
 #endif /* TIOCEXT */
 }
 
@@ -689,16 +762,7 @@ tty_tspeed(val)
 
        for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
                ;
 
        for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
                ;
-#ifndef        USE_TERMIO
-       termbuf.sg.sg_ospeed = tp->value;
-#else
-# ifdef        CBAUD
-       termbuf.c_cflag &= ~CBAUD;
-       termbuf.c_cflag |= tp->value;
-# else
-       termbuf.c_ospeed = tp->value;
-# endif
-#endif
+       cfsetospeed(&termbuf, tp->value);
 }
 
 tty_rspeed(val)
 }
 
 tty_rspeed(val)
@@ -707,16 +771,7 @@ tty_rspeed(val)
 
        for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
                ;
 
        for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
                ;
-#ifndef        USE_TERMIO
-       termbuf.sg.sg_ispeed = tp->value;
-#else
-# ifdef        CBAUD
-       termbuf.c_cflag &= ~CBAUD;
-       termbuf.c_cflag |= tp->value;
-# else
-       termbuf.c_ispeed = tp->value;
-# endif
-#endif
+       cfsetispeed(&termbuf, tp->value);
 }
 
 #if    defined(CRAY2) && defined(UNICOS5)
 }
 
 #if    defined(CRAY2) && defined(UNICOS5)
@@ -754,72 +809,195 @@ getptyslave()
 {
        register int t = -1;
 
 {
        register int t = -1;
 
-#ifndef        CRAY
+#if    !defined(CRAY) || !defined(NEWINIT)
+# ifdef        LINEMODE
        /*
        /*
-        * Disassociate self from control terminal and open ttyp side.
-        * Set important flags on ttyp and ptyp.
+        * Opening the slave side may cause initilization of the
+        * kernel tty structure.  We need remember whether or not
+        * linemode was turned on, so that we can re-set it if we
+        * need to.
         */
         */
+       int waslm = tty_linemode();
+# endif
+
+
+       /*
+        * Make sure that we don't have a controlling tty, and
+        * that we are the session (process group) leader.
+        */
+# ifdef        TIOCNOTTY
        t = open(_PATH_TTY, O_RDWR);
        if (t >= 0) {
                (void) ioctl(t, TIOCNOTTY, (char *)0);
                (void) close(t);
        }
        t = open(_PATH_TTY, O_RDWR);
        if (t >= 0) {
                (void) ioctl(t, TIOCNOTTY, (char *)0);
                (void) close(t);
        }
+# endif
 
 
-       t = open(line, O_RDWR);
-       if (t < 0)
-               fatalperror(net, line);
-       if (fchmod(t, 0))
-               fatalperror(net, line);
-#if BSD <= 43
-       (void) signal(SIGHUP, SIG_IGN);
-       vhangup();
-       (void) signal(SIGHUP, SIG_DFL);
-       t = open(line, O_RDWR);
+
+# ifdef        CRAY
+       /*
+        * Wait for our parent to get the utmp stuff to get done.
+        */
+       utmp_sig_wait();
+# endif
+
+       t = cleanopen(line);
        if (t < 0)
                fatalperror(net, line);
        if (t < 0)
                fatalperror(net, line);
-#endif
 
 
+       /*
+        * set up the tty modes as we like them to be.
+        */
        init_termbuf();
        init_termbuf();
-#ifndef        USE_TERMIO
+# ifdef        LINEMODE
+       if (waslm)
+               tty_setlinemode();
+# endif        LINEMODE
+
+       /*
+        * Settings for sgtty based systems
+        */
+# ifndef       USE_TERMIO
        termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
        termbuf.sg.sg_ospeed = termbuf.sg.sg_ispeed = B9600;
        termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
        termbuf.sg.sg_ospeed = termbuf.sg.sg_ispeed = B9600;
-#else
+# endif        /* USE_TERMIO */
+
+       /*
+        * Settings for UNICOS
+        */
+# ifdef        CRAY
+       termbuf.c_oflag = OPOST|ONLCR|TAB3;
+       termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
+       termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
+       termbuf.c_cflag = EXTB|HUPCL|CS8;
+# endif
+
+       /*
+        * Settings for all other termios/termio based
+        * systems, other than 4.4BSD.  In 4.4BSD the
+        * kernel does the initial terminal setup.
+        */
+# if defined(USE_TERMIO) && !defined(CRAY) && (BSD <= 43)
+#  ifndef      OXTABS
+#   define OXTABS      0
+#  endif
        termbuf.c_lflag |= ECHO;
        termbuf.c_lflag |= ECHO;
-#ifndef        OXTABS
-#define OXTABS 0
-#endif
        termbuf.c_oflag |= ONLCR|OXTABS;
        termbuf.c_iflag |= ICRNL;
        termbuf.c_iflag &= ~IXOFF;
        termbuf.c_oflag |= ONLCR|OXTABS;
        termbuf.c_iflag |= ICRNL;
        termbuf.c_iflag &= ~IXOFF;
-# ifdef        CBAUD
-       termbuf.c_cflag &= ~CBAUD;
-       termbuf.c_cflag |= B9600;
-# else /* CBAUD */
-       termbuf.c_ospeed = termbuf.c_ispeed = B9600;
-# endif        /* CBAUD */
-#endif
+       cfsetospeed(&termbuf, B9600);
+       cfsetispeed(&termbuf, B9600);
+# endif /* defined(USE_TERMIO) && !defined(CRAY) && (BSD <= 43) */
+
+       /*
+        * Set the tty modes, and make this our controlling tty.
+        */
        set_termbuf();
        set_termbuf();
-#else  /* CRAY */
+       if (login_tty(t) == -1)
+               fatalperror(net, "login_tty");
+#endif /* !defined(CRAY) || !defined(NEWINIT) */
+       if (net > 2)
+               (void) close(net);
+       if (pty > 2)
+               (void) close(pty);
+}
+
+#if    !defined(CRAY) || !defined(NEWINIT)
+#ifndef        O_NOCTTY
+#define        O_NOCTTY        0
+#endif
+/*
+ * Open the specified slave side of the pty,
+ * making sure that we have a clean tty.
+ */
+cleanopen(line)
+char *line;
+{
+       register int t;
+
+       /*
+        * Make sure that other people can't open the
+        * slave side of the connection.
+        */
        (void) chown(line, 0, 0);
        (void) chmod(line, 0600);
        (void) chown(line, 0, 0);
        (void) chmod(line, 0600);
-#endif /* CRAY */
+
+# if !defined(CRAY) && (BSD > 43)
+       (void) revoke(line);
+# endif
+       t = open(line, O_RDWR|O_NOCTTY);
+       if (t < 0)
+               return(-1);
+
+       /*
+        * Hangup anybody else using this ttyp, then reopen it for
+        * ourselves.
+        */
+# if !defined(CRAY) && (BSD <= 43)
+       (void) signal(SIGHUP, SIG_IGN);
+       vhangup();
+       (void) signal(SIGHUP, SIG_DFL);
+       t = open(line, O_RDWR|O_NOCTTY);
+       if (t < 0)
+               return(-1);
+# endif
+# if   defined(CRAY) && defined(TCVHUP)
+       {
+               register int i;
+               (void) signal(SIGHUP, SIG_IGN);
+               (void) ioctl(t, TCVHUP, (char *)0);
+               (void) signal(SIGHUP, SIG_DFL);
+               setpgrp();
+               i = open(line, O_RDWR);
+               if (i < 0)
+                       return(-1)
+               (void) close(t);
+               t = i;
+       }
+# endif        /* defined(CRAY) && defined(TCVHUP) */
        return(t);
 }
        return(t);
 }
+#endif /* !defined(CRAY) || !defined(NEWINIT) */
+
+#if BSD <= 43
+login_tty(t)
+int t;
+{
+# ifndef NO_SETSID
+       if (setsid() < 0)
+               fatalperror(net, "setsid()");
+# else
+#  ifndef convex
+       if (setpgrp(0,0) < 0)
+               fatalperror(net, "setpgrp()");
+#  endif
+# endif
+# ifdef        TIOCSCTTY
+       if (ioctl(t, TIOCSCTTY, (char *)0) < 0)
+               fatalperror(net, "ioctl(sctty)");
+# else
+       close(open(line, O_RDWR));
+# endif
+       (void) dup2(t, 0);
+       (void) dup2(t, 1);
+       (void) dup2(t, 2);
+       close(t);
+}
+#endif /* BSD <= 43 */
 
 #ifdef NEWINIT
 char *gen_id = "fe";
 #endif
 
 /*
 
 #ifdef NEWINIT
 char *gen_id = "fe";
 #endif
 
 /*
- * startslave(t, host)
+ * startslave(host)
  *
  *
- * Given a file descriptor (t) for a tty, and a hostname, do whatever
+ * Given a hostname, do whatever
  * is necessary to startup the login process on the slave side of the pty.
  */
 
 /* ARGSUSED */
  * is necessary to startup the login process on the slave side of the pty.
  */
 
 /* ARGSUSED */
-startslave(t, host)
-int t;
+startslave(host)
 char *host;
 {
        register int i;
 char *host;
 {
        register int i;
@@ -861,9 +1039,9 @@ char *host;
                }
                utmp_sig_notify(pid);
 # endif        /* CRAY */
                }
                utmp_sig_notify(pid);
 # endif        /* CRAY */
-               (void) close(t);
        } else {
        } else {
-               start_login(t, host);
+               getptyslave();
+               start_login(host);
                /*NOTREACHED*/
        }
 #else  /* NEWINIT */
                /*NOTREACHED*/
        }
 #else  /* NEWINIT */
@@ -968,14 +1146,13 @@ char *invalid[] = {
 #ifndef        NEWINIT
 
 /*
 #ifndef        NEWINIT
 
 /*
- * start_login(t, host)
+ * start_login(host)
  *
  * Assuming that we are now running as a child processes, this
  * function will turn us into the login process.
  */
 
  *
  * Assuming that we are now running as a child processes, this
  * function will turn us into the login process.
  */
 
-start_login(t, host)
-int t;
+start_login(host)
 char *host;
 {
        register char *cp;
 char *host;
 {
        register char *cp;
@@ -983,57 +1160,8 @@ char *host;
        char **addarg();
 #ifdef CRAY
        register char **cpp, **cpp2;
        char **addarg();
 #ifdef CRAY
        register char **cpp, **cpp2;
-       utmp_sig_wait();
-# ifndef TCVHUP
-       setpgrp();
-# endif
-       t = open(line, 2);      /* open ttyp */
-       if (t < 0)
-               fatalperror(net, line);
-# ifdef        TCVHUP
-       /*
-        * Hangup anybody else using this ttyp, then reopen it for
-        * ourselves.
-        */
-       (void) chown(line, 0, 0);
-       (void) chmod(line, 0600);
-       (void) signal(SIGHUP, SIG_IGN);
-       (void) ioctl(t, TCVHUP, (char *)0);
-       (void) signal(SIGHUP, SIG_DFL);
-       setpgrp();
-       i = open(line, 2);
-       if (i < 0)
-               fatalperror(net, line);
-       (void) close(t);
-       t = i;
-# endif        /* TCVHUP */
-       /*
-        * set ttyp modes as we like them to be
-        */
-       init_termbuf();
-       termbuf.c_oflag = OPOST|ONLCR|TAB3;
-       termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
-       termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
-       termbuf.c_cflag = EXTB|HUPCL|CS8;
-       set_termbuf();
 #endif /* CRAY */
 
 #endif /* CRAY */
 
-       /*
-        * set up standard paths before forking to login
-        */
-#if BSD > 43
-       if (login_tty(t) == -1)
-               fatalperror(net, "login_tty");
-#else
-       (void) dup2(t, 0);
-       (void) dup2(t, 1);
-       (void) dup2(t, 2);
-       (void) close(t);
-#endif
-       if (net > 2)
-               (void) close(net);
-       if (pty > 2)
-               (void) close(pty);
        /*
         * -h : pass on name of host.
         *              WARNING:  -h is accepted by login if and only if
        /*
         * -h : pass on name of host.
         *              WARNING:  -h is accepted by login if and only if
@@ -1118,11 +1246,12 @@ register char *val;
  * This is the routine to call when we are all through, to
  * clean up anything that needs to be cleaned up.
  */
  * This is the routine to call when we are all through, to
  * clean up anything that needs to be cleaned up.
  */
+void
 cleanup()
 {
 
 #ifndef        CRAY
 cleanup()
 {
 
 #ifndef        CRAY
-# if BSD > 43
+# if (BSD > 43) || defined(convex)
        char *p;
 
        p = line + sizeof("/dev/") - 1;
        char *p;
 
        p = line + sizeof("/dev/") - 1;
index b6a70d5..940a6bc 100644 (file)
@@ -12,10 +12,11 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)telnetd.c  5.46 (Berkeley) %G%";
+static char sccsid[] = "@(#)telnetd.c  5.47 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
+#include "pathnames.h"
 
 /*
  * I/O data buffers,
 
 /*
  * I/O data buffers,
@@ -24,9 +25,7 @@ static char sccsid[] = "@(#)telnetd.c 5.46 (Berkeley) %G%";
 char   ptyibuf[BUFSIZ], *ptyip = ptyibuf;
 char   ptyibuf2[BUFSIZ];
 
 char   ptyibuf[BUFSIZ], *ptyip = ptyibuf;
 char   ptyibuf2[BUFSIZ];
 
-#ifdef CRAY
 int    hostinfo = 1;                   /* do we print login banner? */
 int    hostinfo = 1;                   /* do we print login banner? */
-#endif
 
 #ifdef CRAY
 extern int      newmap; /* nonzero if \n maps to ^M^J */
 
 #ifdef CRAY
 extern int      newmap; /* nonzero if \n maps to ^M^J */
@@ -84,6 +83,10 @@ main(argc, argv)
 
 top:
        argc--, argv++;
 
 top:
        argc--, argv++;
+#ifdef convex
+       if (argc == 1 && !debug)
+               argc--;                 /* ignore the host/port name */
+#endif
 
        if (argc > 0 && strcmp(*argv, "-debug") == 0) {
                debug++;
 
        if (argc > 0 && strcmp(*argv, "-debug") == 0) {
                debug++;
@@ -97,12 +100,12 @@ top:
        }
 #endif /* LINEMODE */
 
        }
 #endif /* LINEMODE */
 
-#ifdef CRAY
        if (argc > 0 && !strcmp(*argv, "-h")) {
                hostinfo = 0;
                goto top;
        }
 
        if (argc > 0 && !strcmp(*argv, "-h")) {
                hostinfo = 0;
                goto top;
        }
 
+#ifdef CRAY
        if (argc > 0 && !strncmp(*argv, "-r", 2)) {
                char *strchr();
                char *c;
        if (argc > 0 && !strncmp(*argv, "-r", 2)) {
                char *strchr();
                char *c;
@@ -387,7 +390,7 @@ getterminaltype()
                     * We've hit the end.  If this is the same as
                     * the first name, just go with it.
                     */
                     * We've hit the end.  If this is the same as
                     * the first name, just go with it.
                     */
-                   if (strncmp(first, terminaltype, sizeof(first) == 0))
+                   if (strncmp(first, terminaltype, sizeof(first)) == 0)
                        break;
                    /*
                     * Get the terminal name one more time, so that
                        break;
                    /*
                     * Get the terminal name one more time, so that
@@ -395,7 +398,7 @@ getterminaltype()
                     * the start of the list.
                     */
                     _gettermname();
                     * the start of the list.
                     */
                     _gettermname();
-                   if (strncmp(first, terminaltype, sizeof(first) != 0))
+                   if (strncmp(first, terminaltype, sizeof(first)) != 0)
                        (void) strncpy(terminaltype, first, sizeof(first));
                    break;
                }
                        (void) strncpy(terminaltype, first, sizeof(first));
                    break;
                }
@@ -449,22 +452,28 @@ doit(who)
        char *host, *inet_ntoa();
        int t;
        struct hostent *hp;
        char *host, *inet_ntoa();
        int t;
        struct hostent *hp;
-#if BSD > 43
-       extern char *line;
 
 
-       if (openpty(&pty, &t, line, NULL, NULL) == -1)
-               fatal(net, "All network ports in use");
-       init_termbuf();
-#else
-       
        /*
         * Find an available pty to use.
         */
        /*
         * Find an available pty to use.
         */
+#ifndef        convex
        pty = getpty();
        if (pty < 0)
                fatal(net, "All network ports in use");
        pty = getpty();
        if (pty < 0)
                fatal(net, "All network ports in use");
+#else
+       for (;;) {
+               char *lp;
+               extern char *line, *getpty();
 
 
-       t = getptyslave();
+               if ((lp = getpty()) == NULL)
+                       fatal(net, "Out of ptys");
+
+               if ((pty = open(lp, 2)) >= 0) {
+                       strcpy(line,lp);
+                       line[5] = 't';
+                       break;
+               }
+       }
 #endif
 
        /* get name of connected client */
 #endif
 
        /* get name of connected client */
@@ -485,9 +494,13 @@ doit(who)
        /*
         * Start up the login process on the slave side of the terminal
         */
        /*
         * Start up the login process on the slave side of the terminal
         */
-       startslave(t, host);
+#ifndef        convex
+       startslave(host);
 
        telnet(net, pty);  /* begin server processing */
 
        telnet(net, pty);  /* begin server processing */
+#else
+       telnet(net, pty, host);
+#endif
        /*NOTREACHED*/
 }  /* end of doit */
 
        /*NOTREACHED*/
 }  /* end of doit */
 
@@ -498,8 +511,15 @@ doit(who)
  * Main loop.  Select from pty and network, and
  * hand data to telnet receiver finite state machine.
  */
  * Main loop.  Select from pty and network, and
  * hand data to telnet receiver finite state machine.
  */
+#ifndef        convex
 telnet(f, p)
 telnet(f, p)
+#else
+telnet(f, p, host)
+#endif
 int f, p;
 int f, p;
+#ifdef convex
+char *host;
+#endif
 {
        int on = 1;
        char hostname[MAXHOSTNAMELEN];
 {
        int on = 1;
        char hostname[MAXHOSTNAMELEN];
@@ -616,13 +636,10 @@ int f, p;
                send_will(TELOPT_ECHO, 1);
 
        /*
                send_will(TELOPT_ECHO, 1);
 
        /*
-        * Turn on packet mode, and default to line at at time mode.
+        * Turn on packet mode
         */
        (void) ioctl(p, TIOCPKT, (char *)&on);
         */
        (void) ioctl(p, TIOCPKT, (char *)&on);
-#ifdef LINEMODE
-       tty_setlinemode(1);
-
-# ifdef        KLUDGELINEMODE
+#ifdef KLUDGELINEMODE
        /*
         * Continuing line mode support.  If client does not support
         * real linemode, attempt to negotiate kludge linemode by sending
        /*
         * Continuing line mode support.  If client does not support
         * real linemode, attempt to negotiate kludge linemode by sending
@@ -630,8 +647,7 @@ int f, p;
         */
        if (lmodetype < REAL_LINEMODE)
                send_do(TELOPT_TM, 1);
         */
        if (lmodetype < REAL_LINEMODE)
                send_do(TELOPT_TM, 1);
-# endif        /* KLUDGELINEMODE */
-#endif /* LINEMODE */
+#endif /* KLUDGELINEMODE */
 
        /*
         * Call telrcv() once to pick up anything received during
 
        /*
         * Call telrcv() once to pick up anything received during
@@ -678,12 +694,19 @@ int f, p;
        termstat();
 #endif
 
        termstat();
 #endif
 
-#ifdef NO_SETSID
-       (void) setpgrp(0, 0);
-#else
-       (void) setsid();
+#ifdef  TIOCNOTTY
+       {
+               register int t;
+               t = open(_PATH_TTY, O_RDWR);
+               if (t >= 0) {
+                       (void) ioctl(t, TIOCNOTTY, (char *)0);
+                       (void) close(t);
+               }
+       }
 #endif
 #endif
+
 #if    defined(TIOCSCTTY) && defined(CRAY)
 #if    defined(TIOCSCTTY) && defined(CRAY)
+       (void) setsid();
        ioctl(p, TIOCSCTTY, 0);
 #endif
 
        ioctl(p, TIOCSCTTY, 0);
 #endif
 
@@ -695,6 +718,10 @@ int f, p;
         * other pty --> client data.
         */
 
         * other pty --> client data.
         */
 
+#if    !defined(CRAY) || !defined(NEWINIT)
+       if (getenv("USER"))
+               hostinfo = 0;
+#endif
        (void) gethostname(hostname, sizeof (hostname));
 
        if (getent(defent, "default") == 1) {
        (void) gethostname(hostname, sizeof (hostname));
 
        if (getent(defent, "default") == 1) {
@@ -709,16 +736,11 @@ int f, p;
                if (IM == 0)
                        IM = "";
        } else {
                if (IM == 0)
                        IM = "";
        } else {
-#ifdef CRAY
-               if (hostinfo == 0)
-                       IM = 0;
-               else
-#endif
-                       IM = DEFAULT_IM;
+               IM = DEFAULT_IM;
                HE = 0;
        }
        edithost(HE, hostname);
                HE = 0;
        }
        edithost(HE, hostname);
-       if (IM && *IM)
+       if (hostinfo && *IM)
                putf(IM, ptyibuf2);
 
        if (pcc)
                putf(IM, ptyibuf2);
 
        if (pcc)
@@ -740,6 +762,10 @@ int f, p;
        }
 #endif /* DIAGNOSTICS */
 
        }
 #endif /* DIAGNOSTICS */
 
+#ifdef convex
+       startslave(host);
+#endif
+
        for (;;) {
                fd_set ibits, obits, xbits;
                register int c;
        for (;;) {
                fd_set ibits, obits, xbits;
                register int c;
@@ -892,14 +918,12 @@ int f, p;
 #endif LINEMODE
                                if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
                                        netclear();     /* clear buffer back */
 #endif LINEMODE
                                if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
                                        netclear();     /* clear buffer back */
-#ifdef notdef
+#ifndef        NO_URGENT
                                        /*
                                        /*
-                                        * We really should have this in, but
-                                        * there are client telnets on some
+                                        * There are client telnets on some
                                         * operating systems get screwed up
                                         * royally if we send them urgent
                                         * operating systems get screwed up
                                         * royally if we send them urgent
-                                        * mode data.  So, for now, we'll not
-                                        * do this...
+                                        * mode data.
                                         */
                                        *nfrontp++ = IAC;
                                        *nfrontp++ = DM;
                                         */
                                        *nfrontp++ = IAC;
                                        *nfrontp++ = DM;
@@ -1026,14 +1050,30 @@ sendsusp()
 #endif /* SIGTSTP */
 }
 
 #endif /* SIGTSTP */
 }
 
+/*
+ * When we get an AYT, if ^T is enabled, use that.  Otherwise,
+ * just send back "[Yes]".
+ */
+recv_ayt()
+{
+#if    defined(SIGINFO) && defined(TCSIG)
+       if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {
+               (void) ioctl(pty, TCSIG, (char *)SIGINFO);
+               return;
+       }
+#endif
+       (void) strcpy(nfrontp, "\r\n[Yes]\r\n");
+       nfrontp += 9;
+}
+
 doeof()
 {
 doeof()
 {
-#if    defined(USE_TERMIO) && defined(SYSV_TERMIO)
+#if    defined(LINEMODE) && defined(USE_TERMIO) && (VEOF == VMIN)
        extern char oldeofc;
 #endif
        init_termbuf();
 
        extern char oldeofc;
 #endif
        init_termbuf();
 
-#if    defined(USE_TERMIO) && defined(SYSV_TERMIO)
+#if    defined(LINEMODE) && defined(USE_TERMIO) && (VEOF == VMIN)
        if (!tty_isediting()) {
                *pfrontp++ = oldeofc;
                return;
        if (!tty_isediting()) {
                *pfrontp++ = oldeofc;
                return;
index 962f966..e9add20 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)termstat.c 5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)termstat.c 5.7 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -168,10 +168,12 @@ localstat()
         * not send anything if it is unnecessary, so don't worry
         * about that here.
         */
         * not send anything if it is unnecessary, so don't worry
         * about that here.
         */
-       if (tty_isecho() && uselinemode)
-               send_wont(TELOPT_ECHO, 1);
-       else
-               send_will(TELOPT_ECHO, 1);
+       if (uselinemode) {
+               if (tty_isecho())
+                       send_wont(TELOPT_ECHO, 1);
+               else
+                       send_will(TELOPT_ECHO, 1);
+       }
 
        /*
         * If linemode is being turned off, send appropriate
 
        /*
         * If linemode is being turned off, send appropriate
@@ -248,7 +250,7 @@ localstat()
                goto done;
 # endif        /* KLUDGELINEMODE */
 
                goto done;
 # endif        /* KLUDGELINEMODE */
 
-       if (linemode) {
+       if (linemode && his_state_is_will(TELOPT_LINEMODE)) {
                /*
                 * If edit mode changed, send edit mode.
                 */
                /*
                 * If edit mode changed, send edit mode.
                 */