Fix gcc2 warnings.
authorDave A. Borman <dab@ucbvax.Berkeley.EDU>
Tue, 6 Apr 1993 07:48:27 +0000 (23:48 -0800)
committerDave A. Borman <dab@ucbvax.Berkeley.EDU>
Tue, 6 Apr 1993 07:48:27 +0000 (23:48 -0800)
Add ENV_HACK stuff to deal with telnet clients that
have the wrong definitions for ENV_VAR and ENV_VALUE.
Fix up the flow-control processing to work on systems
that don't use Linemode in the server.

SCCS-vsn: libexec/telnetd/Makefile 5.18
SCCS-vsn: libexec/telnetd/pathnames.h 5.6
SCCS-vsn: libexec/telnetd/termstat.c 5.13
SCCS-vsn: libexec/telnetd/utility.c 5.11
SCCS-vsn: libexec/telnetd/state.c 5.13
SCCS-vsn: libexec/telnetd/sys_term.c 5.20
SCCS-vsn: libexec/telnetd/ext.h 5.9

usr/src/libexec/telnetd/Makefile
usr/src/libexec/telnetd/ext.h
usr/src/libexec/telnetd/pathnames.h
usr/src/libexec/telnetd/state.c
usr/src/libexec/telnetd/sys_term.c
usr/src/libexec/telnetd/termstat.c
usr/src/libexec/telnetd/utility.c

index ed9d7db..1c2b34e 100644 (file)
@@ -1,7 +1,7 @@
-#      @(#)Makefile    5.17 (Berkeley) %G%
+#      @(#)Makefile    5.18 (Berkeley) %G%
 
 PROG=  telnetd
 
 PROG=  telnetd
-CFLAGS+=-DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS
+CFLAGS+=-DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DENV_HACK
 CFLAGS+=-DAUTHENTICATION -DENCRYPTION -I${.CURDIR}/../../lib
 SRCS=  authenc.c global.c slc.c state.c sys_term.c telnetd.c \
        termstat.c utility.c
 CFLAGS+=-DAUTHENTICATION -DENCRYPTION -I${.CURDIR}/../../lib
 SRCS=  authenc.c global.c slc.c state.c sys_term.c telnetd.c \
        termstat.c utility.c
index dadbf59..426505c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ext.h       5.8 (Berkeley) %G%
+ *     @(#)ext.h       5.9 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -93,6 +93,7 @@ extern void
        init_termbuf P((void)),
        interrupt P((void)),
        localstat P((void)),
        init_termbuf P((void)),
        interrupt P((void)),
        localstat P((void)),
+       flowstat P((void)),
        netclear P((void)),
        netflush P((void)),
 #ifdef DIAGNOSTICS
        netclear P((void)),
        netflush P((void)),
 #ifdef DIAGNOSTICS
index c248061..2a0467a 100644 (file)
@@ -4,19 +4,23 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pathnames.h 5.5 (Berkeley) %G%
+ *     @(#)pathnames.h 5.6 (Berkeley) %G%
  */
 
 #if BSD > 43
 
 # include <paths.h>
 
  */
 
 #if BSD > 43
 
 # include <paths.h>
 
-# define       _PATH_LOGIN     "/usr/bin/login"
+# ifndef _PATH_LOGIN
+#  define      _PATH_LOGIN     "/usr/bin/login"
+# endif
 
 #else
  
 # define       _PATH_TTY       "/dev/tty"
 
 #else
  
 # define       _PATH_TTY       "/dev/tty"
-# define       _PATH_LOGIN     "/bin/login"
+# ifndef _PATH_LOGIN
+#  define      _PATH_LOGIN     "/bin/login"
+# endif
 
 #endif
 
 
 #endif
 
index 1a34b4f..5314a4a 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)state.c    5.12 (Berkeley) %G%";
+static char sccsid[] = "@(#)state.c    5.13 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -26,7 +26,7 @@ int   not42 = 1;
  */
 unsigned char subbuffer[512], *subpointer= subbuffer, *subend= subbuffer;
 
  */
 unsigned char subbuffer[512], *subpointer= subbuffer, *subend= subbuffer;
 
-#define        SB_CLEAR()      subpointer = subbuffer;
+#define        SB_CLEAR()      subpointer = subbuffer
 #define        SB_TERM()       { subend = subpointer; SB_CLEAR(); }
 #define        SB_ACCUM(c)     if (subpointer < (subbuffer+sizeof subbuffer)) { \
                                *subpointer++ = (c); \
 #define        SB_TERM()       { subend = subpointer; SB_CLEAR(); }
 #define        SB_ACCUM(c)     if (subpointer < (subbuffer+sizeof subbuffer)) { \
                                *subpointer++ = (c); \
@@ -35,6 +35,11 @@ unsigned char subbuffer[512], *subpointer= subbuffer, *subend= subbuffer;
 #define        SB_EOF()        (subpointer >= subend)
 #define        SB_LEN()        (subend - subpointer)
 
 #define        SB_EOF()        (subpointer >= subend)
 #define        SB_LEN()        (subend - subpointer)
 
+#ifdef ENV_HACK
+unsigned char *subsave;
+#define SB_SAVE()      subsave = subpointer;
+#define        SB_RESTORE()    subpointer = subsave;
+#endif
 
 
 /*
 
 
 /*
@@ -619,7 +624,7 @@ willoption(option)
                        break;
 #endif
                case TELOPT_LFLOW:
                        break;
 #endif
                case TELOPT_LFLOW:
-                       func = localstat;
+                       func = flowstat;
                        break;
                }
            }
                        break;
                }
            }
@@ -1033,6 +1038,14 @@ dontoption(option)
 
 }  /* end of dontoption */
 
 
 }  /* end of dontoption */
 
