xref: /netbsd/usr.sbin/lpr/lpd/ttcompat.c (revision bf9ec67e)
1 /*	$NetBSD: ttcompat.c,v 1.10 1997/10/05 15:12:16 mrg 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 __P((struct termios *));
62 static void	sttysetoflags __P((struct termios *, int));
63 
64 static int
65 sttygetoflags(tp)
66 	struct termios *tp;
67 {
68 	tcflag_t iflag = tp->c_iflag;
69 	tcflag_t lflag = tp->c_lflag;
70 	tcflag_t oflag = tp->c_oflag;
71 	tcflag_t cflag = tp->c_cflag;
72 	int flags = 0;
73 
74 	if (ISSET(cflag, PARENB)) {
75 		if (ISSET(iflag, INPCK)) {
76 			if (ISSET(cflag, PARODD))
77 				SET(flags, ODDP);
78 			else
79 				SET(flags, EVENP);
80 		} else
81 			SET(flags, EVENP|ODDP);
82 	}
83 	if (ISSET(cflag, CSIZE) == CS8) {
84 		if (!ISSET(iflag, ISTRIP))
85 			SET(flags, PASS8);
86 		if (!ISSET(oflag, OPOST))
87 			SET(flags, LITOUT);
88 	}
89 
90 	if (!ISSET(lflag, ICANON)) {
91 		/* fudge */
92 		if (ISSET(iflag, IXON) || ISSET(lflag, ISIG|IEXTEN) ||
93 		    ISSET(cflag, PARENB))
94 			SET(flags, CBREAK);
95 		else
96 			SET(flags, RAW);
97 	}
98 
99 	return (flags);
100 }
101 
102 static void
103 sttysetoflags(tp, flags)
104 	struct termios *tp;
105 	int flags;
106 {
107 	tcflag_t iflag = tp->c_iflag;
108 	tcflag_t oflag = tp->c_oflag;
109 	tcflag_t lflag = tp->c_lflag;
110 	tcflag_t cflag = tp->c_cflag;
111 
112 	if (ISSET(flags, RAW)) {
113 		iflag &= IXOFF;
114 		CLR(lflag, ISIG|ICANON|IEXTEN);
115 		CLR(cflag, PARENB);
116 	} else {
117 		SET(iflag, BRKINT|IXON|IMAXBEL);
118 		SET(lflag, ISIG|IEXTEN);
119 		if (ISSET(flags, CBREAK))
120 			CLR(lflag, ICANON);
121 		else
122 			SET(lflag, ICANON);
123 		switch (ISSET(flags, ANYP)) {
124 		case 0:
125 			CLR(cflag, PARENB);
126 			break;
127 		case ANYP:
128 			SET(cflag, PARENB);
129 			CLR(iflag, INPCK);
130 			break;
131 		case EVENP:
132 			SET(cflag, PARENB);
133 			SET(iflag, INPCK);
134 			CLR(cflag, PARODD);
135 			break;
136 		case ODDP:
137 			SET(cflag, PARENB);
138 			SET(iflag, INPCK);
139 			SET(cflag, PARODD);
140 			break;
141 		}
142 	}
143 
144 	if (ISSET(flags, RAW|LITOUT|PASS8)) {
145 		CLR(cflag, CSIZE);
146 		SET(cflag, CS8);
147 		if (!ISSET(flags, RAW|PASS8))
148 			SET(iflag, ISTRIP);
149 		else
150 			CLR(iflag, ISTRIP);
151 		if (!ISSET(flags, RAW|LITOUT))
152 			SET(oflag, OPOST);
153 		else
154 			CLR(oflag, OPOST);
155 	} else {
156 		CLR(cflag, CSIZE);
157 		SET(cflag, CS7);
158 		SET(iflag, ISTRIP);
159 		SET(oflag, OPOST);
160 	}
161 
162 	tp->c_iflag = iflag;
163 	tp->c_oflag = oflag;
164 	tp->c_lflag = lflag;
165 	tp->c_cflag = cflag;
166 }
167 
168 void
169 sttyclearflags(tp, flags)
170 	struct termios *tp;
171 	int flags;
172 {
173 	tcflag_t iflag = tp->c_iflag;
174 	tcflag_t oflag = tp->c_oflag;
175 	tcflag_t lflag = tp->c_lflag;
176 	tcflag_t cflag = tp->c_cflag;
177 	int oflags = sttygetoflags(tp) & ~flags;
178 
179 	if (ISSET(flags, TANDEM))
180 		CLR(iflag, IXOFF);
181 	if (ISSET(flags, ECHO))
182 		CLR(lflag, ECHO);
183 	if (ISSET(flags, CRMOD)) {
184 		CLR(iflag, ICRNL);
185 		CLR(oflag, ONLCR);
186 	}
187 	if (ISSET(flags, XTABS))
188 		CLR(oflag, OXTABS);
189 
190 
191 	tp->c_iflag = iflag;
192 	tp->c_oflag = oflag;
193 	tp->c_lflag = lflag;
194 	tp->c_cflag = cflag;
195 
196 	sttysetoflags(tp, oflags);
197 }
198 
199 void
200 sttysetflags(tp, flags)
201 	struct termios *tp;
202 	int flags;
203 {
204 	tcflag_t iflag = tp->c_iflag;
205 	tcflag_t oflag = tp->c_oflag;
206 	tcflag_t lflag = tp->c_lflag;
207 	tcflag_t cflag = tp->c_cflag;
208 	int oflags = sttygetoflags(tp) | flags;
209 
210 	if (ISSET(flags, TANDEM))
211 		SET(iflag, IXOFF);
212 	if (ISSET(flags, ECHO))
213 		SET(lflag, ECHO);
214 	if (ISSET(flags, CRMOD)) {
215 		SET(iflag, ICRNL);
216 		SET(oflag, ONLCR);
217 	}
218 	if (ISSET(flags, XTABS))
219 		SET(oflag, OXTABS);
220 
221 	tp->c_iflag = iflag;
222 	tp->c_oflag = oflag;
223 	tp->c_lflag = lflag;
224 	tp->c_cflag = cflag;
225 
226 	sttysetoflags(tp, oflags);
227 }
228 
229 void
230 sttyclearlflags(tp, flags)
231 	struct termios *tp;
232 	int flags;
233 {
234 	tcflag_t iflag = tp->c_iflag;
235 	tcflag_t oflag = tp->c_oflag;
236 	tcflag_t lflag = tp->c_lflag;
237 	tcflag_t cflag = tp->c_cflag;
238 	int oflags = sttygetoflags(tp) & ~flags;
239 
240 	/* Nothing we can do with CRTBS. */
241 	if (ISSET(flags, PRTERA))
242 		CLR(lflag, ECHOPRT);
243 	if (ISSET(flags, CRTERA))
244 		CLR(lflag, ECHOE);
245 	/* Nothing we can do with TILDE. */
246 	if (ISSET(flags, MDMBUF))
247 		CLR(cflag, MDMBUF);
248 	if (ISSET(flags, NOHANG))
249 		SET(cflag, HUPCL);
250 	if (ISSET(flags, CRTKIL))
251 		CLR(lflag, ECHOKE);
252 	if (ISSET(flags, CTLECH))
253 		CLR(lflag, ECHOCTL);
254 	if (ISSET(flags, DECCTQ))
255 		SET(iflag, IXANY);
256 	CLR(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
257 
258 	tp->c_iflag = iflag;
259 	tp->c_oflag = oflag;
260 	tp->c_lflag = lflag;
261 	tp->c_cflag = cflag;
262 
263 	sttysetoflags(tp, oflags);
264 }
265 
266 void
267 sttysetlflags(tp, flags)
268 	struct termios *tp;
269 	int flags;
270 {
271 	tcflag_t iflag = tp->c_iflag;
272 	tcflag_t oflag = tp->c_oflag;
273 	tcflag_t lflag = tp->c_lflag;
274 	tcflag_t cflag = tp->c_cflag;
275 	int oflags = sttygetoflags(tp) | flags;
276 
277 	/* Nothing we can do with CRTBS. */
278 	if (ISSET(flags, PRTERA))
279 		SET(lflag, ECHOPRT);
280 	if (ISSET(flags, CRTERA))
281 		SET(lflag, ECHOE);
282 	/* Nothing we can do with TILDE. */
283 	if (ISSET(flags, MDMBUF))
284 		SET(cflag, MDMBUF);
285 	if (ISSET(flags, NOHANG))
286 		CLR(cflag, HUPCL);
287 	if (ISSET(flags, CRTKIL))
288 		SET(lflag, ECHOKE);
289 	if (ISSET(flags, CTLECH))
290 		SET(lflag, ECHOCTL);
291 	if (ISSET(flags, DECCTQ))
292 		CLR(iflag, IXANY);
293 	SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
294 
295 	tp->c_iflag = iflag;
296 	tp->c_oflag = oflag;
297 	tp->c_lflag = lflag;
298 	tp->c_cflag = cflag;
299 
300 	sttysetoflags(tp, oflags);
301 }
302