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