133686Sbostic /* 233686Sbostic * Copyright (c) 1988 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 5*42770Sbostic * %sccs.include.redist.c% 633686Sbostic */ 733686Sbostic 833686Sbostic #ifndef lint 9*42770Sbostic static char sccsid[] = "@(#)terminal.c 1.19 (Berkeley) 06/01/90"; 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 2032531Sminshall Ring ttyoring, ttyiring; 2132531Sminshall char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ]; 2232148Sminshall 2338208Sminshall int termdata; /* Debugging flag */ 2438208Sminshall 2538690Sborman #ifdef USE_TERMIO 2639529Sborman # ifndef VFLUSHO 2739529Sborman char termFlushChar; 2839529Sborman # endif 2939529Sborman # ifndef VLNEXT 3039529Sborman char termLiteralNextChar; 3139529Sborman # endif 3239529Sborman # ifndef VSUSP 3339529Sborman char termSuspChar; 3439529Sborman # endif 3539529Sborman # ifndef VWERASE 3639529Sborman char termWerasChar; 3739529Sborman # endif 3839529Sborman # ifndef VREPRINT 3939529Sborman char termRprntChar; 4039529Sborman # endif 4139529Sborman # ifndef VSTART 4239529Sborman char termStartChar; 4339529Sborman # endif 4439529Sborman # ifndef VSTOP 4539529Sborman char termStopChar; 4639529Sborman # endif 4740245Sborman # ifndef VEOL 4840245Sborman char termForw1Char; 4940245Sborman # endif 5040245Sborman # ifndef VEOL2 5140245Sborman char termForw2Char; 5240245Sborman # endif 5340245Sborman #else 5440245Sborman char termForw2Char; 5538690Sborman #endif 5632148Sminshall 5732148Sminshall /* 5832148Sminshall * initialize the terminal data structures. 5932148Sminshall */ 6032148Sminshall 6132148Sminshall init_terminal() 6232148Sminshall { 6334848Sminshall if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) { 6434848Sminshall exit(1); 6534848Sminshall } 6634848Sminshall if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) { 6734848Sminshall exit(1); 6834848Sminshall } 6932148Sminshall autoflush = TerminalAutoFlush(); 7032148Sminshall } 7132148Sminshall 7232148Sminshall 7332148Sminshall /* 7432148Sminshall * Send as much data as possible to the terminal. 7532148Sminshall * 7638690Sborman * Return value: 7738690Sborman * -1: No useful work done, data waiting to go out. 7838690Sborman * 0: No data was waiting, so nothing was done. 7938690Sborman * 1: All waiting data was written out. 8038690Sborman * n: All data - n was written out. 8132148Sminshall */ 8232148Sminshall 8332148Sminshall 8432148Sminshall int 8532257Sminshall ttyflush(drop) 8632257Sminshall int drop; 8732148Sminshall { 8832667Sminshall register int n, n0, n1; 8932148Sminshall 9032667Sminshall n0 = ring_full_count(&ttyoring); 9132667Sminshall if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) { 9232257Sminshall if (drop) { 9332148Sminshall TerminalFlushOutput(); 9432148Sminshall /* we leave 'n' alone! */ 9532257Sminshall } else { 9633286Sminshall n = TerminalWrite(ttyoring.consume, n); 9732148Sminshall } 9832148Sminshall } 9932667Sminshall if (n > 0) { 10038208Sminshall if (termdata && n) { 10138208Sminshall Dump('>', ttyoring.consume, n); 10238208Sminshall } 10332667Sminshall /* 10432667Sminshall * If we wrote everything, and the full count is 10532667Sminshall * larger than what we wrote, then write the 10632667Sminshall * rest of the buffer. 10732667Sminshall */ 10832667Sminshall if (n1 == n && n0 > n) { 10932667Sminshall n1 = n0 - n; 11032667Sminshall if (!drop) 11133286Sminshall n1 = TerminalWrite(ttyoring.bottom, n1); 11232667Sminshall n += n1; 11332667Sminshall } 11432528Sminshall ring_consumed(&ttyoring, n); 11532148Sminshall } 11638690Sborman if (n < 0) 11738690Sborman return -1; 11838690Sborman if (n == n0) { 11938690Sborman if (n0) 12038690Sborman return -1; 12138690Sborman return 0; 12238690Sborman } 12338690Sborman return n0 - n + 1; 12432148Sminshall } 12532148Sminshall 12632148Sminshall 12732148Sminshall /* 12832148Sminshall * These routines decides on what the mode should be (based on the values 12932148Sminshall * of various global variables). 13032148Sminshall */ 13132148Sminshall 13232148Sminshall 13332148Sminshall int 13432148Sminshall getconnmode() 13532148Sminshall { 13638690Sborman extern int linemode; 13738690Sborman int mode = 0; 13838690Sborman #ifdef KLUDGELINEMODE 13938690Sborman extern int kludgelinemode; 14038690Sborman #endif 14132148Sminshall 14238690Sborman if (In3270) 14338690Sborman return(MODE_FLOW); 14438690Sborman 14538690Sborman if (my_want_state_is_dont(TELOPT_ECHO)) 14638690Sborman mode |= MODE_ECHO; 14738690Sborman 14838690Sborman if (localflow) 14938690Sborman mode |= MODE_FLOW; 15038690Sborman 15139529Sborman if (my_want_state_is_will(TELOPT_BINARY)) 15239529Sborman mode |= MODE_INBIN; 15339529Sborman 15439529Sborman if (his_want_state_is_will(TELOPT_BINARY)) 15539529Sborman mode |= MODE_OUTBIN; 15639529Sborman 15738690Sborman #ifdef KLUDGELINEMODE 15838690Sborman if (kludgelinemode) { 15938690Sborman if (my_want_state_is_dont(TELOPT_SGA)) { 16038690Sborman mode |= (MODE_TRAPSIG|MODE_EDIT); 16138690Sborman if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 16238690Sborman mode &= ~MODE_ECHO; 16338690Sborman } 16438690Sborman } 16538690Sborman return(mode); 16632148Sminshall } 16738690Sborman #endif 16838690Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) 16938690Sborman mode |= linemode; 17038690Sborman return(mode); 17132148Sminshall } 17232148Sminshall 17332148Sminshall void 17438690Sborman setconnmode(force) 17532148Sminshall { 17638690Sborman TerminalNewMode(getconnmode()|(force?MODE_FORCE:0)); 17732148Sminshall } 17832148Sminshall 17932148Sminshall 18032148Sminshall void 18132148Sminshall setcommandmode() 18232148Sminshall { 18338690Sborman TerminalNewMode(-1); 18432148Sminshall } 185