Add "nocrypt" target to create a subdirectory
[unix-history] / usr / src / libexec / telnetd / state.c
index e8ede0e..a4f8b23 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)state.c    5.11 (Berkeley) %G%";
+static char sccsid[] = "@(#)state.c    5.14 (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
 
 
 /*
 
 
 /*
@@ -63,10 +68,10 @@ telrcv()
                if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
                        break;
                c = *netip++ & 0377, ncc--;
                if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
                        break;
                c = *netip++ & 0377, ncc--;
-#if    defined(ENCRYPTION)
+#ifdef ENCRYPTION
                if (decrypt_input)
                        c = (*decrypt_input)(c);
                if (decrypt_input)
                        c = (*decrypt_input)(c);
-#endif
+#endif /* ENCRYPTION */
                switch (state) {
 
                case TS_CR:
                switch (state) {
 
                case TS_CR:
@@ -95,10 +100,10 @@ telrcv()
                         */
                        if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) {
                                int nc = *netip;
                         */
                        if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) {
                                int nc = *netip;
-#if    defined(ENCRYPTION)
+#ifdef ENCRYPTION
                                if (decrypt_input)
                                        nc = (*decrypt_input)(nc & 0xff);
                                if (decrypt_input)
                                        nc = (*decrypt_input)(nc & 0xff);
-#endif
+#endif /* ENCRYPTION */
 #ifdef LINEMODE
                                /*
                                 * If we are operating in linemode,
 #ifdef LINEMODE
                                /*
                                 * If we are operating in linemode,
@@ -111,10 +116,10 @@ telrcv()
                                } else
 #endif
                                {
                                } else
 #endif
                                {
-#if    defined(ENCRYPTION)
+#ifdef ENCRYPTION
                                        if (decrypt_input)
                                                (void)(*decrypt_input)(-1);
                                        if (decrypt_input)
                                                (void)(*decrypt_input)(-1);
-#endif
+#endif /* ENCRYPTION */
                                        state = TS_CR;
                                }
                        }
                                        state = TS_CR;
                                }
                        }
@@ -435,7 +440,7 @@ extern void doclientstat();
 #endif
 #ifdef ENCRYPTION
 extern void encrypt_send_support();
 #endif
 #ifdef ENCRYPTION
 extern void encrypt_send_support();
-#endif
+#endif /* ENCRYPTION */
 
        void
 willoption(option)
 
        void
 willoption(option)
@@ -553,7 +558,7 @@ willoption(option)
                        func = encrypt_send_support;
                        changeok++;
                        break;
                        func = encrypt_send_support;
                        changeok++;
                        break;
-#endif
+#endif /* ENCRYPTION */
 
                default:
                        break;
 
                default:
                        break;
@@ -617,7 +622,10 @@ willoption(option)
                case TELOPT_ENCRYPT:
                        func = encrypt_send_support;
                        break;
                case TELOPT_ENCRYPT:
                        func = encrypt_send_support;
                        break;
-#endif
+#endif /* ENCRYPTION */
+               case TELOPT_LFLOW:
+                       func = flowstat;
+                       break;
                }
            }
        }
                }
            }
        }
@@ -901,11 +909,11 @@ dooption(option)
                        /* NOT REACHED */
                        break;
 
                        /* NOT REACHED */
                        break;
 
-#if    defined(ENCRYPTION)
+#ifdef ENCRYPTION
                case TELOPT_ENCRYPT:
                        changeok++;
                        break;
                case TELOPT_ENCRYPT:
                        changeok++;
                        break;
-#endif
+#endif /* ENCRYPTION */
                case TELOPT_LINEMODE:
                case TELOPT_TTYPE:
                case TELOPT_NAWS:
                case TELOPT_LINEMODE:
                case TELOPT_TTYPE:
                case TELOPT_NAWS:
@@ -1030,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()
  *
@@ -1218,9 +1234,111 @@ 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 got exactly as many VARs as VALUEs and
+                * USERVARS, the client has reversed definitions.
+                */
+               if (got_uservar + got_var == got_value) {
+           env_var_ok:
+                       env_var = ENV_VAR;
+                       env_value = ENV_VALUE;
+               } else if (got_uservar + got_value == 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;
        }
 
@@ -1231,7 +1349,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;
@@ -1286,7 +1412,7 @@ suboption()
        }
        break;
 #endif
        }
        break;
 #endif
-#if    defined(ENCRYPTION)
+#ifdef ENCRYPTION
     case TELOPT_ENCRYPT:
        if (SB_EOF())
                break;
     case TELOPT_ENCRYPT:
        if (SB_EOF())
                break;
@@ -1328,7 +1454,7 @@ suboption()
                break;
        }
        break;
                break;
        }
        break;
-#endif
+#endif /* ENCRYPTION */
 
     default:
        break;
 
     default:
        break;