xref: /csrg-svn/usr.bin/telnet/terminal.c (revision 39529)
133686Sbostic /*
233686Sbostic  * Copyright (c) 1988 Regents of the University of California.
333686Sbostic  * All rights reserved.
433686Sbostic  *
533686Sbostic  * Redistribution and use in source and binary forms are permitted
634898Sbostic  * provided that the above copyright notice and this paragraph are
734898Sbostic  * duplicated in all such forms and that any documentation,
834898Sbostic  * advertising materials, and other materials related to such
934898Sbostic  * distribution and use acknowledge that the software was developed
1034898Sbostic  * by the University of California, Berkeley.  The name of the
1134898Sbostic  * University may not be used to endorse or promote products derived
1234898Sbostic  * from this software without specific prior written permission.
1334898Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434898Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534898Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1633686Sbostic  */
1733686Sbostic 
1833686Sbostic #ifndef lint
19*39529Sborman static char sccsid[] = "@(#)terminal.c	1.17 (Berkeley) 11/14/89";
2033686Sbostic #endif /* not lint */
2133686Sbostic 
2232148Sminshall #include <arpa/telnet.h>
2332381Sminshall #include <sys/types.h>
2432148Sminshall 
2532381Sminshall #include "ring.h"
2632381Sminshall 
2732148Sminshall #include "externs.h"
2832148Sminshall #include "types.h"
2932148Sminshall 
3032531Sminshall Ring	ttyoring, ttyiring;
3132531Sminshall char	ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
3232148Sminshall 
3338208Sminshall int termdata;			/* Debugging flag */
3438208Sminshall 
3538690Sborman #ifdef	USE_TERMIO
36*39529Sborman # ifndef VFLUSHO
37*39529Sborman char termFlushChar;
38*39529Sborman # endif
39*39529Sborman # ifndef VLNEXT
40*39529Sborman char termLiteralNextChar;
41*39529Sborman # endif
42*39529Sborman # ifndef VSUSP
43*39529Sborman char termSuspChar;
44*39529Sborman # endif
45*39529Sborman # ifndef VWERASE
46*39529Sborman char termWerasChar;
47*39529Sborman # endif
48*39529Sborman # ifndef VREPRINT
49*39529Sborman char termRprntChar;
50*39529Sborman # endif
51*39529Sborman # ifndef VSTART
52*39529Sborman char termStartChar;
53*39529Sborman # endif
54*39529Sborman # ifndef VSTOP
55*39529Sborman char termStopChar;
56*39529Sborman # endif
5738690Sborman #endif
5832148Sminshall 
5932148Sminshall /*
6032148Sminshall  * initialize the terminal data structures.
6132148Sminshall  */
6232148Sminshall 
6332148Sminshall init_terminal()
6432148Sminshall {
6534848Sminshall     if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
6634848Sminshall 	exit(1);
6734848Sminshall     }
6834848Sminshall     if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
6934848Sminshall 	exit(1);
7034848Sminshall     }
7132148Sminshall     autoflush = TerminalAutoFlush();
7232148Sminshall }
7332148Sminshall 
7432148Sminshall 
7532148Sminshall /*
7632148Sminshall  *		Send as much data as possible to the terminal.
7732148Sminshall  *
7838690Sborman  *		Return value:
7938690Sborman  *			-1: No useful work done, data waiting to go out.
8038690Sborman  *			 0: No data was waiting, so nothing was done.
8138690Sborman  *			 1: All waiting data was written out.
8238690Sborman  *			 n: All data - n was written out.
8332148Sminshall  */
8432148Sminshall 
8532148Sminshall 
8632148Sminshall int
8732257Sminshall ttyflush(drop)
8832257Sminshall int drop;
8932148Sminshall {
9032667Sminshall     register int n, n0, n1;
9132148Sminshall 
9232667Sminshall     n0 = ring_full_count(&ttyoring);
9332667Sminshall     if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
9432257Sminshall 	if (drop) {
9532148Sminshall 	    TerminalFlushOutput();
9632148Sminshall 	    /* we leave 'n' alone! */
9732257Sminshall 	} else {
9833286Sminshall 	    n = TerminalWrite(ttyoring.consume, n);
9932148Sminshall 	}
10032148Sminshall     }
10132667Sminshall     if (n > 0) {
10238208Sminshall 	if (termdata && n) {
10338208Sminshall 	    Dump('>', ttyoring.consume, n);
10438208Sminshall 	}
10532667Sminshall 	/*
10632667Sminshall 	 * If we wrote everything, and the full count is
10732667Sminshall 	 * larger than what we wrote, then write the
10832667Sminshall 	 * rest of the buffer.
10932667Sminshall 	 */
11032667Sminshall 	if (n1 == n && n0 > n) {
11132667Sminshall 		n1 = n0 - n;
11232667Sminshall 		if (!drop)
11333286Sminshall 			n1 = TerminalWrite(ttyoring.bottom, n1);
11432667Sminshall 		n += n1;
11532667Sminshall 	}
11632528Sminshall 	ring_consumed(&ttyoring, n);
11732148Sminshall     }
11838690Sborman     if (n < 0)
11938690Sborman 	return -1;
12038690Sborman     if (n == n0) {
12138690Sborman 	if (n0)
12238690Sborman 	    return -1;
12338690Sborman 	return 0;
12438690Sborman     }
12538690Sborman     return n0 - n + 1;
12632148Sminshall }
12732148Sminshall 
12832148Sminshall 
12932148Sminshall /*
13032148Sminshall  * These routines decides on what the mode should be (based on the values
13132148Sminshall  * of various global variables).
13232148Sminshall  */
13332148Sminshall 
13432148Sminshall 
13532148Sminshall int
13632148Sminshall getconnmode()
13732148Sminshall {
13838690Sborman     extern int linemode;
13938690Sborman     int mode = 0;
14038690Sborman #ifdef	KLUDGELINEMODE
14138690Sborman     extern int kludgelinemode;
14238690Sborman #endif
14332148Sminshall 
14438690Sborman     if (In3270)
14538690Sborman 	return(MODE_FLOW);
14638690Sborman 
14738690Sborman     if (my_want_state_is_dont(TELOPT_ECHO))
14838690Sborman 	mode |= MODE_ECHO;
14938690Sborman 
15038690Sborman     if (localflow)
15138690Sborman 	mode |= MODE_FLOW;
15238690Sborman 
153*39529Sborman     if (my_want_state_is_will(TELOPT_BINARY))
154*39529Sborman 	mode |= MODE_INBIN;
155*39529Sborman 
156*39529Sborman     if (his_want_state_is_will(TELOPT_BINARY))
157*39529Sborman 	mode |= MODE_OUTBIN;
158*39529Sborman 
15938690Sborman #ifdef	KLUDGELINEMODE
16038690Sborman     if (kludgelinemode) {
16138690Sborman 	if (my_want_state_is_dont(TELOPT_SGA)) {
16238690Sborman 	    mode |= (MODE_TRAPSIG|MODE_EDIT);
16338690Sborman 	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
16438690Sborman 		mode &= ~MODE_ECHO;
16538690Sborman 	    }
16638690Sborman 	}
16738690Sborman 	return(mode);
16832148Sminshall     }
16938690Sborman #endif
17038690Sborman     if (my_want_state_is_will(TELOPT_LINEMODE))
17138690Sborman 	mode |= linemode;
17238690Sborman     return(mode);
17332148Sminshall }
17432148Sminshall 
17532148Sminshall void
17638690Sborman setconnmode(force)
17732148Sminshall {
17838690Sborman     TerminalNewMode(getconnmode()|(force?MODE_FORCE:0));
17932148Sminshall }
18032148Sminshall 
18132148Sminshall 
18232148Sminshall void
18332148Sminshall setcommandmode()
18432148Sminshall {
18538690Sborman     TerminalNewMode(-1);
18632148Sminshall }
187