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