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