xref: /original-bsd/usr.bin/telnet/terminal.c (revision 27393bdf)
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