xref: /csrg-svn/usr.bin/telnet/terminal.c (revision 38690)
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*38690Sborman static char sccsid[] = "@(#)terminal.c	1.16 (Berkeley) 08/21/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 
35*38690Sborman #ifdef	USE_TERMIO
3632148Sminshall char
3732148Sminshall     termFlushChar,
3832148Sminshall     termLiteralNextChar,
39*38690Sborman     termSuspChar,
40*38690Sborman     termWerasChar,
41*38690Sborman     termRprntChar,
42*38690Sborman     termStartChar,
43*38690Sborman     termStopChar;
44*38690Sborman #endif
4532148Sminshall 
4632148Sminshall /*
4732148Sminshall  * initialize the terminal data structures.
4832148Sminshall  */
4932148Sminshall 
5032148Sminshall init_terminal()
5132148Sminshall {
5234848Sminshall     if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
5334848Sminshall 	exit(1);
5434848Sminshall     }
5534848Sminshall     if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
5634848Sminshall 	exit(1);
5734848Sminshall     }
5832148Sminshall     autoflush = TerminalAutoFlush();
5932148Sminshall }
6032148Sminshall 
6132148Sminshall 
6232148Sminshall /*
6332148Sminshall  *		Send as much data as possible to the terminal.
6432148Sminshall  *
65*38690Sborman  *		Return value:
66*38690Sborman  *			-1: No useful work done, data waiting to go out.
67*38690Sborman  *			 0: No data was waiting, so nothing was done.
68*38690Sborman  *			 1: All waiting data was written out.
69*38690Sborman  *			 n: All data - n was written out.
7032148Sminshall  */
7132148Sminshall 
7232148Sminshall 
7332148Sminshall int
7432257Sminshall ttyflush(drop)
7532257Sminshall int drop;
7632148Sminshall {
7732667Sminshall     register int n, n0, n1;
7832148Sminshall 
7932667Sminshall     n0 = ring_full_count(&ttyoring);
8032667Sminshall     if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
8132257Sminshall 	if (drop) {
8232148Sminshall 	    TerminalFlushOutput();
8332148Sminshall 	    /* we leave 'n' alone! */
8432257Sminshall 	} else {
8533286Sminshall 	    n = TerminalWrite(ttyoring.consume, n);
8632148Sminshall 	}
8732148Sminshall     }
8832667Sminshall     if (n > 0) {
8938208Sminshall 	if (termdata && n) {
9038208Sminshall 	    Dump('>', ttyoring.consume, n);
9138208Sminshall 	}
9232667Sminshall 	/*
9332667Sminshall 	 * If we wrote everything, and the full count is
9432667Sminshall 	 * larger than what we wrote, then write the
9532667Sminshall 	 * rest of the buffer.
9632667Sminshall 	 */
9732667Sminshall 	if (n1 == n && n0 > n) {
9832667Sminshall 		n1 = n0 - n;
9932667Sminshall 		if (!drop)
10033286Sminshall 			n1 = TerminalWrite(ttyoring.bottom, n1);
10132667Sminshall 		n += n1;
10232667Sminshall 	}
10332528Sminshall 	ring_consumed(&ttyoring, n);
10432148Sminshall     }
105*38690Sborman     if (n < 0)
106*38690Sborman 	return -1;
107*38690Sborman     if (n == n0) {
108*38690Sborman 	if (n0)
109*38690Sborman 	    return -1;
110*38690Sborman 	return 0;
111*38690Sborman     }
112*38690Sborman     return n0 - n + 1;
11332148Sminshall }
11432148Sminshall 
11532148Sminshall 
11632148Sminshall /*
11732148Sminshall  * These routines decides on what the mode should be (based on the values
11832148Sminshall  * of various global variables).
11932148Sminshall  */
12032148Sminshall 
12132148Sminshall 
12232148Sminshall int
12332148Sminshall getconnmode()
12432148Sminshall {
125*38690Sborman     extern int linemode;
126*38690Sborman     int mode = 0;
127*38690Sborman #ifdef	KLUDGELINEMODE
128*38690Sborman     extern int kludgelinemode;
129*38690Sborman #endif
13032148Sminshall 
131*38690Sborman     if (In3270)
132*38690Sborman 	return(MODE_FLOW);
133*38690Sborman 
134*38690Sborman     if (my_want_state_is_dont(TELOPT_ECHO))
135*38690Sborman 	mode |= MODE_ECHO;
136*38690Sborman 
137*38690Sborman     if (localflow)
138*38690Sborman 	mode |= MODE_FLOW;
139*38690Sborman 
140*38690Sborman #ifdef	KLUDGELINEMODE
141*38690Sborman     if (kludgelinemode) {
142*38690Sborman 	if (my_want_state_is_dont(TELOPT_SGA)) {
143*38690Sborman 	    mode |= (MODE_TRAPSIG|MODE_EDIT);
144*38690Sborman 	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
145*38690Sborman 		mode &= ~MODE_ECHO;
146*38690Sborman 	    }
147*38690Sborman 	}
148*38690Sborman 	return(mode);
14932148Sminshall     }
150*38690Sborman #endif
151*38690Sborman     if (my_want_state_is_will(TELOPT_LINEMODE))
152*38690Sborman 	mode |= linemode;
153*38690Sborman     return(mode);
15432148Sminshall }
15532148Sminshall 
15632148Sminshall void
157*38690Sborman setconnmode(force)
15832148Sminshall {
159*38690Sborman     TerminalNewMode(getconnmode()|(force?MODE_FORCE:0));
16032148Sminshall }
16132148Sminshall 
16232148Sminshall 
16332148Sminshall void
16432148Sminshall setcommandmode()
16532148Sminshall {
166*38690Sborman     TerminalNewMode(-1);
16732148Sminshall }
168