terminal.c revision 29181
1/*
2 * Copyright (c) 1988, 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static const char sccsid[] = "@(#)terminal.c	8.2 (Berkeley) 2/16/95";
36#endif /* not lint */
37
38#include <arpa/telnet.h>
39#include <sys/types.h>
40
41#include "ring.h"
42
43#include "externs.h"
44#include "types.h"
45
46#if	defined(ENCRYPTION)
47#include <libtelnet/encrypt.h>
48#endif
49
50Ring		ttyoring, ttyiring;
51unsigned char	ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
52
53int termdata;			/* Debugging flag */
54
55#ifdef	USE_TERMIO
56# ifndef VDISCARD
57cc_t termFlushChar;
58# endif
59# ifndef VLNEXT
60cc_t termLiteralNextChar;
61# endif
62# ifndef VSUSP
63cc_t termSuspChar;
64# endif
65# ifndef VWERASE
66cc_t termWerasChar;
67# endif
68# ifndef VREPRINT
69cc_t termRprntChar;
70# endif
71# ifndef VSTART
72cc_t termStartChar;
73# endif
74# ifndef VSTOP
75cc_t termStopChar;
76# endif
77# ifndef VEOL
78cc_t termForw1Char;
79# endif
80# ifndef VEOL2
81cc_t termForw2Char;
82# endif
83# ifndef VSTATUS
84cc_t termAytChar;
85# endif
86#else
87cc_t termForw2Char;
88cc_t termAytChar;
89#endif
90
91/*
92 * initialize the terminal data structures.
93 */
94
95    void
96init_terminal()
97{
98    if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
99	exit(1);
100    }
101    if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
102	exit(1);
103    }
104    autoflush = TerminalAutoFlush();
105}
106
107
108/*
109 *		Send as much data as possible to the terminal.
110 *
111 *		Return value:
112 *			-1: No useful work done, data waiting to go out.
113 *			 0: No data was waiting, so nothing was done.
114 *			 1: All waiting data was written out.
115 *			 n: All data - n was written out.
116 */
117
118
119    int
120ttyflush(drop)
121    int drop;
122{
123    register int n, n0, n1;
124
125    n0 = ring_full_count(&ttyoring);
126    if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
127	if (drop) {
128	    TerminalFlushOutput();
129	    /* we leave 'n' alone! */
130	} else {
131	    n = TerminalWrite(ttyoring.consume, n);
132	}
133    }
134    if (n > 0) {
135	if (termdata && n) {
136	    Dump('>', ttyoring.consume, n);
137	}
138	/*
139	 * If we wrote everything, and the full count is
140	 * larger than what we wrote, then write the
141	 * rest of the buffer.
142	 */
143	if (n1 == n && n0 > n) {
144		n1 = n0 - n;
145		if (!drop)
146			n1 = TerminalWrite(ttyoring.bottom, n1);
147		if (n1 > 0)
148			n += n1;
149	}
150	ring_consumed(&ttyoring, n);
151    }
152    if (n < 0)
153	return -1;
154    if (n == n0) {
155	if (n0)
156	    return -1;
157	return 0;
158    }
159    return n0 - n + 1;
160}
161
162
163/*
164 * These routines decides on what the mode should be (based on the values
165 * of various global variables).
166 */
167
168
169    int
170getconnmode()
171{
172    extern int linemode;
173    int mode = 0;
174#ifdef	KLUDGELINEMODE
175    extern int kludgelinemode;
176#endif
177
178    if (In3270)
179	return(MODE_FLOW);
180
181    if (my_want_state_is_dont(TELOPT_ECHO))
182	mode |= MODE_ECHO;
183
184    if (localflow)
185	mode |= MODE_FLOW;
186
187    if (my_want_state_is_will(TELOPT_BINARY))
188	mode |= MODE_INBIN;
189
190    if (his_want_state_is_will(TELOPT_BINARY))
191	mode |= MODE_OUTBIN;
192
193#ifdef	KLUDGELINEMODE
194    if (kludgelinemode) {
195	if (my_want_state_is_dont(TELOPT_SGA)) {
196	    mode |= (MODE_TRAPSIG|MODE_EDIT);
197	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
198		mode &= ~MODE_ECHO;
199	    }
200	}
201	return(mode);
202    }
203#endif
204    if (my_want_state_is_will(TELOPT_LINEMODE))
205	mode |= linemode;
206    return(mode);
207}
208
209    void
210setconnmode(force)
211    int force;
212{
213#ifdef	ENCRYPTION
214    static int enc_passwd = 0;
215#endif	/* ENCRYPTION */
216    register int newmode;
217
218    newmode = getconnmode()|(force?MODE_FORCE:0);
219
220    TerminalNewMode(newmode);
221
222#ifdef  ENCRYPTION
223    if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
224	if (my_want_state_is_will(TELOPT_ENCRYPT)
225				&& (enc_passwd == 0) && !encrypt_output) {
226	    encrypt_request_start(0, 0);
227	    enc_passwd = 1;
228	}
229    } else {
230	if (enc_passwd) {
231	    encrypt_request_end();
232	    enc_passwd = 0;
233	}
234    }
235#endif	/* ENCRYPTION */
236
237}
238
239
240    void
241setcommandmode()
242{
243    TerminalNewMode(-1);
244}
245