+#ifdef ENV_HACK
+int env_var = -1;
+int env_value = -1;
+#else  /* ENV_HACK */
+# define env_var ENV_VAR
+# define env_value ENV_VALUE
+#endif /* ENV_HACK */
+
 /*
  * suboption()
  *
 /*
  * suboption()
  *
@@ -1221,9 +1234,119 @@ suboption()
        else if (c != TELQUAL_INFO)
                return;
 
        else if (c != TELQUAL_INFO)
                return;
 
+#ifdef ENV_HACK
+       /*
+        * We only want to do this if we haven't already decided
+        * whether or not the other side has its VALUE and VAR
+        * reversed.
+        */
+       if (env_var < 0) {
+               register int last = -1;         /* invalid value */
+               int empty = 0;
+               int got_var = 0, got_value = 0, got_uservar = 0;
+
+               /*
+                * The other side might have its VALUE and VAR values
+                * reversed.  To be interoperable, we need to determine
+                * which way it is.  If the first recognized character
+                * is a VAR or VALUE, then that will tell us what
+                * type of client it is.  If the fist recognized
+                * character is a USERVAR, then we continue scanning
+                * the suboption looking for two consecutive
+                * VAR or VALUE fields.  We should not get two
+                * consecutive VALUE fields, so finding two
+                * consecutive VALUE or VAR fields will tell us
+                * what the client is.
+                */
+               SB_SAVE();
+               while (!SB_EOF()) {
+                       c = SB_GET();
+                       switch(c) {
+                       case ENV_VAR:
+                               if (last < 0 || last == ENV_VAR
+                                   || (empty && (last == ENV_VALUE)))
+                                       goto env_var_ok;
+                               got_var++;
+                               last = ENV_VAR;
+                               break;
+                       case ENV_VALUE:
+                               if (last < 0 || last == ENV_VALUE
+                                   || (empty && (last == ENV_VAR)))
+                                       goto env_var_wrong;
+                               got_value++;
+                               last = ENV_VALUE;
+                               break;
+                       case ENV_USERVAR:
+                               /* count strings of USERVAR as one */
+                               if (last != ENV_USERVAR)
+                                       got_uservar++;
+                               if (empty) {
+                                       if (last == ENV_VALUE)
+                                               goto env_var_ok;
+                                       if (last == ENV_VAR)
+                                               goto env_var_wrong;
+                               }
+                               last = ENV_USERVAR;
+                               break;
+                       case ENV_ESC:
+                               if (!SB_EOF())
+                                       c = SB_GET();
+                               /* FALL THROUGH */
+                       default:
+                               empty = 0;
+                               continue;
+                       }
+                       empty = 1;
+               }
+               if (empty) {
+                       if (last == ENV_VALUE)
+                               goto env_var_ok;
+                       if (last == ENV_VAR)
+                               goto env_var_wrong;
+               }
+               /*
+                * Ok, the first thing was a USERVAR, and there
+                * are not two consecutive VAR or VALUE commands,
+                * and none of the VAR or VALUE commands are empty.
+                * If the client has sent us a well-formed option,
+                * then the number of VALUEs received should always
+                * be less than or equal to the number of VARs and
+                * USERVARs received.
+                *
+                * If we got exactly as many VALUEs as VARs and
+                * USERVARs, the client has the same definitions.
+                *
+                * If we get more VARs than the total number of VALUEs
+                * and USERVARs, the client has the same definitions.
+                *
+                * If we got exactly as many VARs as VALUEs and
+                * USERVARS, the client has reversed definitions.
+                *
+                * If we get more VALUEs than the total number of VARs
+                * and USERVARs, the client has reversed definitions
+                */
+               if ((got_uservar + got_var == got_value) ||
+                   (got_var > got_uservar + got_value)) {
+           env_var_ok:
+                       env_var = ENV_VAR;
+                       env_value = ENV_VALUE;
+               } else if ((got_uservar + got_value == got_var) ||
+                          (got_value > got_uservar + got_var)) {
+           env_var_wrong:
+                       env_var = ENV_VALUE;
+                       env_value = ENV_VAR;
+                       DIAG(TD_OPTIONS, {sprintf(nfrontp,
+                               "ENVIRON VALUE and VAR are reversed!\r\n");
+                               nfrontp += strlen(nfrontp);});
+
+               }
+       }
+       SB_RESTORE();
+#endif
+
        while (!SB_EOF()) {
                c = SB_GET();
        while (!SB_EOF()) {
                c = SB_GET();
-               if ((c == ENV_VAR) || (c == ENV_USERVAR))
+               if ((c == env_var) || (c == ENV_USERVAR))
                        break;
        }
 
                        break;
        }
 
