ttcompat.c revision 1.8 1 /*
2 * Copyright (c) 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 /*
36 * ttcompat.c -- convert sgtty flags to termios
37 * originally from /sys/kern/tty_compat.c
38 */
39
40 #include <sys/param.h>
41 #include <sys/types.h>
42
43 #include <unistd.h>
44 #include <sys/ioctl_compat.h>
45 #include <termios.h>
46 #include <syslog.h>
47 #include <fcntl.h>
48 #include <dirent.h>
49 #include <errno.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <stdlib.h>
53 #include "extern.h"
54
55 /* Macros to clear/set/test flags. */
56 #define SET(t, f) (t) |= (f)
57 #define CLR(t, f) (t) &= ~(f)
58 #define ISSET(t, f) ((t) & (f))
59
60 static int
61 sttygetoflags(tp)
62 struct termios *tp;
63 {
64 register tcflag_t iflag = tp->c_iflag;
65 register tcflag_t lflag = tp->c_lflag;
66 register tcflag_t oflag = tp->c_oflag;
67 register tcflag_t cflag = tp->c_cflag;
68 register int flags = 0;
69
70 if (ISSET(cflag, PARENB)) {
71 if (ISSET(iflag, INPCK)) {
72 if (ISSET(cflag, PARODD))
73 SET(flags, ODDP);
74 else
75 SET(flags, EVENP);
76 } else
77 SET(flags, EVENP|ODDP);
78 }
79 if (ISSET(cflag, CSIZE) == CS8) {
80 if (!ISSET(iflag, ISTRIP))
81 SET(flags, PASS8);
82 if (!ISSET(oflag, OPOST))
83 SET(flags, LITOUT);
84 }
85
86 if (!ISSET(lflag, ICANON)) {
87 /* fudge */
88 if (ISSET(iflag, IXON) || ISSET(lflag, ISIG|IEXTEN) ||
89 ISSET(cflag, PARENB))
90 SET(flags, CBREAK);
91 else
92 SET(flags, RAW);
93 }
94
95 return (flags);
96 }
97
98 static void
99 sttysetoflags(tp, flags)
100 struct termios *tp;
101 int flags;
102 {
103 register tcflag_t iflag = tp->c_iflag;
104 register tcflag_t oflag = tp->c_oflag;
105 register tcflag_t lflag = tp->c_lflag;
106 register tcflag_t cflag = tp->c_cflag;
107
108 if (ISSET(flags, RAW)) {
109 iflag &= IXOFF;
110 CLR(lflag, ISIG|ICANON|IEXTEN);
111 CLR(cflag, PARENB);
112 } else {
113 SET(iflag, BRKINT|IXON|IMAXBEL);
114 SET(lflag, ISIG|IEXTEN);
115 if (ISSET(flags, CBREAK))
116 CLR(lflag, ICANON);
117 else
118 SET(lflag, ICANON);
119 switch (ISSET(flags, ANYP)) {
120 case 0:
121 CLR(cflag, PARENB);
122 break;
123 case ANYP:
124 SET(cflag, PARENB);
125 CLR(iflag, INPCK);
126 break;
127 case EVENP:
128 SET(cflag, PARENB);
129 SET(iflag, INPCK);
130 CLR(cflag, PARODD);
131 break;
132 case ODDP:
133 SET(cflag, PARENB);
134 SET(iflag, INPCK);
135 SET(cflag, PARODD);
136 break;
137 }
138 }
139
140 if (ISSET(flags, RAW|LITOUT|PASS8)) {
141 CLR(cflag, CSIZE);
142 SET(cflag, CS8);
143 if (!ISSET(flags, RAW|PASS8))
144 SET(iflag, ISTRIP);
145 else
146 CLR(iflag, ISTRIP);
147 if (!ISSET(flags, RAW|LITOUT))
148 SET(oflag, OPOST);
149 else
150 CLR(oflag, OPOST);
151 } else {
152 CLR(cflag, CSIZE);
153 SET(cflag, CS7);
154 SET(iflag, ISTRIP);
155 SET(oflag, OPOST);
156 }
157
158 tp->c_iflag = iflag;
159 tp->c_oflag = oflag;
160 tp->c_lflag = lflag;
161 tp->c_cflag = cflag;
162 }
163
164 void
165 sttyclearflags(tp, flags)
166 struct termios *tp;
167 int flags;
168 {
169 register tcflag_t iflag = tp->c_iflag;
170 register tcflag_t oflag = tp->c_oflag;
171 register tcflag_t lflag = tp->c_lflag;
172 register tcflag_t cflag = tp->c_cflag;
173 register int oflags = sttygetoflags(tp) & ~flags;
174
175 if (ISSET(flags, TANDEM))
176 CLR(iflag, IXOFF);
177 if (ISSET(flags, ECHO))
178 CLR(lflag, ECHO);
179 if (ISSET(flags, CRMOD)) {
180 CLR(iflag, ICRNL);
181 CLR(oflag, ONLCR);
182 }
183 if (ISSET(flags, XTABS))
184 CLR(oflag, OXTABS);
185
186
187 tp->c_iflag = iflag;
188 tp->c_oflag = oflag;
189 tp->c_lflag = lflag;
190 tp->c_cflag = cflag;
191
192 sttysetoflags(tp, oflags);
193 }
194
195 void
196 sttysetflags(tp, flags)
197 struct termios *tp;
198 int flags;
199 {
200 register tcflag_t iflag = tp->c_iflag;
201 register tcflag_t oflag = tp->c_oflag;
202 register tcflag_t lflag = tp->c_lflag;
203 register tcflag_t cflag = tp->c_cflag;
204 register int oflags = sttygetoflags(tp) | flags;
205
206 if (ISSET(flags, TANDEM))
207 SET(iflag, IXOFF);
208 if (ISSET(flags, ECHO))
209 SET(lflag, ECHO);
210 if (ISSET(flags, CRMOD)) {
211 SET(iflag, ICRNL);
212 SET(oflag, ONLCR);
213 }
214 if (ISSET(flags, XTABS))
215 SET(oflag, OXTABS);
216
217 tp->c_iflag = iflag;
218 tp->c_oflag = oflag;
219 tp->c_lflag = lflag;
220 tp->c_cflag = cflag;
221
222 sttysetoflags(tp, oflags);
223 }
224
225 void
226 sttyclearlflags(tp, flags)
227 struct termios *tp;
228 int flags;
229 {
230 register tcflag_t iflag = tp->c_iflag;
231 register tcflag_t oflag = tp->c_oflag;
232 register tcflag_t lflag = tp->c_lflag;
233 register tcflag_t cflag = tp->c_cflag;
234 register int oflags = sttygetoflags(tp) & ~flags;
235
236 /* Nothing we can do with CRTBS. */
237 if (ISSET(flags, PRTERA))
238 CLR(lflag, ECHOPRT);
239 if (ISSET(flags, CRTERA))
240 CLR(lflag, ECHOE);
241 /* Nothing we can do with TILDE. */
242 if (ISSET(flags, MDMBUF))
243 CLR(cflag, MDMBUF);
244 if (ISSET(flags, NOHANG))
245 SET(cflag, HUPCL);
246 if (ISSET(flags, CRTKIL))
247 CLR(lflag, ECHOKE);
248 if (ISSET(flags, CTLECH))
249 CLR(lflag, ECHOCTL);
250 if (ISSET(flags, DECCTQ))
251 SET(iflag, IXANY);
252 CLR(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
253
254 tp->c_iflag = iflag;
255 tp->c_oflag = oflag;
256 tp->c_lflag = lflag;
257 tp->c_cflag = cflag;
258
259 sttysetoflags(tp, oflags);
260 }
261
262 void
263 sttysetlflags(tp, flags)
264 struct termios *tp;
265 int flags;
266 {
267 register tcflag_t iflag = tp->c_iflag;
268 register tcflag_t oflag = tp->c_oflag;
269 register tcflag_t lflag = tp->c_lflag;
270 register tcflag_t cflag = tp->c_cflag;
271 register int oflags = sttygetoflags(tp) | flags;
272
273 /* Nothing we can do with CRTBS. */
274 if (ISSET(flags, PRTERA))
275 SET(lflag, ECHOPRT);
276 if (ISSET(flags, CRTERA))
277 SET(lflag, ECHOE);
278 /* Nothing we can do with TILDE. */
279 if (ISSET(flags, MDMBUF))
280 SET(cflag, MDMBUF);
281 if (ISSET(flags, NOHANG))
282 CLR(cflag, HUPCL);
283 if (ISSET(flags, CRTKIL))
284 SET(lflag, ECHOKE);
285 if (ISSET(flags, CTLECH))
286 SET(lflag, ECHOCTL);
287 if (ISSET(flags, DECCTQ))
288 CLR(iflag, IXANY);
289 SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
290
291 tp->c_iflag = iflag;
292 tp->c_oflag = oflag;
293 tp->c_lflag = lflag;
294 tp->c_cflag = cflag;
295
296 sttysetoflags(tp, oflags);
297 }
298