BSD 4_4_Lite2 release
[unix-history] / usr / src / libexec / telnetd / state.c
index dead4b0..4ee8bea 100644 (file)
@@ -2,11 +2,37 @@
  * Copyright (c) 1989, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
  * Copyright (c) 1989, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)state.c    8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)state.c    8.5 (Berkeley) 5/30/95";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -14,10 +40,10 @@ static char sccsid[] = "@(#)state.c 8.1 (Berkeley) %G%";
 #include <libtelnet/auth.h>
 #endif
 
 #include <libtelnet/auth.h>
 #endif
 
-char   doopt[] = { IAC, DO, '%', 'c', 0 };
-char   dont[] = { IAC, DONT, '%', 'c', 0 };
-char   will[] = { IAC, WILL, '%', 'c', 0 };
-char   wont[] = { IAC, WONT, '%', 'c', 0 };
+unsigned char  doopt[] = { IAC, DO, '%', 'c', 0 };
+unsigned char  dont[] = { IAC, DONT, '%', 'c', 0 };
+unsigned char  will[] = { IAC, WILL, '%', 'c', 0 };
+unsigned char  wont[] = { IAC, WONT, '%', 'c', 0 };
 int    not42 = 1;
 
 /*
 int    not42 = 1;
 
 /*
@@ -340,7 +366,7 @@ gotiac:                     switch (c) {
                char    xbuf2[BUFSIZ];
                register char *cp;
                int n = pfrontp - opfrontp, oc;
                char    xbuf2[BUFSIZ];
                register char *cp;
                int n = pfrontp - opfrontp, oc;
-               bcopy(opfrontp, xptyobuf, n);
+               memmove(xptyobuf, opfrontp, n);
                pfrontp = opfrontp;
                pfrontp += term_input(xptyobuf, pfrontp, n, BUFSIZ+NETSLOP,
                                        xbuf2, &oc, BUFSIZ);
                pfrontp = opfrontp;
                pfrontp += term_input(xptyobuf, pfrontp, n, BUFSIZ+NETSLOP,
                                        xbuf2, &oc, BUFSIZ);
@@ -362,7 +388,7 @@ gotiac:                     switch (c) {
  * All state defaults are negative, and resp defaults to 0.
  *
  * When initiating a request to change state to new_state:
  * All state defaults are negative, and resp defaults to 0.
  *
  * When initiating a request to change state to new_state:
- * 
+ *
  * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) {
  *     do nothing;
  * } else {
  * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) {
  *     do nothing;
  * } else {
@@ -426,7 +452,7 @@ send_do(option, init)
                        set_his_want_state_will(option);
                do_dont_resp[option]++;
        }
                        set_his_want_state_will(option);
                do_dont_resp[option]++;
        }
-       (void) sprintf(nfrontp, doopt, option);
+       (void) sprintf(nfrontp, (char *)doopt, option);
        nfrontp += sizeof (dont) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send do", option));
        nfrontp += sizeof (dont) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send do", option));
@@ -529,7 +555,8 @@ willoption(option)
                case TELOPT_NAWS:
                case TELOPT_TSPEED:
                case TELOPT_XDISPLOC:
                case TELOPT_NAWS:
                case TELOPT_TSPEED:
                case TELOPT_XDISPLOC:
-               case TELOPT_ENVIRON:
+               case TELOPT_NEW_ENVIRON:
+               case TELOPT_OLD_ENVIRON:
                        changeok++;
                        break;
 
                        changeok++;
                        break;
 
@@ -645,7 +672,7 @@ send_dont(option, init)
                set_his_want_state_wont(option);
                do_dont_resp[option]++;
        }
                set_his_want_state_wont(option);
                do_dont_resp[option]++;
        }
-       (void) sprintf(nfrontp, dont, option);
+       (void) sprintf(nfrontp, (char *)dont, option);
        nfrontp += sizeof (doopt) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send dont", option));
        nfrontp += sizeof (doopt) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send dont", option));
@@ -689,7 +716,6 @@ wontoption(option)
                         */
                        if (lmodetype != REAL_LINEMODE)
                                break;
                         */
                        if (lmodetype != REAL_LINEMODE)
                                break;
-                       lmodetype = KLUDGE_LINEMODE;
 # endif        /* KLUDGELINEMODE */
                        clientstat(TELOPT_LINEMODE, WONT, 0);
                        break;
 # endif        /* KLUDGELINEMODE */
                        clientstat(TELOPT_LINEMODE, WONT, 0);
                        break;
@@ -743,7 +769,11 @@ wontoption(option)
                        settimer(xdisplocsubopt);
                        break;
 
                        settimer(xdisplocsubopt);
                        break;
 
-               case TELOPT_ENVIRON:
+               case TELOPT_OLD_ENVIRON:
+                       settimer(oenvironsubopt);
+                       break;
+
+               case TELOPT_NEW_ENVIRON:
                        settimer(environsubopt);
                        break;
 
                        settimer(environsubopt);
                        break;
 
@@ -791,7 +821,7 @@ send_will(option, init)
                set_my_want_state_will(option);
                will_wont_resp[option]++;
        }
                set_my_want_state_will(option);
                will_wont_resp[option]++;
        }
