133686Sbostic /* 2*45232Sborman * Copyright (c) 1988, 1990 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 542770Sbostic * %sccs.include.redist.c% 633686Sbostic */ 733686Sbostic 833686Sbostic #ifndef lint 9*45232Sborman static char sccsid[] = "@(#)terminal.c 5.1 (Berkeley) 09/14/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 26*45232Sborman # ifndef VDISCARD 2744360Sborman cc_t termFlushChar; 2839529Sborman # endif 2939529Sborman # ifndef VLNEXT 3044360Sborman cc_t termLiteralNextChar; 3139529Sborman # endif 3239529Sborman # ifndef VSUSP 3344360Sborman cc_t termSuspChar; 3439529Sborman # endif 3539529Sborman # ifndef VWERASE 3644360Sborman cc_t termWerasChar; 3739529Sborman # endif 3839529Sborman # ifndef VREPRINT 3944360Sborman cc_t termRprntChar; 4039529Sborman # endif 4139529Sborman # ifndef VSTART 4244360Sborman cc_t termStartChar; 4339529Sborman # endif 4439529Sborman # ifndef VSTOP 4544360Sborman cc_t termStopChar; 4639529Sborman # endif 4740245Sborman # ifndef VEOL 4844360Sborman cc_t termForw1Char; 4940245Sborman # endif 5040245Sborman # ifndef VEOL2 5144360Sborman cc_t termForw2Char; 5240245Sborman # endif 53*45232Sborman # ifndef VSTATUS 54*45232Sborman cc_t termAytChar; 55*45232Sborman # endif 5640245Sborman #else 5744360Sborman cc_t termForw2Char; 58*45232Sborman cc_t termAytChar; 5938690Sborman #endif 6032148Sminshall 6132148Sminshall /* 6232148Sminshall * initialize the terminal data structures. 6332148Sminshall */ 6432148Sminshall 6532148Sminshall init_terminal() 6632148Sminshall { 6734848Sminshall if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) { 6834848Sminshall exit(1); 6934848Sminshall } 7034848Sminshall if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) { 7134848Sminshall exit(1); 7234848Sminshall } 7332148Sminshall autoflush = TerminalAutoFlush(); 7432148Sminshall } 7532148Sminshall 7632148Sminshall 7732148Sminshall /* 7832148Sminshall * Send as much data as possible to the terminal. 7932148Sminshall * 8038690Sborman * Return value: 8138690Sborman * -1: No useful work done, data waiting to go out. 8238690Sborman * 0: No data was waiting, so nothing was done. 8338690Sborman * 1: All waiting data was written out. 8438690Sborman * n: All data - n was written out. 8532148Sminshall */ 8632148Sminshall 8732148Sminshall 8832148Sminshall int 8932257Sminshall ttyflush(drop) 9032257Sminshall int drop; 9132148Sminshall { 9232667Sminshall register int n, n0, n1; 9332148Sminshall 9432667Sminshall n0 = ring_full_count(&ttyoring); 9532667Sminshall if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) { 9632257Sminshall if (drop) { 9732148Sminshall TerminalFlushOutput(); 9832148Sminshall /* we leave 'n' alone! */ 9932257Sminshall } else { 10033286Sminshall n = TerminalWrite(ttyoring.consume, n); 10132148Sminshall } 10232148Sminshall } 10332667Sminshall if (n > 0) { 10438208Sminshall if (termdata && n) { 10538208Sminshall Dump('>', ttyoring.consume, n); 10638208Sminshall } 10732667Sminshall /* 10832667Sminshall * If we wrote everything, and the full count is 10932667Sminshall * larger than what we wrote, then write the 11032667Sminshall * rest of the buffer. 11132667Sminshall */ 11232667Sminshall if (n1 == n && n0 > n) { 11332667Sminshall n1 = n0 - n; 11432667Sminshall if (!drop) 11533286Sminshall n1 = TerminalWrite(ttyoring.bottom, n1); 11632667Sminshall n += n1; 11732667Sminshall } 11832528Sminshall ring_consumed(&ttyoring, n); 11932148Sminshall } 12038690Sborman if (n < 0) 12138690Sborman return -1; 12238690Sborman if (n == n0) { 12338690Sborman if (n0) 12438690Sborman return -1; 12538690Sborman return 0; 12638690Sborman } 12738690Sborman return n0 - n + 1; 12832148Sminshall } 12932148Sminshall 13032148Sminshall 13132148Sminshall /* 13232148Sminshall * These routines decides on what the mode should be (based on the values 13332148Sminshall * of various global variables). 13432148Sminshall */ 13532148Sminshall 13632148Sminshall 13732148Sminshall int 13832148Sminshall getconnmode() 13932148Sminshall { 14038690Sborman extern int linemode; 14138690Sborman int mode = 0; 14238690Sborman #ifdef KLUDGELINEMODE 14338690Sborman extern int kludgelinemode; 14438690Sborman #endif 14532148Sminshall 14638690Sborman if (In3270) 14738690Sborman return(MODE_FLOW); 14838690Sborman 14938690Sborman if (my_want_state_is_dont(TELOPT_ECHO)) 15038690Sborman mode |= MODE_ECHO; 15138690Sborman 15238690Sborman if (localflow) 15338690Sborman mode |= MODE_FLOW; 15438690Sborman 15539529Sborman if (my_want_state_is_will(TELOPT_BINARY)) 15639529Sborman mode |= MODE_INBIN; 15739529Sborman 15839529Sborman if (his_want_state_is_will(TELOPT_BINARY)) 15939529Sborman mode |= MODE_OUTBIN; 16039529Sborman 16138690Sborman #ifdef KLUDGELINEMODE 16238690Sborman if (kludgelinemode) { 16338690Sborman if (my_want_state_is_dont(TELOPT_SGA)) { 16438690Sborman mode |= (MODE_TRAPSIG|MODE_EDIT); 16538690Sborman if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 16638690Sborman mode &= ~MODE_ECHO; 16738690Sborman } 16838690Sborman } 16938690Sborman return(mode); 17032148Sminshall } 17138690Sborman #endif 17238690Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) 17338690Sborman mode |= linemode; 17438690Sborman return(mode); 17532148Sminshall } 17632148Sminshall 17732148Sminshall void 17838690Sborman setconnmode(force) 17932148Sminshall { 18038690Sborman TerminalNewMode(getconnmode()|(force?MODE_FORCE:0)); 18132148Sminshall } 18232148Sminshall 18332148Sminshall 18432148Sminshall void 18532148Sminshall setcommandmode() 18632148Sminshall { 18738690Sborman TerminalNewMode(-1); 18832148Sminshall } 189