xref: /csrg-svn/usr.bin/telnet/terminal.c (revision 68344)
133686Sbostic /*
262313Sbostic  * Copyright (c) 1988, 1990, 1993
362313Sbostic  *	The Regents of the University of California.  All rights reserved.
433686Sbostic  *
542770Sbostic  * %sccs.include.redist.c%
633686Sbostic  */
733686Sbostic 
833686Sbostic #ifndef lint
9*68344Sdab static char sccsid[] = "@(#)terminal.c	8.2 (Berkeley) 02/16/95";
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
init_terminal()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
ttyflush(drop)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);
117*68344Sdab 		if (n1 > 0)
118*68344Sdab 			n += n1;
11932667Sminshall 	}
12032528Sminshall 	ring_consumed(&ttyoring, n);
12132148Sminshall     }
12238690Sborman     if (n < 0)
12338690Sborman 	return -1;
12438690Sborman     if (n == n0) {
12538690Sborman 	if (n0)
12638690Sborman 	    return -1;
12738690Sborman 	return 0;
12838690Sborman     }
12938690Sborman     return n0 - n + 1;
13032148Sminshall }
13132148Sminshall 
13232148Sminshall 
13332148Sminshall /*
13432148Sminshall  * These routines decides on what the mode should be (based on the values
13532148Sminshall  * of various global variables).
13632148Sminshall  */
13732148Sminshall 
13832148Sminshall 
13946808Sdab     int
getconnmode()14032148Sminshall getconnmode()
14132148Sminshall {
14238690Sborman     extern int linemode;
14338690Sborman     int mode = 0;
14438690Sborman #ifdef	KLUDGELINEMODE
14538690Sborman     extern int kludgelinemode;
14638690Sborman #endif
14732148Sminshall 
14838690Sborman     if (In3270)
14938690Sborman 	return(MODE_FLOW);
15038690Sborman 
15138690Sborman     if (my_want_state_is_dont(TELOPT_ECHO))
15238690Sborman 	mode |= MODE_ECHO;
15338690Sborman 
15438690Sborman     if (localflow)
15538690Sborman 	mode |= MODE_FLOW;
15638690Sborman 
15739529Sborman     if (my_want_state_is_will(TELOPT_BINARY))
15839529Sborman 	mode |= MODE_INBIN;
15939529Sborman 
16039529Sborman     if (his_want_state_is_will(TELOPT_BINARY))
16139529Sborman 	mode |= MODE_OUTBIN;
16239529Sborman 
16338690Sborman #ifdef	KLUDGELINEMODE
16438690Sborman     if (kludgelinemode) {
16538690Sborman 	if (my_want_state_is_dont(TELOPT_SGA)) {
16638690Sborman 	    mode |= (MODE_TRAPSIG|MODE_EDIT);
16738690Sborman 	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
16838690Sborman 		mode &= ~MODE_ECHO;
16938690Sborman 	    }
17038690Sborman 	}
17138690Sborman 	return(mode);
17232148Sminshall     }
17338690Sborman #endif
17438690Sborman     if (my_want_state_is_will(TELOPT_LINEMODE))
17538690Sborman 	mode |= linemode;
17638690Sborman     return(mode);
17732148Sminshall }
17832148Sminshall 
17946808Sdab     void
setconnmode(force)18038690Sborman setconnmode(force)
18146808Sdab     int force;
18232148Sminshall {
18357213Sdab #ifdef	ENCRYPTION
18446808Sdab     static int enc_passwd = 0;
18560149Sdab #endif	/* ENCRYPTION */
18646808Sdab     register int newmode;
18746808Sdab 
18846808Sdab     newmode = getconnmode()|(force?MODE_FORCE:0);
18946808Sdab 
19046808Sdab     TerminalNewMode(newmode);
19146808Sdab 
19257213Sdab #ifdef  ENCRYPTION
19346808Sdab     if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
19446808Sdab 	if (my_want_state_is_will(TELOPT_ENCRYPT)
19546808Sdab 				&& (enc_passwd == 0) && !encrypt_output) {
19647609Sdab 	    encrypt_request_start(0, 0);
19746808Sdab 	    enc_passwd = 1;
19846808Sdab 	}
19946808Sdab     } else {
20046808Sdab 	if (enc_passwd) {
20146808Sdab 	    encrypt_request_end();
20246808Sdab 	    enc_passwd = 0;
20346808Sdab 	}
20446808Sdab     }
20560149Sdab #endif	/* ENCRYPTION */
20646808Sdab 
20732148Sminshall }
20832148Sminshall 
20932148Sminshall 
21046808Sdab     void
setcommandmode()21132148Sminshall setcommandmode()
21232148Sminshall {
21338690Sborman     TerminalNewMode(-1);
21432148Sminshall }
215