-       (void) sprintf(nfrontp, will, option);
+       (void) sprintf(nfrontp, (char *)will, option);
        nfrontp += sizeof (doopt) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send will", option));
        nfrontp += sizeof (doopt) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send will", option));
@@ -920,7 +950,10 @@ dooption(option)
                case TELOPT_TSPEED:
                case TELOPT_LFLOW:
                case TELOPT_XDISPLOC:
                case TELOPT_TSPEED:
                case TELOPT_LFLOW:
                case TELOPT_XDISPLOC:
-               case TELOPT_ENVIRON:
+#ifdef TELOPT_ENVIRON
+               case TELOPT_NEW_ENVIRON:
+#endif
+               case TELOPT_OLD_ENVIRON:
                default:
                        break;
                }
                default:
                        break;
                }
@@ -947,7 +980,7 @@ send_wont(option, init)
                set_my_want_state_wont(option);
                will_wont_resp[option]++;
        }
                set_my_want_state_wont(option);
                will_wont_resp[option]++;
        }
-       (void) sprintf(nfrontp, wont, option);
+       (void) sprintf(nfrontp, (char *)wont, option);
        nfrontp += sizeof (wont) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send wont", option));
        nfrontp += sizeof (wont) - 2;
 
        DIAG(TD_OPTIONS, printoption("td: send wont", option));
@@ -1039,11 +1072,11 @@ dontoption(option)
 }  /* end of dontoption */
 
 #ifdef ENV_HACK
 }  /* end of dontoption */
 
 #ifdef ENV_HACK
-int env_var = -1;
-int env_value = -1;
+int env_ovar = -1;
+int env_ovalue = -1;
 #else  /* ENV_HACK */
 #else  /* ENV_HACK */
-# define env_var ENV_VAR
-# define env_value ENV_VALUE
+# define env_ovar OLD_ENV_VAR
+# define env_ovalue OLD_ENV_VALUE
 #endif /* ENV_HACK */
 
 /*
 #endif /* ENV_HACK */
 
 /*
@@ -1222,25 +1255,42 @@ suboption()
        break;
     }  /* end of case TELOPT_XDISPLOC */
 
        break;
     }  /* end of case TELOPT_XDISPLOC */
 