@@ -1234,7 +1357,15 @@ suboption()
        valp = 0;
 
        while (!SB_EOF()) {
        valp = 0;
 
        while (!SB_EOF()) {
-               switch (c = SB_GET()) {
+               c = SB_GET();
+#ifdef ENV_HACK
+               if (c == env_var)
+                       c = ENV_VAR;
+               else if (c == env_value)
+                       c = ENV_VALUE;
+#endif
+               switch (c) {
+
                case ENV_VALUE:
                        *cp = '\0';
                        cp = valp = (char *)subpointer;
                case ENV_VALUE:
                        *cp = '\0';
                        cp = valp = (char *)subpointer;
index e2cfa10..d6bab00 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)sys_term.c 5.19 (Berkeley) %G%";
+static char sccsid[] = "@(#)sys_term.c 5.20 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -548,30 +548,6 @@ getpty()
  * tty_rspeed(val)     Set receive speed to val.
  */
 
  * tty_rspeed(val)     Set receive speed to val.
  */
 
-       int
-tty_flowmode()
-{
-#ifndef USE_TERMIO
-       return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0);
-#else
-       return((termbuf.c_iflag & IXON) ? 1 : 0);
-#endif
-}
-
-       int
-tty_restartany()
-{
-#ifndef USE_TERMIO
-# ifdef        DECCTQ
-       return((termbuf.lflags & DECCTQ) ? 0 : 1);
-# else
-       return(-1);
-# endif
-#else
-       return((termbuf.c_iflag & IXANY) ? 1 : 0);
-#endif
-}
-
 #ifdef convex
 static int linestate;
 #endif
 #ifdef convex
 static int linestate;
 #endif
@@ -625,6 +601,30 @@ tty_isecho()
 }
 #endif /* LINEMODE */
 
 }
 #endif /* LINEMODE */
 
+       int
+tty_flowmode()
+{
+#ifndef USE_TERMIO
+       return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0);
+#else
+       return((termbuf.c_iflag & IXON) ? 1 : 0);
+#endif
+}
+
+       int
+tty_restartany()
+{
+#ifndef USE_TERMIO
+# ifdef        DECCTQ
+       return((termbuf.lflags & DECCTQ) ? 0 : 1);
+# else
+       return(-1);
+# endif
+#else
+       return((termbuf.c_iflag & IXANY) ? 1 : 0);
+#endif
+}
+
        void
 tty_setecho(on)
        int on;
        void
 tty_setecho(on)
        int on;
index f5be6ad..c7b2844 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)termstat.c 5.12 (Berkeley) %G%";
+static char sccsid[] = "@(#)termstat.c 5.13 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -139,25 +139,7 @@ localstat()
        /*
         * Check for changes to flow control if client supports it.
         */
        /*
         * Check for changes to flow control if client supports it.
         */
