133686Sbostic /* 2*62313Sbostic * Copyright (c) 1988, 1990, 1993 3*62313Sbostic * The Regents of the University of California. All rights reserved. 433686Sbostic * 542770Sbostic * %sccs.include.redist.c% 633686Sbostic */ 733686Sbostic 833686Sbostic #ifndef lint 9*62313Sbostic static char sccsid[] = "@(#)terminal.c 8.1 (Berkeley) 06/06/93"; 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 2046808Sdab Ring ttyoring, ttyiring; 2146808Sdab unsigned char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ]; 2232148Sminshall 2338208Sminshall int termdata; /* Debugging flag */ 2438208Sminshall 2538690Sborman #ifdef USE_TERMIO 2645232Sborman # 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 5345232Sborman # ifndef VSTATUS 5445232Sborman cc_t termAytChar; 5545232Sborman # endif 5640245Sborman #else 5744360Sborman cc_t termForw2Char; 5845232Sborman cc_t termAytChar; 5938690Sborman #endif 6032148Sminshall 6132148Sminshall /* 6232148Sminshall * initialize the terminal data structures. 6332148Sminshall */ 6432148Sminshall 6546808Sdab void 6632148Sminshall init_terminal() 6732148Sminshall { 6834848Sminshall if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) { 6934848Sminshall exit(1); 7034848Sminshall } 7134848Sminshall if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) { 7234848Sminshall exit(1); 7334848Sminshall } 7432148Sminshall autoflush = TerminalAutoFlush(); 7532148Sminshall } 7632148Sminshall 7732148Sminshall 7832148Sminshall /* 7932148Sminshall * Send as much data as possible to the terminal. 8032148Sminshall * 8138690Sborman * Return value: 8238690Sborman * -1: No useful work done, data waiting to go out. 8338690Sborman * 0: No data was waiting, so nothing was done. 8438690Sborman * 1: All waiting data was written out. 8538690Sborman * n: All data - n was written out. 8632148Sminshall */ 8732148Sminshall 8832148Sminshall 8946808Sdab int 9032257Sminshall ttyflush(drop) 9146808Sdab int drop; 9232148Sminshall { 9332667Sminshall register int n, n0, n1; 9432148Sminshall 9532667Sminshall n0 = ring_full_count(&ttyoring); 9632667Sminshall if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) { 9732257Sminshall if (drop) { 9832148Sminshall TerminalFlushOutput(); 9932148Sminshall /* we leave 'n' alone! */ 10032257Sminshall } else { 10133286Sminshall n = TerminalWrite(ttyoring.consume, n); 10232148Sminshall } 10332148Sminshall } 10432667Sminshall if (n > 0) { 10538208Sminshall if (termdata && n) { 10638208Sminshall Dump('>', ttyoring.consume, n); 10738208Sminshall } 10832667Sminshall /* 10932667Sminshall * If we wrote everything, and the full count is 11032667Sminshall * larger than what we wrote, then write the 11132667Sminshall * rest of the buffer. 11232667Sminshall */ 11332667Sminshall if (n1 == n && n0 > n) { 11432667Sminshall n1 = n0 - n; 11532667Sminshall if (!drop) 11633286Sminshall n1 = TerminalWrite(ttyoring.bottom, n1); 11732667Sminshall n += n1; 11832667Sminshall } 11932528Sminshall ring_consumed(&ttyoring, n); 12032148Sminshall } 12138690Sborman if (n < 0) 12238690Sborman return -1; 12338690Sborman if (n == n0) { 12438690Sborman if (n0) 12538690Sborman return -1; 12638690Sborman return 0; 12738690Sborman } 12838690Sborman return n0 - n + 1; 12932148Sminshall } 13032148Sminshall 13132148Sminshall 13232148Sminshall /* 13332148Sminshall * These routines decides on what the mode should be (based on the values 13432148Sminshall * of various global variables). 13532148Sminshall */ 13632148Sminshall 13732148Sminshall 13846808Sdab int 13932148Sminshall getconnmode() 14032148Sminshall { 14138690Sborman extern int linemode; 14238690Sborman int mode = 0; 14338690Sborman #ifdef KLUDGELINEMODE 14438690Sborman extern int kludgelinemode; 14538690Sborman #endif 14632148Sminshall 14738690Sborman if (In3270) 14838690Sborman return(MODE_FLOW); 14938690Sborman 15038690Sborman if (my_want_state_is_dont(TELOPT_ECHO)) 15138690Sborman mode |= MODE_ECHO; 15238690Sborman 15338690Sborman if (localflow) 15438690Sborman mode |= MODE_FLOW; 15538690Sborman 15639529Sborman if (my_want_state_is_will(TELOPT_BINARY)) 15739529Sborman mode |= MODE_INBIN; 15839529Sborman 15939529Sborman if (his_want_state_is_will(TELOPT_BINARY)) 16039529Sborman mode |= MODE_OUTBIN; 16139529Sborman 16238690Sborman #ifdef KLUDGELINEMODE 16338690Sborman if (kludgelinemode) { 16438690Sborman if (my_want_state_is_dont(TELOPT_SGA)) { 16538690Sborman mode |= (MODE_TRAPSIG|MODE_EDIT); 16638690Sborman if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 16738690Sborman mode &= ~MODE_ECHO; 16838690Sborman } 16938690Sborman } 17038690Sborman return(mode); 17132148Sminshall } 17238690Sborman #endif 17338690Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) 17438690Sborman mode |= linemode; 17538690Sborman return(mode); 17632148Sminshall } 17732148Sminshall 17846808Sdab void 17938690Sborman setconnmode(force) 18046808Sdab int force; 18132148Sminshall { 18257213Sdab #ifdef ENCRYPTION 18346808Sdab static int enc_passwd = 0; 18460149Sdab #endif /* ENCRYPTION */ 18546808Sdab register int newmode; 18646808Sdab 18746808Sdab newmode = getconnmode()|(force?MODE_FORCE:0); 18846808Sdab 18946808Sdab TerminalNewMode(newmode); 19046808Sdab 19157213Sdab #ifdef ENCRYPTION 19246808Sdab if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) { 19346808Sdab if (my_want_state_is_will(TELOPT_ENCRYPT) 19446808Sdab && (enc_passwd == 0) && !encrypt_output) { 19547609Sdab encrypt_request_start(0, 0); 19646808Sdab enc_passwd = 1; 19746808Sdab } 19846808Sdab } else { 19946808Sdab if (enc_passwd) { 20046808Sdab encrypt_request_end(); 20146808Sdab enc_passwd = 0; 20246808Sdab } 20346808Sdab } 20460149Sdab #endif /* ENCRYPTION */ 20546808Sdab 20632148Sminshall } 20732148Sminshall 20832148Sminshall 20946808Sdab void 21032148Sminshall setcommandmode() 21132148Sminshall { 21238690Sborman TerminalNewMode(-1); 21332148Sminshall } 214