-    case TELOPT_ENVIRON: {
+#ifdef TELOPT_NEW_ENVIRON
+    case TELOPT_NEW_ENVIRON:
+#endif
+    case TELOPT_OLD_ENVIRON: {
        register int c;
        register char *cp, *varp, *valp;
 
        if (SB_EOF())
                return;
        c = SB_GET();
        register int c;
        register char *cp, *varp, *valp;
 
        if (SB_EOF())
                return;
        c = SB_GET();
-       if (c == TELQUAL_IS)
-               settimer(environsubopt);
-       else if (c != TELQUAL_INFO)
+       if (c == TELQUAL_IS) {
+               if (subchar == TELOPT_OLD_ENVIRON)
+                       settimer(oenvironsubopt);
+               else
+                       settimer(environsubopt);
+       } else if (c != TELQUAL_INFO) {
                return;
                return;
+       }
 
 
+#ifdef TELOPT_NEW_ENVIRON
+       if (subchar == TELOPT_NEW_ENVIRON) {
+           while (!SB_EOF()) {
+               c = SB_GET();
+               if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR))
+                       break;
+           }
+       } else
+#endif
+       {
 #ifdef ENV_HACK
 #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) {
+           /*
+            * 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_ovar < 0) {
                register int last = -1;         /* invalid value */
                int empty = 0;
                int got_var = 0, got_value = 0, got_uservar = 0;
                register int last = -1;         /* invalid value */
                int empty = 0;
                int got_var = 0, got_value = 0, got_uservar = 0;
@@ -1262,29 +1312,29 @@ suboption()
                while (!SB_EOF()) {
                        c = SB_GET();
                        switch(c) {
                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;
+                       case OLD_ENV_VAR:
+                               if (last < 0 || last == OLD_ENV_VAR
+                                   || (empty && (last == OLD_ENV_VALUE)))
+                                       goto env_ovar_ok;
                                got_var++;
                                got_var++;
-                               last = ENV_VAR;
+                               last = OLD_ENV_VAR;
                                break;
                                break;
-                       case ENV_VALUE:
-                               if (last < 0 || last == ENV_VALUE
-                                   || (empty && (last == ENV_VAR)))
-                                       goto env_var_wrong;
+                       case OLD_ENV_VALUE:
+                               if (last < 0 || last == OLD_ENV_VALUE
+                                   || (empty && (last == OLD_ENV_VAR)))
+                                       goto env_ovar_wrong;
                                got_value++;
                                got_value++;
-                               last = ENV_VALUE;
+                               last = OLD_ENV_VALUE;
                                break;
                        case ENV_USERVAR:
                                /* count strings of USERVAR as one */
                                if (last != ENV_USERVAR)
                                        got_uservar++;
                                if (empty) {
                                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;
+                                       if (last == OLD_ENV_VALUE)
+                                               goto env_ovar_ok;
+                                       if (last == OLD_ENV_VAR)
+                                               goto env_ovar_wrong;
                                }
                                last = ENV_USERVAR;
                                break;
                                }
                                last = ENV_USERVAR;
                                break;
@@ -1299,10 +1349,10 @@ suboption()
                        empty = 1;
                }
                if (empty) {
                        empty = 1;
                }
                if (empty) {
-                       if (last == ENV_VALUE)
-                               goto env_var_ok;
-                       if (last == ENV_VAR)
-                               goto env_var_wrong;
+                       if (last == OLD_ENV_VALUE)
+                               goto env_ovar_ok;
+                       if (last == OLD_ENV_VAR)
+                               goto env_ovar_wrong;
                }
                /*
                 * Ok, the first thing was a USERVAR, and there
                }
                /*
                 * Ok, the first thing was a USERVAR, and there
@@ -1320,26 +1370,27 @@ suboption()
                 * USERVARS, the client has reversed definitions.
                 */
                if (got_uservar + got_var == got_value) {
                 * USERVARS, the client has reversed definitions.
                 */
                if (got_uservar + got_var == got_value) {
-           env_var_ok:
-                       env_var = ENV_VAR;
-                       env_value = ENV_VALUE;
+           env_ovar_ok:
+                       env_ovar = OLD_ENV_VAR;
+                       env_ovalue = OLD_ENV_VALUE;
                } else if (got_uservar + got_value == got_var) {
                } else if (got_uservar + got_value == got_var) {
-           env_var_wrong:
-                       env_var = ENV_VALUE;
-                       env_value = ENV_VAR;
+           env_ovar_wrong:
+                       env_ovar = OLD_ENV_VALUE;
+                       env_ovalue = OLD_ENV_VAR;
                        DIAG(TD_OPTIONS, {sprintf(nfrontp,
                                "ENVIRON VALUE and VAR are reversed!\r\n");
                                nfrontp += strlen(nfrontp);});
 
                }
                        DIAG(TD_OPTIONS, {sprintf(nfrontp,
                                "ENVIRON VALUE and VAR are reversed!\r\n");
                                nfrontp += strlen(nfrontp);});
 
                }
-       }
-       SB_RESTORE();
+           }
+           SB_RESTORE();
 #endif
 
 #endif
 
-       while (!SB_EOF()) {
+           while (!SB_EOF()) {
                c = SB_GET();
                c = SB_GET();
-               if ((c == env_var) || (c == ENV_USERVAR))
+               if ((c == env_ovar) || (c == ENV_USERVAR))
                        break;
                        break;
+           }
        }
 
        if (SB_EOF())
        }
 
        if (SB_EOF())
