1 /* 2 * Copyright (c) 1988, 1990 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)terminal.c 5.1 (Berkeley) 09/14/90"; 10 #endif /* not lint */ 11 12 #include <arpa/telnet.h> 13 #include <sys/types.h> 14 15 #include "ring.h" 16 17 #include "externs.h" 18 #include "types.h" 19 20 Ring ttyoring, ttyiring; 21 char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ]; 22 23 int termdata; /* Debugging flag */ 24 25 #ifdef USE_TERMIO 26 # ifndef VDISCARD 27 cc_t termFlushChar; 28 # endif 29 # ifndef VLNEXT 30 cc_t termLiteralNextChar; 31 # endif 32 # ifndef VSUSP 33 cc_t termSuspChar; 34 # endif 35 # ifndef VWERASE 36 cc_t termWerasChar; 37 # endif 38 # ifndef VREPRINT 39 cc_t termRprntChar; 40 # endif 41 # ifndef VSTART 42 cc_t termStartChar; 43 # endif 44 # ifndef VSTOP 45 cc_t termStopChar; 46 # endif 47 # ifndef VEOL 48 cc_t termForw1Char; 49 # endif 50 # ifndef VEOL2 51 cc_t termForw2Char; 52 # endif 53 # ifndef VSTATUS 54 cc_t termAytChar; 55 # endif 56 #else 57 cc_t termForw2Char; 58 cc_t termAytChar; 59 #endif 60 61 /* 62 * initialize the terminal data structures. 63 */ 64 65 init_terminal() 66 { 67 if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) { 68 exit(1); 69 } 70 if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) { 71 exit(1); 72 } 73 autoflush = TerminalAutoFlush(); 74 } 75 76 77 /* 78 * Send as much data as possible to the terminal. 79 * 80 * Return value: 81 * -1: No useful work done, data waiting to go out. 82 * 0: No data was waiting, so nothing was done. 83 * 1: All waiting data was written out. 84 * n: All data - n was written out. 85 */ 86 87 88 int 89 ttyflush(drop) 90 int drop; 91 { 92 register int n, n0, n1; 93 94 n0 = ring_full_count(&ttyoring); 95 if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) { 96 if (drop) { 97 TerminalFlushOutput(); 98 /* we leave 'n' alone! */ 99 } else { 100 n = TerminalWrite(ttyoring.consume, n); 101 } 102 } 103 if (n > 0) { 104 if (termdata && n) { 105 Dump('>', ttyoring.consume, n); 106 } 107 /* 108 * If we wrote everything, and the full count is 109 * larger than what we wrote, then write the 110 * rest of the buffer. 111 */ 112 if (n1 == n && n0 > n) { 113 n1 = n0 - n; 114 if (!drop) 115 n1 = TerminalWrite(ttyoring.bottom, n1); 116 n += n1; 117 } 118 ring_consumed(&ttyoring, n); 119 } 120 if (n < 0) 121 return -1; 122 if (n == n0) { 123 if (n0) 124 return -1; 125 return 0; 126 } 127 return n0 - n + 1; 128 } 129 130 131 /* 132 * These routines decides on what the mode should be (based on the values 133 * of various global variables). 134 */ 135 136 137 int 138 getconnmode() 139 { 140 extern int linemode; 141 int mode = 0; 142 #ifdef KLUDGELINEMODE 143 extern int kludgelinemode; 144 #endif 145 146 if (In3270) 147 return(MODE_FLOW); 148 149 if (my_want_state_is_dont(TELOPT_ECHO)) 150 mode |= MODE_ECHO; 151 152 if (localflow) 153 mode |= MODE_FLOW; 154 155 if (my_want_state_is_will(TELOPT_BINARY)) 156 mode |= MODE_INBIN; 157 158 if (his_want_state_is_will(TELOPT_BINARY)) 159 mode |= MODE_OUTBIN; 160 161 #ifdef KLUDGELINEMODE 162 if (kludgelinemode) { 163 if (my_want_state_is_dont(TELOPT_SGA)) { 164 mode |= (MODE_TRAPSIG|MODE_EDIT); 165 if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 166 mode &= ~MODE_ECHO; 167 } 168 } 169 return(mode); 170 } 171 #endif 172 if (my_want_state_is_will(TELOPT_LINEMODE)) 173 mode |= linemode; 174 return(mode); 175 } 176 177 void 178 setconnmode(force) 179 { 180 TerminalNewMode(getconnmode()|(force?MODE_FORCE:0)); 181 } 182 183 184 void 185 setcommandmode() 186 { 187 TerminalNewMode(-1); 188 } 189