xref: /original-bsd/usr.bin/telnet/terminal.c (revision c3e32dec)
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.1 (Berkeley) 06/06/93";
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 		n += n1;
118 	}
119 	ring_consumed(&ttyoring, n);
120     }
121     if (n < 0)
122 	return -1;
123     if (n == n0) {
124 	if (n0)
125 	    return -1;
126 	return 0;
127     }
128     return n0 - n + 1;
129 }
130 
131 
132 /*
133  * These routines decides on what the mode should be (based on the values
134  * of various global variables).
135  */
136 
137 
138     int
139 getconnmode()
140 {
141     extern int linemode;
142     int mode = 0;
143 #ifdef	KLUDGELINEMODE
144     extern int kludgelinemode;
145 #endif
146 
147     if (In3270)
148 	return(MODE_FLOW);
149 
150     if (my_want_state_is_dont(TELOPT_ECHO))
151 	mode |= MODE_ECHO;
152 
153     if (localflow)
154 	mode |= MODE_FLOW;
155 
156     if (my_want_state_is_will(TELOPT_BINARY))
157 	mode |= MODE_INBIN;
158 
159     if (his_want_state_is_will(TELOPT_BINARY))
160 	mode |= MODE_OUTBIN;
161 
162 #ifdef	KLUDGELINEMODE
163     if (kludgelinemode) {
164 	if (my_want_state_is_dont(TELOPT_SGA)) {
165 	    mode |= (MODE_TRAPSIG|MODE_EDIT);
166 	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
167 		mode &= ~MODE_ECHO;
168 	    }
169 	}
170 	return(mode);
171     }
172 #endif
173     if (my_want_state_is_will(TELOPT_LINEMODE))
174 	mode |= linemode;
175     return(mode);
176 }
177 
178     void
179 setconnmode(force)
180     int force;
181 {
182 #ifdef	ENCRYPTION
183     static int enc_passwd = 0;
184 #endif	/* ENCRYPTION */
185     register int newmode;
186 
187     newmode = getconnmode()|(force?MODE_FORCE:0);
188 
189     TerminalNewMode(newmode);
190 
191 #ifdef  ENCRYPTION
192     if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
193 	if (my_want_state_is_will(TELOPT_ENCRYPT)
194 				&& (enc_passwd == 0) && !encrypt_output) {
195 	    encrypt_request_start(0, 0);
196 	    enc_passwd = 1;
197 	}
198     } else {
199 	if (enc_passwd) {
200 	    encrypt_request_end();
201 	    enc_passwd = 0;
202 	}
203     }
204 #endif	/* ENCRYPTION */
205 
206 }
207 
208 
209     void
210 setcommandmode()
211 {
212     TerminalNewMode(-1);
213 }
214