1 /* 2 * Copyright (c) 1988, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)terminal.c 8.2 (Berkeley) 02/16/95"; 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 unsigned 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 void 66 init_terminal() 67 { 68 if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) { 69 exit(1); 70 } 71 if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) { 72 exit(1); 73 } 74 autoflush = TerminalAutoFlush(); 75 } 76 77 78 /* 79 * Send as much data as possible to the terminal. 80 * 81 * Return value: 82 * -1: No useful work done, data waiting to go out. 83 * 0: No data was waiting, so nothing was done. 84 * 1: All waiting data was written out. 85 * n: All data - n was written out. 86 */ 87 88 89 int 90 ttyflush(drop) 91 int drop; 92 { 93 register int n, n0, n1; 94 95 n0 = ring_full_count(&ttyoring); 96 if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) { 97 if (drop) { 98 TerminalFlushOutput(); 99 /* we leave 'n' alone! */ 100 } else { 101 n = TerminalWrite(ttyoring.consume, n); 102 } 103 } 104 if (n > 0) { 105 if (termdata && n) { 106 Dump('>', ttyoring.consume, n); 107 } 108 /* 109 * If we wrote everything, and the full count is 110 * larger than what we wrote, then write the 111 * rest of the buffer. 112 */ 113 if (n1 == n && n0 > n) { 114 n1 = n0 - n; 115 if (!drop) 116 n1 = TerminalWrite(ttyoring.bottom, n1); 117 if (n1 > 0) 118 n += n1; 119 } 120 ring_consumed(&ttyoring, n); 121 } 122 if (n < 0) 123 return -1; 124 if (n == n0) { 125 if (n0) 126 return -1; 127 return 0; 128 } 129 return n0 - n + 1; 130 } 131 132 133 /* 134 * These routines decides on what the mode should be (based on the values 135 * of various global variables). 136 */ 137 138 139 int 140 getconnmode() 141 { 142 extern int linemode; 143 int mode = 0; 144 #ifdef KLUDGELINEMODE 145 extern int kludgelinemode; 146 #endif 147 148 if (In3270) 149 return(MODE_FLOW); 150 151 if (my_want_state_is_dont(TELOPT_ECHO)) 152 mode |= MODE_ECHO; 153 154 if (localflow) 155 mode |= MODE_FLOW; 156 157 if (my_want_state_is_will(TELOPT_BINARY)) 158 mode |= MODE_INBIN; 159 160 if (his_want_state_is_will(TELOPT_BINARY)) 161 mode |= MODE_OUTBIN; 162 163 #ifdef KLUDGELINEMODE 164 if (kludgelinemode) { 165 if (my_want_state_is_dont(TELOPT_SGA)) { 166 mode |= (MODE_TRAPSIG|MODE_EDIT); 167 if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 168 mode &= ~MODE_ECHO; 169 } 170 } 171 return(mode); 172 } 173 #endif 174 if (my_want_state_is_will(TELOPT_LINEMODE)) 175 mode |= linemode; 176 return(mode); 177 } 178 179 void 180 setconnmode(force) 181 int force; 182 { 183 #ifdef ENCRYPTION 184 static int enc_passwd = 0; 185 #endif /* ENCRYPTION */ 186 register int newmode; 187 188 newmode = getconnmode()|(force?MODE_FORCE:0); 189 190 TerminalNewMode(newmode); 191 192 #ifdef ENCRYPTION 193 if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) { 194 if (my_want_state_is_will(TELOPT_ENCRYPT) 195 && (enc_passwd == 0) && !encrypt_output) { 196 encrypt_request_start(0, 0); 197 enc_passwd = 1; 198 } 199 } else { 200 if (enc_passwd) { 201 encrypt_request_end(); 202 enc_passwd = 0; 203 } 204 } 205 #endif /* ENCRYPTION */ 206 207 } 208 209 210 void 211 setcommandmode() 212 { 213 TerminalNewMode(-1); 214 } 215