BSD 4_3_Net_2 release
[unix-history] / usr / src / libexec / telnetd / slc.c
index cc38852..6cdc286 100644 (file)
@@ -2,23 +2,37 @@
  * Copyright (c) 1989 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989 Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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[] = "@(#)slc.c      5.4 (Berkeley) 6/28/90";
+static char sccsid[] = "@(#)slc.c      5.7 (Berkeley) 3/1/91";
 #endif /* not lint */
 
 #include "telnetd.h"
 #endif /* not lint */
 
 #include "telnetd.h"
@@ -38,6 +52,7 @@ static unsigned char  slcbuf[NSLC*6]; /* buffer for slc negotiation */
  *
  * Write out the current special characters to the client.
  */
  *
  * Write out the current special characters to the client.
  */
+       void
 send_slc()
 {
        register int i;
 send_slc()
 {
        register int i;
@@ -48,10 +63,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 */
@@ -61,13 +76,17 @@ send_slc()
  *
  * Set pty special characters to all the defaults.
  */
  *
  * Set pty special characters to all the defaults.
  */
+       void
 default_slc()
 {
        register int i;
 
        for (i = 1; i <= NSLC; i++) {
 default_slc()
 {
        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;
                }
@@ -75,13 +94,14 @@ default_slc()
        slcchange = 1;
 
 }  /* end of default_slc */
        slcchange = 1;
 
 }  /* end of default_slc */
-#endif LINEMODE
+#endif /* LINEMODE */
 
 /*
  * get_slc_defaults
  *
  * Initialize the slc mapping table.
  */
 
 /*
  * get_slc_defaults
  *
  * Initialize the slc mapping table.
  */
+       void
 get_slc_defaults()
 {
        register int i;
 get_slc_defaults()
 {
        register int i;
@@ -103,15 +123,16 @@ get_slc_defaults()
  *
  * Add an slc triplet to the slc buffer.
  */
  *
  * Add an slc triplet to the slc buffer.
  */
+       void
 add_slc(func, flag, val)
 add_slc(func, flag, val)
-       register unsigned char func, flag;
-       cc_t val;
+       register char func, flag;
+       register cc_t val;
 {
 
 {
 
-       if ((*slcptr++ = func) == 0xff)
+       if ((*slcptr++ = (unsigned char)func) == 0xff)
                *slcptr++ = 0xff;
 
                *slcptr++ = 0xff;
 
-       if ((*slcptr++ = flag) == 0xff)
+       if ((*slcptr++ = (unsigned char)flag) == 0xff)
                *slcptr++ = 0xff;
 
        if ((*slcptr++ = (unsigned char)val) == 0xff)
                *slcptr++ = 0xff;
 
        if ((*slcptr++ = (unsigned char)val) == 0xff)
@@ -127,6 +148,7 @@ add_slc(func, flag, val)
  * The parameter getit is non-zero if it is necessary to grab a copy
  * of the terminal control structures.
  */
  * The parameter getit is non-zero if it is necessary to grab a copy
  * of the terminal control structures.
  */
+       void
 start_slc(getit)
        register int getit;
 {
 start_slc(getit)
        register int getit;
 {
@@ -134,7 +156,8 @@ start_slc(getit)
        slcchange = 0;
        if (getit)
                init_termbuf();
        slcchange = 0;
        if (getit)
                init_termbuf();
-       (void) sprintf(slcbuf, "%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_SLC);
+       (void) sprintf((char *)slcbuf, "%c%c%c%c",
+                                       IAC, SB, TELOPT_LINEMODE, LM_SLC);
        slcptr = slcbuf + 4;
 
 }  /* end of start_slc */
        slcptr = slcbuf + 4;
 
 }  /* end of start_slc */
@@ -144,8 +167,9 @@ start_slc(getit)
  *
  * Finish up the slc negotiation.  If something to send, then send it.
  */
  *
  * Finish up the slc negotiation.  If something to send, then send it.
  */
+       int
 end_slc(bufp)
 end_slc(bufp)
-register unsigned char **bufp;
+       register unsigned char **bufp;
 {
        register int len;
        void netflush();
 {
        register int len;
        void netflush();
@@ -165,7 +189,7 @@ register unsigned char **bufp;
         * request very soon.
         */
        if (def_slcbuf && (terminit() == 0)) {
         * request very soon.
         */
        if (def_slcbuf && (terminit() == 0)) {
-               return;
+               return(0);
        }
 
        if (slcptr > (slcbuf + 4)) {
        }
 
        if (slcptr > (slcbuf + 4)) {
@@ -173,13 +197,14 @@ register unsigned char **bufp;
                        *bufp = &slcbuf[4];
                        return(slcptr - slcbuf - 4);
                } else {
                        *bufp = &slcbuf[4];
                        return(slcptr - slcbuf - 4);
                } else {
-                       (void) sprintf(slcptr, "%c%c", IAC, SE);
+                       (void) sprintf((char *)slcptr, "%c%c", IAC, SE);
                        slcptr += 2;
                        len = slcptr - slcbuf;
                        writenet(slcbuf, len);
                        netflush();  /* force it out immediately */
                }
        }
                        slcptr += 2;
                        len = slcptr - slcbuf;
                        writenet(slcbuf, len);
                        netflush();  /* force it out immediately */
                }
        }
+       return (0);
 
 }  /* end of end_slc */
 
 
 }  /* end of end_slc */
 
@@ -188,9 +213,10 @@ register unsigned char **bufp;
  *
  * Figure out what to do about the client's slc
  */
  *
  * Figure out what to do about the client's slc
  */
+       void
 process_slc(func, flag, val)
        register unsigned char func, flag;
 process_slc(func, flag, val)
        register unsigned char func, flag;
-       cc_t val;
+       register cc_t val;
 {
        register int hislevel, mylevel, ack;
 
 {
        register int hislevel, mylevel, ack;
 
@@ -210,8 +236,8 @@ 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();
+               } else if (flag == SLC_VARIABLE) {
                        send_slc();
                }
                return;
                        send_slc();
                }
                return;
@@ -232,6 +258,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);
        }
@@ -244,9 +279,10 @@ process_slc(func, flag, val)
  * Process a request to change one of our special characters.
  * Compare client's request with what we are capable of supporting.
  */
  * Process a request to change one of our special characters.
  * Compare client's request with what we are capable of supporting.
  */
+       void
 change_slc(func, flag, val)
 change_slc(func, flag, val)
-       register unsigned char func, flag;
-       cc_t val;
+       register char func, flag;
+       register cc_t val;
 {
        register int hislevel, mylevel;
        
 {
        register int hislevel, mylevel;
        
@@ -259,7 +295,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;
@@ -342,7 +378,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
 
@@ -354,12 +390,13 @@ cc_t oldeofc = '\004';
  * likely to have changed.  If a local change occurs, kick the support level
  * and flags up to the defaults.
  */
  * likely to have changed.  If a local change occurs, kick the support level
  * and flags up to the defaults.
  */
+       void
 check_slc()
 {
        register int i;
 
        for (i = 1; i <= NSLC; i++) {
 check_slc()
 {
        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
@@ -377,7 +414,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);
                }
@@ -394,14 +434,14 @@ check_slc()
  *
  * ptr points to the beginning of the buffer, len is the length.
  */
  *
  * ptr points to the beginning of the buffer, len is the length.
  */
+       void
 do_opt_slc(ptr, len)
 do_opt_slc(ptr, len)
-register char *ptr;
-register int len;
+       register unsigned char *ptr;
+       register int len;
 {
        register unsigned char func, flag;
        cc_t val;
 {
        register unsigned char func, flag;
        cc_t val;
-       register char *end = (char *)(ptr + len);
-       char *malloc();
+       register unsigned char *end = ptr + len;
 
        if (terminit()) {  /* go ahead */
                while (ptr < end) {
 
        if (terminit()) {  /* go ahead */
                while (ptr < end) {
@@ -435,12 +475,13 @@ register int len;
  *
  * Do slc stuff that was deferred.
  */
  *
  * Do slc stuff that was deferred.
  */
+       void
 deferslc()
 {
        if (def_slcbuf) {
                start_slc(1);
                do_opt_slc(def_slcbuf, def_slclen);
 deferslc()
 {
        if (def_slcbuf) {
                start_slc(1);
                do_opt_slc(def_slcbuf, def_slclen);
-               end_slc(0);
+               (void) end_slc(0);
                free(def_slcbuf);
                def_slcbuf = (unsigned char *)0;
                def_slclen = 0;
                free(def_slcbuf);
                def_slcbuf = (unsigned char *)0;
                def_slclen = 0;