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