xref: /netbsd/usr.sbin/lpr/lpd/ttcompat.c (revision 326b2259)
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