terminal.c revision 29088
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 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
46Ring		ttyoring, ttyiring;
47unsigned char	ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
48
49int termdata;			/* Debugging flag */
50
51#ifdef	USE_TERMIO
52# ifndef VDISCARD
53cc_t termFlushChar;
54# endif
55# ifndef VLNEXT
56cc_t termLiteralNextChar;
57# endif
58# ifndef VSUSP
59cc_t termSuspChar;
60# endif
61# ifndef VWERASE
62cc_t termWerasChar;
63# endif
64# ifndef VREPRINT
65cc_t termRprntChar;
66# endif
67# ifndef VSTART
68cc_t termStartChar;
69# endif
70# ifndef VSTOP
71cc_t termStopChar;
72# endif
73# ifndef VEOL
74cc_t termForw1Char;
75# endif
76# ifndef VEOL2
77cc_t termForw2Char;
78# endif
79# ifndef VSTATUS
80cc_t termAytChar;
81# endif
82#else
83cc_t termForw2Char;
84cc_t termAytChar;
85#endif
86
87/*
88 * initialize the terminal data structures.
89 */
90
91    void
92init_terminal()
93{
94    if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
95	exit(1);
96    }
97    if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
98	exit(1);
99    }
100    autoflush = TerminalAutoFlush();
101}
102
103
104/*
105 *		Send as much data as possible to the terminal.
106 *
107 *		Return value:
108 *			-1: No useful work done, data waiting to go out.
109 *			 0: No data was waiting, so nothing was done.
110 *			 1: All waiting data was written out.
111 *			 n: All data - n was written out.
112 */
113
114
115    int
116ttyflush(drop)
117    int drop;
118{
119    register int n, n0, n1;
120
121    n0 = ring_full_count(&ttyoring);
122    if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
123	if (drop) {
124	    TerminalFlushOutput();
125	    /* we leave 'n' alone! */
126	} else {
127	    n = TerminalWrite(ttyoring.consume, n);
128	}
129    }
130    if (n > 0) {
131	if (termdata && n) {
132	    Dump('>', ttyoring.consume, n);
133	}
134	/*
135	 * If we wrote everything, and the full count is
136	 * larger than what we wrote, then write the
137	 * rest of the buffer.
138	 */
139	if (n1 == n && n0 > n) {
140		n1 = n0 - n;
141		if (!drop)
142			n1 = TerminalWrite(ttyoring.bottom, n1);
143		if (n1 > 0)
144			n += n1;
145	}
146	ring_consumed(&ttyoring, n);
147    }
148    if (n < 0)
149	return -1;
150    if (n == n0) {
151	if (n0)
152	    return -1;
153	return 0;
154    }
155    return n0 - n + 1;
156}
157
158
159/*
160 * These routines decides on what the mode should be (based on the values
161 * of various global variables).
162 */
163
164
165    int
166getconnmode()
167{
168    extern int linemode;
169    int mode = 0;
170#ifdef	KLUDGELINEMODE
171    extern int kludgelinemode;
172#endif
173
174    if (In3270)
175	return(MODE_FLOW);
176
177    if (my_want_state_is_dont(TELOPT_ECHO))
178	mode |= MODE_ECHO;
179
180    if (localflow)
181	mode |= MODE_FLOW;
182
183    if (my_want_state_is_will(TELOPT_BINARY))
184	mode |= MODE_INBIN;
185
186    if (his_want_state_is_will(TELOPT_BINARY))
187	mode |= MODE_OUTBIN;
188
189#ifdef	KLUDGELINEMODE
190    if (kludgelinemode) {
191	if (my_want_state_is_dont(TELOPT_SGA)) {
192	    mode |= (MODE_TRAPSIG|MODE_EDIT);
193	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
194		mode &= ~MODE_ECHO;
195	    }
196	}
197	return(mode);
198    }
199#endif
200    if (my_want_state_is_will(TELOPT_LINEMODE))
201	mode |= linemode;
202    return(mode);
203}
204
205    void
206setconnmode(force)
207    int force;
208{
209#ifdef	ENCRYPTION
210    static int enc_passwd = 0;
211#endif	/* ENCRYPTION */
212    register int newmode;
213
214    newmode = getconnmode()|(force?MODE_FORCE:0);
215
216    TerminalNewMode(newmode);
217
218#ifdef  ENCRYPTION
219    if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
220	if (my_want_state_is_will(TELOPT_ENCRYPT)
221				&& (enc_passwd == 0) && !encrypt_output) {
222	    encrypt_request_start(0, 0);
223	    enc_passwd = 1;
224	}
225    } else {
226	if (enc_passwd) {
227	    encrypt_request_end();
228	    enc_passwd = 0;
229	}
230    }
231#endif	/* ENCRYPTION */
232
233}
234
235
236    void
237setcommandmode()
238{
239    TerminalNewMode(-1);
240}
241