xref: /original-bsd/usr.bin/telnet/terminal.c (revision e9b82df0)
1 /*
2  * Copyright (c) 1988 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	1.19 (Berkeley) 06/01/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 VFLUSHO
27 char termFlushChar;
28 # endif
29 # ifndef VLNEXT
30 char termLiteralNextChar;
31 # endif
32 # ifndef VSUSP
33 char termSuspChar;
34 # endif
35 # ifndef VWERASE
36 char termWerasChar;
37 # endif
38 # ifndef VREPRINT
39 char termRprntChar;
40 # endif
41 # ifndef VSTART
42 char termStartChar;
43 # endif
44 # ifndef VSTOP
45 char termStopChar;
46 # endif
47 # ifndef VEOL
48 char termForw1Char;
49 # endif
50 # ifndef VEOL2
51 char termForw2Char;
52 # endif
53 #else
54 char termForw2Char;
55 #endif
56 
57 /*
58  * initialize the terminal data structures.
59  */
60 
61 init_terminal()
62 {
63     if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
64 	exit(1);
65     }
66     if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
67 	exit(1);
68     }
69     autoflush = TerminalAutoFlush();
70 }
71 
72 
73 /*
74  *		Send as much data as possible to the terminal.
75  *
76  *		Return value:
77  *			-1: No useful work done, data waiting to go out.
78  *			 0: No data was waiting, so nothing was done.
79  *			 1: All waiting data was written out.
80  *			 n: All data - n was written out.
81  */
82 
83 
84 int
85 ttyflush(drop)
86 int drop;
87 {
88     register int n, n0, n1;
89 
90     n0 = ring_full_count(&ttyoring);
91     if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
92 	if (drop) {
93 	    TerminalFlushOutput();
94 	    /* we leave 'n' alone! */
95 	} else {
96 	    n = TerminalWrite(ttyoring.consume, n);
97 	}
98     }
99     if (n > 0) {
100 	if (termdata && n) {
101 	    Dump('>', ttyoring.consume, n);
102 	}
103 	/*
104 	 * If we wrote everything, and the full count is
105 	 * larger than what we wrote, then write the
106 	 * rest of the buffer.
107 	 */
108 	if (n1 == n && n0 > n) {
109 		n1 = n0 - n;
110 		if (!drop)
111 			n1 = TerminalWrite(ttyoring.bottom, n1);
112 		n += n1;
113 	}
114 	ring_consumed(&ttyoring, n);
115     }
116     if (n < 0)
117 	return -1;
118     if (n == n0) {
119 	if (n0)
120 	    return -1;
121 	return 0;
122     }
123     return n0 - n + 1;
124 }
125 
126 
127 /*
128  * These routines decides on what the mode should be (based on the values
129  * of various global variables).
130  */
131 
132 
133 int
134 getconnmode()
135 {
136     extern int linemode;
137     int mode = 0;
138 #ifdef	KLUDGELINEMODE
139     extern int kludgelinemode;
140 #endif
141 
142     if (In3270)
143 	return(MODE_FLOW);
144 
145     if (my_want_state_is_dont(TELOPT_ECHO))
146 	mode |= MODE_ECHO;
147 
148     if (localflow)
149 	mode |= MODE_FLOW;
150 
151     if (my_want_state_is_will(TELOPT_BINARY))
152 	mode |= MODE_INBIN;
153 
154     if (his_want_state_is_will(TELOPT_BINARY))
155 	mode |= MODE_OUTBIN;
156 
157 #ifdef	KLUDGELINEMODE
158     if (kludgelinemode) {
159 	if (my_want_state_is_dont(TELOPT_SGA)) {
160 	    mode |= (MODE_TRAPSIG|MODE_EDIT);
161 	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
162 		mode &= ~MODE_ECHO;
163 	    }
164 	}
165 	return(mode);
166     }
167 #endif
168     if (my_want_state_is_will(TELOPT_LINEMODE))
169 	mode |= linemode;
170     return(mode);
171 }
172 
173 void
174 setconnmode(force)
175 {
176     TerminalNewMode(getconnmode()|(force?MODE_FORCE:0));
177 }
178 
179 
180 void
181 setcommandmode()
182 {
183     TerminalNewMode(-1);
184 }
185