xref: /csrg-svn/usr.bin/telnet/terminal.c (revision 62313)
133686Sbostic /*
2*62313Sbostic  * Copyright (c) 1988, 1990, 1993
3*62313Sbostic  *	The Regents of the University of California.  All rights reserved.
433686Sbostic  *
542770Sbostic  * %sccs.include.redist.c%
633686Sbostic  */
733686Sbostic 
833686Sbostic #ifndef lint
9*62313Sbostic static char sccsid[] = "@(#)terminal.c	8.1 (Berkeley) 06/06/93";
1033686Sbostic #endif /* not lint */
1133686Sbostic 
1232148Sminshall #include <arpa/telnet.h>
1332381Sminshall #include <sys/types.h>
1432148Sminshall 
1532381Sminshall #include "ring.h"
1632381Sminshall 
1732148Sminshall #include "externs.h"
1832148Sminshall #include "types.h"
1932148Sminshall 
2046808Sdab Ring		ttyoring, ttyiring;
2146808Sdab unsigned char	ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
2232148Sminshall 
2338208Sminshall int termdata;			/* Debugging flag */
2438208Sminshall 
2538690Sborman #ifdef	USE_TERMIO
2645232Sborman # ifndef VDISCARD
2744360Sborman cc_t termFlushChar;
2839529Sborman # endif
2939529Sborman # ifndef VLNEXT
3044360Sborman cc_t termLiteralNextChar;
3139529Sborman # endif
3239529Sborman # ifndef VSUSP
3344360Sborman cc_t termSuspChar;
3439529Sborman # endif
3539529Sborman # ifndef VWERASE
3644360Sborman cc_t termWerasChar;
3739529Sborman # endif
3839529Sborman # ifndef VREPRINT
3944360Sborman cc_t termRprntChar;
4039529Sborman # endif
4139529Sborman # ifndef VSTART
4244360Sborman cc_t termStartChar;
4339529Sborman # endif
4439529Sborman # ifndef VSTOP
4544360Sborman cc_t termStopChar;
4639529Sborman # endif
4740245Sborman # ifndef VEOL
4844360Sborman cc_t termForw1Char;
4940245Sborman # endif
5040245Sborman # ifndef VEOL2
5144360Sborman cc_t termForw2Char;
5240245Sborman # endif
5345232Sborman # ifndef VSTATUS
5445232Sborman cc_t termAytChar;
5545232Sborman # endif
5640245Sborman #else
5744360Sborman cc_t termForw2Char;
5845232Sborman cc_t termAytChar;
5938690Sborman #endif
6032148Sminshall 
6132148Sminshall /*
6232148Sminshall  * initialize the terminal data structures.
6332148Sminshall  */
6432148Sminshall 
6546808Sdab     void
6632148Sminshall init_terminal()
6732148Sminshall {
6834848Sminshall     if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
6934848Sminshall 	exit(1);
7034848Sminshall     }
7134848Sminshall     if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
7234848Sminshall 	exit(1);
7334848Sminshall     }
7432148Sminshall     autoflush = TerminalAutoFlush();
7532148Sminshall }
7632148Sminshall 
7732148Sminshall 
7832148Sminshall /*
7932148Sminshall  *		Send as much data as possible to the terminal.
8032148Sminshall  *
8138690Sborman  *		Return value:
8238690Sborman  *			-1: No useful work done, data waiting to go out.
8338690Sborman  *			 0: No data was waiting, so nothing was done.
8438690Sborman  *			 1: All waiting data was written out.
8538690Sborman  *			 n: All data - n was written out.
8632148Sminshall  */
8732148Sminshall 
8832148Sminshall 
8946808Sdab     int
9032257Sminshall ttyflush(drop)
9146808Sdab     int drop;
9232148Sminshall {
9332667Sminshall     register int n, n0, n1;
9432148Sminshall 
9532667Sminshall     n0 = ring_full_count(&ttyoring);
9632667Sminshall     if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
9732257Sminshall 	if (drop) {
9832148Sminshall 	    TerminalFlushOutput();
9932148Sminshall 	    /* we leave 'n' alone! */
10032257Sminshall 	} else {
10133286Sminshall 	    n = TerminalWrite(ttyoring.consume, n);
10232148Sminshall 	}
10332148Sminshall     }
10432667Sminshall     if (n > 0) {
10538208Sminshall 	if (termdata && n) {
10638208Sminshall 	    Dump('>', ttyoring.consume, n);
10738208Sminshall 	}
10832667Sminshall 	/*
10932667Sminshall 	 * If we wrote everything, and the full count is
11032667Sminshall 	 * larger than what we wrote, then write the
11132667Sminshall 	 * rest of the buffer.
11232667Sminshall 	 */
11332667Sminshall 	if (n1 == n && n0 > n) {
11432667Sminshall 		n1 = n0 - n;
11532667Sminshall 		if (!drop)
11633286Sminshall 			n1 = TerminalWrite(ttyoring.bottom, n1);
11732667Sminshall 		n += n1;
11832667Sminshall 	}
11932528Sminshall 	ring_consumed(&ttyoring, n);
12032148Sminshall     }
12138690Sborman     if (n < 0)
12238690Sborman 	return -1;
12338690Sborman     if (n == n0) {
12438690Sborman 	if (n0)
12538690Sborman 	    return -1;
12638690Sborman 	return 0;
12738690Sborman     }
12838690Sborman     return n0 - n + 1;
12932148Sminshall }
13032148Sminshall 
13132148Sminshall 
13232148Sminshall /*
13332148Sminshall  * These routines decides on what the mode should be (based on the values
13432148Sminshall  * of various global variables).
13532148Sminshall  */
13632148Sminshall 
13732148Sminshall 
13846808Sdab     int
13932148Sminshall getconnmode()
14032148Sminshall {
14138690Sborman     extern int linemode;
14238690Sborman     int mode = 0;
14338690Sborman #ifdef	KLUDGELINEMODE
14438690Sborman     extern int kludgelinemode;
14538690Sborman #endif
14632148Sminshall 
14738690Sborman     if (In3270)
14838690Sborman 	return(MODE_FLOW);
14938690Sborman 
15038690Sborman     if (my_want_state_is_dont(TELOPT_ECHO))
15138690Sborman 	mode |= MODE_ECHO;
15238690Sborman 
15338690Sborman     if (localflow)
15438690Sborman 	mode |= MODE_FLOW;
15538690Sborman 
15639529Sborman     if (my_want_state_is_will(TELOPT_BINARY))
15739529Sborman 	mode |= MODE_INBIN;
15839529Sborman 
15939529Sborman     if (his_want_state_is_will(TELOPT_BINARY))
16039529Sborman 	mode |= MODE_OUTBIN;
16139529Sborman 
16238690Sborman #ifdef	KLUDGELINEMODE
16338690Sborman     if (kludgelinemode) {
16438690Sborman 	if (my_want_state_is_dont(TELOPT_SGA)) {
16538690Sborman 	    mode |= (MODE_TRAPSIG|MODE_EDIT);
16638690Sborman 	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
16738690Sborman 		mode &= ~MODE_ECHO;
16838690Sborman 	    }
16938690Sborman 	}
17038690Sborman 	return(mode);
17132148Sminshall     }
17238690Sborman #endif
17338690Sborman     if (my_want_state_is_will(TELOPT_LINEMODE))
17438690Sborman 	mode |= linemode;
17538690Sborman     return(mode);
17632148Sminshall }
17732148Sminshall 
17846808Sdab     void
17938690Sborman setconnmode(force)
18046808Sdab     int force;
18132148Sminshall {
18257213Sdab #ifdef	ENCRYPTION
18346808Sdab     static int enc_passwd = 0;
18460149Sdab #endif	/* ENCRYPTION */
18546808Sdab     register int newmode;
18646808Sdab 
18746808Sdab     newmode = getconnmode()|(force?MODE_FORCE:0);
18846808Sdab 
18946808Sdab     TerminalNewMode(newmode);
19046808Sdab 
19157213Sdab #ifdef  ENCRYPTION
19246808Sdab     if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
19346808Sdab 	if (my_want_state_is_will(TELOPT_ENCRYPT)
19446808Sdab 				&& (enc_passwd == 0) && !encrypt_output) {
19547609Sdab 	    encrypt_request_start(0, 0);
19646808Sdab 	    enc_passwd = 1;
19746808Sdab 	}
19846808Sdab     } else {
19946808Sdab 	if (enc_passwd) {
20046808Sdab 	    encrypt_request_end();
20146808Sdab 	    enc_passwd = 0;
20246808Sdab 	}
20346808Sdab     }
20460149Sdab #endif	/* ENCRYPTION */
20546808Sdab 
20632148Sminshall }
20732148Sminshall 
20832148Sminshall 
20946808Sdab     void
21032148Sminshall setcommandmode()
21132148Sminshall {
21238690Sborman     TerminalNewMode(-1);
21332148Sminshall }
214