@@ -1350,20 +1401,20 @@ suboption()
 
        while (!SB_EOF()) {
                c = SB_GET();
 
        while (!SB_EOF()) {
                c = SB_GET();
-#ifdef ENV_HACK
-               if (c == env_var)
-                       c = ENV_VAR;
-               else if (c == env_value)
-                       c = ENV_VALUE;
-#endif
+               if (subchar == TELOPT_OLD_ENVIRON) {
+                       if (c == env_ovar)
+                               c = NEW_ENV_VAR;
+                       else if (c == env_ovalue)
+                               c = NEW_ENV_VALUE;
+               }
                switch (c) {
 
                switch (c) {
 
-               case ENV_VALUE:
+               case NEW_ENV_VALUE:
                        *cp = '\0';
                        cp = valp = (char *)subpointer;
                        break;
 
                        *cp = '\0';
                        cp = valp = (char *)subpointer;
                        break;
 
-               case ENV_VAR:
+               case NEW_ENV_VAR:
                case ENV_USERVAR:
                        *cp = '\0';
                        if (valp)
                case ENV_USERVAR:
                        *cp = '\0';
                        if (valp)
@@ -1390,7 +1441,7 @@ suboption()
        else
                unsetenv(varp);
        break;
        else
                unsetenv(varp);
        break;
-    }  /* end of case TELOPT_ENVIRON */
+    }  /* end of case TELOPT_NEW_ENVIRON */
 #if    defined(AUTHENTICATION)
     case TELOPT_AUTHENTICATION:
        if (SB_EOF())
 #if    defined(AUTHENTICATION)
     case TELOPT_AUTHENTICATION:
        if (SB_EOF())
@@ -1468,8 +1519,8 @@ doclientstat()
        clientstat(TELOPT_LINEMODE, WILL, 0);
 }
 
        clientstat(TELOPT_LINEMODE, WILL, 0);
 }
 
-#define        ADD(c)   *ncp++ = c;
-#define        ADD_DATA(c) { *ncp++ = c; if (c == SE) *ncp++ = c; }
+#define        ADD(c)   *ncp++ = c
+#define        ADD_DATA(c) { *ncp++ = c; if (c == SE || c == IAC) *ncp++ = c; }
        void
 send_status()
 {
        void
 send_status()
 {
@@ -1494,18 +1545,14 @@ send_status()
         * WILL/DO, and the "want_state" will be WONT/DONT.  We
         * need to go by the latter.
         */
         * WILL/DO, and the "want_state" will be WONT/DONT.  We
         * need to go by the latter.
         */
-       for (i = 0; i < NTELOPTS; i++) {
+       for (i = 0; i < (unsigned char)NTELOPTS; i++) {
                if (my_want_state_is_will(i)) {
                        ADD(WILL);
                        ADD_DATA(i);
                if (my_want_state_is_will(i)) {
                        ADD(WILL);
                        ADD_DATA(i);
-                       if (i == IAC)
-                               ADD(IAC);
                }
                if (his_want_state_is_will(i)) {
                        ADD(DO);
                        ADD_DATA(i);
                }
                if (his_want_state_is_will(i)) {
                        ADD(DO);
                        ADD_DATA(i);
-                       if (i == IAC)
-                               ADD(IAC);
                }
        }
 
                }
        }
 
@@ -1520,15 +1567,14 @@ send_status()
                ADD(SE);
 
                if (restartany >= 0) {
                ADD(SE);
 
                if (restartany >= 0) {
-                       ADD(SB)
+                       ADD(SB);
                        ADD(TELOPT_LFLOW);
                        if (restartany) {
                                ADD(LFLOW_RESTART_ANY);
                        } else {
                                ADD(LFLOW_RESTART_XON);
                        }
                        ADD(TELOPT_LFLOW);
                        if (restartany) {
                                ADD(LFLOW_RESTART_ANY);
                        } else {
                                ADD(LFLOW_RESTART_XON);
                        }
-                       ADD(SE)
-                       ADD(SB);
+                       ADD(SE);
                }
        }
 
                }
        }
 
@@ -1541,8 +1587,6 @@ send_status()
                ADD(TELOPT_LINEMODE);
                ADD(LM_MODE);
                ADD_DATA(editmode);
                ADD(TELOPT_LINEMODE);
                ADD(LM_MODE);
                ADD_DATA(editmode);
-               if (editmode == IAC)
-                       ADD(IAC);
                ADD(SE);
 
                ADD(SB);
                ADD(SE);
 
                ADD(SB);