xref: /csrg-svn/usr.bin/telnet/terminal.c (revision 40245)
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*40245Sborman static char sccsid[] = "@(#)terminal.c	1.18 (Berkeley) 03/01/90";
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
3639529Sborman # ifndef VFLUSHO
3739529Sborman char termFlushChar;
3839529Sborman # endif
3939529Sborman # ifndef VLNEXT
4039529Sborman char termLiteralNextChar;
4139529Sborman # endif
4239529Sborman # ifndef VSUSP
4339529Sborman char termSuspChar;
4439529Sborman # endif
4539529Sborman # ifndef VWERASE
4639529Sborman char termWerasChar;
4739529Sborman # endif
4839529Sborman # ifndef VREPRINT
4939529Sborman char termRprntChar;
5039529Sborman # endif
5139529Sborman # ifndef VSTART
5239529Sborman char termStartChar;
5339529Sborman # endif
5439529Sborman # ifndef VSTOP
5539529Sborman char termStopChar;
5639529Sborman # endif
57*40245Sborman # ifndef VEOL
58*40245Sborman char termForw1Char;
59*40245Sborman # endif
60*40245Sborman # ifndef VEOL2
61*40245Sborman char termForw2Char;
62*40245Sborman # endif
63*40245Sborman #else
64*40245Sborman char termForw2Char;
6538690Sborman #endif
6632148Sminshall 
6732148Sminshall /*
6832148Sminshall  * initialize the terminal data structures.
6932148Sminshall  */
7032148Sminshall 
7132148Sminshall init_terminal()
7232148Sminshall {
7334848Sminshall     if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
7434848Sminshall 	exit(1);
7534848Sminshall     }
7634848Sminshall     if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
7734848Sminshall 	exit(1);
7834848Sminshall     }
7932148Sminshall     autoflush = TerminalAutoFlush();
8032148Sminshall }
8132148Sminshall 
8232148Sminshall 
8332148Sminshall /*
8432148Sminshall  *		Send as much data as possible to the terminal.
8532148Sminshall  *
8638690Sborman  *		Return value:
8738690Sborman  *			-1: No useful work done, data waiting to go out.
8838690Sborman  *			 0: No data was waiting, so nothing was done.
8938690Sborman  *			 1: All waiting data was written out.
9038690Sborman  *			 n: All data - n was written out.
9132148Sminshall  */
9232148Sminshall 
9332148Sminshall 
9432148Sminshall int
9532257Sminshall ttyflush(drop)
9632257Sminshall int drop;
9732148Sminshall {
9832667Sminshall     register int n, n0, n1;
9932148Sminshall 
10032667Sminshall     n0 = ring_full_count(&ttyoring);
10132667Sminshall     if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
10232257Sminshall 	if (drop) {
10332148Sminshall 	    TerminalFlushOutput();
10432148Sminshall 	    /* we leave 'n' alone! */
10532257Sminshall 	} else {
10633286Sminshall 	    n = TerminalWrite(ttyoring.consume, n);
10732148Sminshall 	}
10832148Sminshall     }
10932667Sminshall     if (n > 0) {
11038208Sminshall 	if (termdata && n) {
11138208Sminshall 	    Dump('>', ttyoring.consume, n);
11238208Sminshall 	}
11332667Sminshall 	/*
11432667Sminshall 	 * If we wrote everything, and the full count is
11532667Sminshall 	 * larger than what we wrote, then write the
11632667Sminshall 	 * rest of the buffer.
11732667Sminshall 	 */
11832667Sminshall 	if (n1 == n && n0 > n) {
11932667Sminshall 		n1 = n0 - n;
12032667Sminshall 		if (!drop)
12133286Sminshall 			n1 = TerminalWrite(ttyoring.bottom, n1);
12232667Sminshall 		n += n1;
12332667Sminshall 	}
12432528Sminshall 	ring_consumed(&ttyoring, n);
12532148Sminshall     }
12638690Sborman     if (n < 0)
12738690Sborman 	return -1;
12838690Sborman     if (n == n0) {
12938690Sborman 	if (n0)
13038690Sborman 	    return -1;
13138690Sborman 	return 0;
13238690Sborman     }
13338690Sborman     return n0 - n + 1;
13432148Sminshall }
13532148Sminshall 
13632148Sminshall 
13732148Sminshall /*
13832148Sminshall  * These routines decides on what the mode should be (based on the values
13932148Sminshall  * of various global variables).
14032148Sminshall  */
14132148Sminshall 
14232148Sminshall 
14332148Sminshall int
14432148Sminshall getconnmode()
14532148Sminshall {
14638690Sborman     extern int linemode;
14738690Sborman     int mode = 0;
14838690Sborman #ifdef	KLUDGELINEMODE
14938690Sborman     extern int kludgelinemode;
15038690Sborman #endif
15132148Sminshall 
15238690Sborman     if (In3270)
15338690Sborman 	return(MODE_FLOW);
15438690Sborman 
15538690Sborman     if (my_want_state_is_dont(TELOPT_ECHO))
15638690Sborman 	mode |= MODE_ECHO;
15738690Sborman 
15838690Sborman     if (localflow)
15938690Sborman 	mode |= MODE_FLOW;
16038690Sborman 
16139529Sborman     if (my_want_state_is_will(TELOPT_BINARY))
16239529Sborman 	mode |= MODE_INBIN;
16339529Sborman 
16439529Sborman     if (his_want_state_is_will(TELOPT_BINARY))
16539529Sborman 	mode |= MODE_OUTBIN;
16639529Sborman 
16738690Sborman #ifdef	KLUDGELINEMODE
16838690Sborman     if (kludgelinemode) {
16938690Sborman 	if (my_want_state_is_dont(TELOPT_SGA)) {
17038690Sborman 	    mode |= (MODE_TRAPSIG|MODE_EDIT);
17138690Sborman 	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
17238690Sborman 		mode &= ~MODE_ECHO;
17338690Sborman 	    }
17438690Sborman 	}
17538690Sborman 	return(mode);
17632148Sminshall     }
17738690Sborman #endif
17838690Sborman     if (my_want_state_is_will(TELOPT_LINEMODE))
17938690Sborman 	mode |= linemode;
18038690Sborman     return(mode);
18132148Sminshall }
18232148Sminshall 
18332148Sminshall void
18438690Sborman setconnmode(force)
18532148Sminshall {
18638690Sborman     TerminalNewMode(getconnmode()|(force?MODE_FORCE:0));
18732148Sminshall }
18832148Sminshall 
18932148Sminshall 
19032148Sminshall void
19132148Sminshall setcommandmode()
19232148Sminshall {
19338690Sborman     TerminalNewMode(-1);
19432148Sminshall }
195