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*40245Sborman static char sccsid[] = "@(#)terminal.c 1.18 (Berkeley) 03/01/90"; 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 3639529Sborman # ifndef VFLUSHO 3739529Sborman char termFlushChar; 3839529Sborman # endif 3939529Sborman # ifndef VLNEXT 4039529Sborman char termLiteralNextChar; 4139529Sborman # endif 4239529Sborman # ifndef VSUSP 4339529Sborman char termSuspChar; 4439529Sborman # endif 4539529Sborman # ifndef VWERASE 4639529Sborman char termWerasChar; 4739529Sborman # endif 4839529Sborman # ifndef VREPRINT 4939529Sborman char termRprntChar; 5039529Sborman # endif 5139529Sborman # ifndef VSTART 5239529Sborman char termStartChar; 5339529Sborman # endif 5439529Sborman # ifndef VSTOP 5539529Sborman char termStopChar; 5639529Sborman # endif 57*40245Sborman # ifndef VEOL 58*40245Sborman char termForw1Char; 59*40245Sborman # endif 60*40245Sborman # ifndef VEOL2 61*40245Sborman char termForw2Char; 62*40245Sborman # endif 63*40245Sborman #else 64*40245Sborman char termForw2Char; 6538690Sborman #endif 6632148Sminshall 6732148Sminshall /* 6832148Sminshall * initialize the terminal data structures. 6932148Sminshall */ 7032148Sminshall 7132148Sminshall init_terminal() 7232148Sminshall { 7334848Sminshall if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) { 7434848Sminshall exit(1); 7534848Sminshall } 7634848Sminshall if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) { 7734848Sminshall exit(1); 7834848Sminshall } 7932148Sminshall autoflush = TerminalAutoFlush(); 8032148Sminshall } 8132148Sminshall 8232148Sminshall 8332148Sminshall /* 8432148Sminshall * Send as much data as possible to the terminal. 8532148Sminshall * 8638690Sborman * Return value: 8738690Sborman * -1: No useful work done, data waiting to go out. 8838690Sborman * 0: No data was waiting, so nothing was done. 8938690Sborman * 1: All waiting data was written out. 9038690Sborman * n: All data - n was written out. 9132148Sminshall */ 9232148Sminshall 9332148Sminshall 9432148Sminshall int 9532257Sminshall ttyflush(drop) 9632257Sminshall int drop; 9732148Sminshall { 9832667Sminshall register int n, n0, n1; 9932148Sminshall 10032667Sminshall n0 = ring_full_count(&ttyoring); 10132667Sminshall if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) { 10232257Sminshall if (drop) { 10332148Sminshall TerminalFlushOutput(); 10432148Sminshall /* we leave 'n' alone! */ 10532257Sminshall } else { 10633286Sminshall n = TerminalWrite(ttyoring.consume, n); 10732148Sminshall } 10832148Sminshall } 10932667Sminshall if (n > 0) { 11038208Sminshall if (termdata && n) { 11138208Sminshall Dump('>', ttyoring.consume, n); 11238208Sminshall } 11332667Sminshall /* 11432667Sminshall * If we wrote everything, and the full count is 11532667Sminshall * larger than what we wrote, then write the 11632667Sminshall * rest of the buffer. 11732667Sminshall */ 11832667Sminshall if (n1 == n && n0 > n) { 11932667Sminshall n1 = n0 - n; 12032667Sminshall if (!drop) 12133286Sminshall n1 = TerminalWrite(ttyoring.bottom, n1); 12232667Sminshall n += n1; 12332667Sminshall } 12432528Sminshall ring_consumed(&ttyoring, n); 12532148Sminshall } 12638690Sborman if (n < 0) 12738690Sborman return -1; 12838690Sborman if (n == n0) { 12938690Sborman if (n0) 13038690Sborman return -1; 13138690Sborman return 0; 13238690Sborman } 13338690Sborman return n0 - n + 1; 13432148Sminshall } 13532148Sminshall 13632148Sminshall 13732148Sminshall /* 13832148Sminshall * These routines decides on what the mode should be (based on the values 13932148Sminshall * of various global variables). 14032148Sminshall */ 14132148Sminshall 14232148Sminshall 14332148Sminshall int 14432148Sminshall getconnmode() 14532148Sminshall { 14638690Sborman extern int linemode; 14738690Sborman int mode = 0; 14838690Sborman #ifdef KLUDGELINEMODE 14938690Sborman extern int kludgelinemode; 15038690Sborman #endif 15132148Sminshall 15238690Sborman if (In3270) 15338690Sborman return(MODE_FLOW); 15438690Sborman 15538690Sborman if (my_want_state_is_dont(TELOPT_ECHO)) 15638690Sborman mode |= MODE_ECHO; 15738690Sborman 15838690Sborman if (localflow) 15938690Sborman mode |= MODE_FLOW; 16038690Sborman 16139529Sborman if (my_want_state_is_will(TELOPT_BINARY)) 16239529Sborman mode |= MODE_INBIN; 16339529Sborman 16439529Sborman if (his_want_state_is_will(TELOPT_BINARY)) 16539529Sborman mode |= MODE_OUTBIN; 16639529Sborman 16738690Sborman #ifdef KLUDGELINEMODE 16838690Sborman if (kludgelinemode) { 16938690Sborman if (my_want_state_is_dont(TELOPT_SGA)) { 17038690Sborman mode |= (MODE_TRAPSIG|MODE_EDIT); 17138690Sborman if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 17238690Sborman mode &= ~MODE_ECHO; 17338690Sborman } 17438690Sborman } 17538690Sborman return(mode); 17632148Sminshall } 17738690Sborman #endif 17838690Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) 17938690Sborman mode |= linemode; 18038690Sborman return(mode); 18132148Sminshall } 18232148Sminshall 18332148Sminshall void 18438690Sborman setconnmode(force) 18532148Sminshall { 18638690Sborman TerminalNewMode(getconnmode()|(force?MODE_FORCE:0)); 18732148Sminshall } 18832148Sminshall 18932148Sminshall 19032148Sminshall void 19132148Sminshall setcommandmode() 19232148Sminshall { 19338690Sborman TerminalNewMode(-1); 19432148Sminshall } 195