-       if (his_state_is_will(TELOPT_LFLOW)) {
-               if (tty_flowmode() != flowmode) {
-                       flowmode = tty_flowmode();
-                       (void) sprintf(nfrontp, "%c%c%c%c%c%c",
-                                       IAC, SB, TELOPT_LFLOW,
-                                       flowmode ? LFLOW_ON : LFLOW_OFF,
-                                       IAC, SE);
-                       nfrontp += 6;
-               }
-               if (tty_restartany() != restartany) {
-                       restartany = tty_restartany();
-                       (void) sprintf(nfrontp, "%c%c%c%c%c%c",
-                                       IAC, SB, TELOPT_LFLOW,
-                                       restartany ? LFLOW_RESTART_ANY
-                                                  : LFLOW_RESTART_XON,
-                                       IAC, SE);
-                       nfrontp += 6;
-               }
-       }
+       flowstat();
 
        /*
         * Check linemode on/off state
 
        /*
         * Check linemode on/off state
@@ -342,6 +324,34 @@ done:
 }  /* end of localstat */
 #endif /* LINEMODE */
 
 }  /* end of localstat */
 #endif /* LINEMODE */
 
+/*
+ * flowstat
+ *
+ * Check for changes to flow control
+ */
+       void
+flowstat()
+{
+       if (his_state_is_will(TELOPT_LFLOW)) {
+               if (tty_flowmode() != flowmode) {
+                       flowmode = tty_flowmode();
+                       (void) sprintf(nfrontp, "%c%c%c%c%c%c",
+                                       IAC, SB, TELOPT_LFLOW,
+                                       flowmode ? LFLOW_ON : LFLOW_OFF,
+                                       IAC, SE);
+                       nfrontp += 6;
+               }
+               if (tty_restartany() != restartany) {
+                       restartany = tty_restartany();
+                       (void) sprintf(nfrontp, "%c%c%c%c%c%c",
+                                       IAC, SB, TELOPT_LFLOW,
+                                       restartany ? LFLOW_RESTART_ANY
+                                                  : LFLOW_RESTART_XON,
+                                       IAC, SE);
+                       nfrontp += 6;
+               }
+       }
+}
 
 /*
  * clientstat
 
 /*
  * clientstat
index a4d80e8..4c4df25 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)utility.c  5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)utility.c  5.11 (Berkeley) %G%";
 #endif /* not lint */
 
 #define PRINTOPTIONS
 #endif /* not lint */
 
 #define PRINTOPTIONS
@@ -795,7 +795,7 @@ printsub(direction, pointer, length)
                    case WONT:  cp = "WONT"; goto common2;
                    common2:
                        i++;
                    case WONT:  cp = "WONT"; goto common2;
                    common2:
                        i++;
-                       if (TELOPT_OK((int)pointer[i]))
+                       if (TELOPT_OK(pointer[i]))
                            sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i]));
                        else
                            sprintf(nfrontp, " %s %d", cp, pointer[i]);
                            sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i]));
                        else
                            sprintf(nfrontp, " %s %d", cp, pointer[i]);
@@ -881,8 +881,6 @@ printsub(direction, pointer, length)
                    for (i = 2; i < length; i++ ) {
                        switch (pointer[i]) {
                        case ENV_VAR:
                    for (i = 2; i < length; i++ ) {
                        switch (pointer[i]) {
                        case ENV_VAR:
-                           if (pointer[1] == TELQUAL_SEND)
-                               goto def_case;
                            sprintf(nfrontp, "\" VAR " + noquote);
                            nfrontp += strlen(nfrontp);
                            noquote = 2;
                            sprintf(nfrontp, "\" VAR " + noquote);
                            nfrontp += strlen(nfrontp);
                            noquote = 2;
@@ -901,8 +899,6 @@ printsub(direction, pointer, length)
                            break;
 
                        case ENV_USERVAR:
                            break;
 
                        case ENV_USERVAR:
-                           if (pointer[1] == TELQUAL_SEND)
-                               goto def_case;
                            sprintf(nfrontp, "\" USERVAR " + noquote);
                            nfrontp += strlen(nfrontp);
                            noquote = 2;
                            sprintf(nfrontp, "\" USERVAR " + noquote);
                            nfrontp += strlen(nfrontp);
                            noquote = 2;