xref: /netbsd-src/usr.sbin/lpr/lpd/ttcompat.c (revision 326b2259b73e878289ebd80cd9d20bc5aee35e99)
1*326b2259Sagc /*	$NetBSD: ttcompat.c,v 1.12 2003/08/07 11:25:28 agc Exp $	*/
28e41ca80Shpeyerl /*
38e41ca80Shpeyerl  * Copyright (c) 1995
48e41ca80Shpeyerl  *	The Regents of the University of California.  All rights reserved.
58e41ca80Shpeyerl  *
68e41ca80Shpeyerl  *
78e41ca80Shpeyerl  * Redistribution and use in source and binary forms, with or without
88e41ca80Shpeyerl  * modification, are permitted provided that the following conditions
98e41ca80Shpeyerl  * are met:
108e41ca80Shpeyerl  * 1. Redistributions of source code must retain the above copyright
118e41ca80Shpeyerl  *    notice, this list of conditions and the following disclaimer.
128e41ca80Shpeyerl  * 2. Redistributions in binary form must reproduce the above copyright
138e41ca80Shpeyerl  *    notice, this list of conditions and the following disclaimer in the
148e41ca80Shpeyerl  *    documentation and/or other materials provided with the distribution.
15*326b2259Sagc  * 3. Neither the name of the University nor the names of its contributors
168e41ca80Shpeyerl  *    may be used to endorse or promote products derived from this software
178e41ca80Shpeyerl  *    without specific prior written permission.
188e41ca80Shpeyerl  *
198e41ca80Shpeyerl  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
208e41ca80Shpeyerl  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
218e41ca80Shpeyerl  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
228e41ca80Shpeyerl  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
238e41ca80Shpeyerl  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
248e41ca80Shpeyerl  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
258e41ca80Shpeyerl  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
268e41ca80Shpeyerl  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
278e41ca80Shpeyerl  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
288e41ca80Shpeyerl  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
298e41ca80Shpeyerl  * SUCH DAMAGE.
308e41ca80Shpeyerl  */
318e41ca80Shpeyerl 
328e41ca80Shpeyerl /*
338e41ca80Shpeyerl  * ttcompat.c -- convert sgtty flags to termios
348e41ca80Shpeyerl  *	originally from /sys/kern/tty_compat.c
358e41ca80Shpeyerl  */
368e41ca80Shpeyerl 
378e41ca80Shpeyerl #include <sys/param.h>
388e41ca80Shpeyerl #include <sys/types.h>
398e41ca80Shpeyerl 
408e41ca80Shpeyerl #include <unistd.h>
418e41ca80Shpeyerl #include <sys/ioctl_compat.h>
428e41ca80Shpeyerl #include <termios.h>
438e41ca80Shpeyerl #include <syslog.h>
448e41ca80Shpeyerl #include <fcntl.h>
458e41ca80Shpeyerl #include <dirent.h>
468e41ca80Shpeyerl #include <errno.h>
478e41ca80Shpeyerl #include <stdio.h>
488e41ca80Shpeyerl #include <string.h>
498e41ca80Shpeyerl #include <stdlib.h>
508e41ca80Shpeyerl #include "extern.h"
518e41ca80Shpeyerl 
52780c7fbeSmycroft /* Macros to clear/set/test flags. */
53780c7fbeSmycroft #define	SET(t, f)	(t) |= (f)
54780c7fbeSmycroft #define	CLR(t, f)	(t) &= ~(f)
55780c7fbeSmycroft #define	ISSET(t, f)	((t) & (f))
56780c7fbeSmycroft 
57895dc72aSwiz static int	sttygetoflags(struct termios *);
58895dc72aSwiz static void	sttysetoflags(struct termios *, int);
59fe7ed7ceSmrg 
602347ccbaSmycroft static int
sttygetoflags(struct termios * tp)61895dc72aSwiz sttygetoflags(struct termios *tp)
622347ccbaSmycroft {
63fe7ed7ceSmrg 	tcflag_t iflag = tp->c_iflag;
64fe7ed7ceSmrg 	tcflag_t lflag = tp->c_lflag;
65fe7ed7ceSmrg 	tcflag_t oflag = tp->c_oflag;
66fe7ed7ceSmrg 	tcflag_t cflag = tp->c_cflag;
67fe7ed7ceSmrg 	int flags = 0;
682347ccbaSmycroft 
692347ccbaSmycroft 	if (ISSET(cflag, PARENB)) {
702347ccbaSmycroft 		if (ISSET(iflag, INPCK)) {
712347ccbaSmycroft 			if (ISSET(cflag, PARODD))
722347ccbaSmycroft 				SET(flags, ODDP);
732347ccbaSmycroft 			else
742347ccbaSmycroft 				SET(flags, EVENP);
752347ccbaSmycroft 		} else
762347ccbaSmycroft 			SET(flags, EVENP|ODDP);
772347ccbaSmycroft 	}
782347ccbaSmycroft 	if (ISSET(cflag, CSIZE) == CS8) {
792347ccbaSmycroft 		if (!ISSET(iflag, ISTRIP))
802347ccbaSmycroft 			SET(flags, PASS8);
812347ccbaSmycroft 		if (!ISSET(oflag, OPOST))
822347ccbaSmycroft 			SET(flags, LITOUT);
832347ccbaSmycroft 	}
842347ccbaSmycroft 
852347ccbaSmycroft 	if (!ISSET(lflag, ICANON)) {
862347ccbaSmycroft 		/* fudge */
872347ccbaSmycroft 		if (ISSET(iflag, IXON) || ISSET(lflag, ISIG|IEXTEN) ||
882347ccbaSmycroft 		    ISSET(cflag, PARENB))
892347ccbaSmycroft 			SET(flags, CBREAK);
902347ccbaSmycroft 		else
912347ccbaSmycroft 			SET(flags, RAW);
922347ccbaSmycroft 	}
932347ccbaSmycroft 
942347ccbaSmycroft 	return (flags);
952347ccbaSmycroft }
962347ccbaSmycroft 
972347ccbaSmycroft static void
sttysetoflags(struct termios * tp,int flags)98895dc72aSwiz sttysetoflags(struct termios *tp, int flags)
992347ccbaSmycroft {
100fe7ed7ceSmrg 	tcflag_t iflag = tp->c_iflag;
101fe7ed7ceSmrg 	tcflag_t oflag = tp->c_oflag;
102fe7ed7ceSmrg 	tcflag_t lflag = tp->c_lflag;
103fe7ed7ceSmrg 	tcflag_t cflag = tp->c_cflag;
1042347ccbaSmycroft 
10549d5e896Smycroft 	if (ISSET(flags, RAW)) {
10649d5e896Smycroft 		iflag &= IXOFF;
10749d5e896Smycroft 		CLR(lflag, ISIG|ICANON|IEXTEN);
10849d5e896Smycroft 		CLR(cflag, PARENB);
10949d5e896Smycroft 	} else {
11049d5e896Smycroft 		SET(iflag, BRKINT|IXON|IMAXBEL);
11149d5e896Smycroft 		SET(lflag, ISIG|IEXTEN);
11249d5e896Smycroft 		if (ISSET(flags, CBREAK))
11349d5e896Smycroft 			CLR(lflag, ICANON);
11449d5e896Smycroft 		else
11549d5e896Smycroft 			SET(lflag, ICANON);
1162347ccbaSmycroft 		switch (ISSET(flags, ANYP)) {
11749d5e896Smycroft 		case 0:
11849d5e896Smycroft 			CLR(cflag, PARENB);
11949d5e896Smycroft 			break;
12049d5e896Smycroft 		case ANYP:
12149d5e896Smycroft 			SET(cflag, PARENB);
12249d5e896Smycroft 			CLR(iflag, INPCK);
12349d5e896Smycroft 			break;
1242347ccbaSmycroft 		case EVENP:
12549d5e896Smycroft 			SET(cflag, PARENB);
1262347ccbaSmycroft 			SET(iflag, INPCK);
1272347ccbaSmycroft 			CLR(cflag, PARODD);
1282347ccbaSmycroft 			break;
1292347ccbaSmycroft 		case ODDP:
13049d5e896Smycroft 			SET(cflag, PARENB);
1312347ccbaSmycroft 			SET(iflag, INPCK);
1322347ccbaSmycroft 			SET(cflag, PARODD);
1332347ccbaSmycroft 			break;
13449d5e896Smycroft 		}
1352347ccbaSmycroft 	}
1362347ccbaSmycroft 
1372347ccbaSmycroft 	if (ISSET(flags, RAW|LITOUT|PASS8)) {
13849d5e896Smycroft 		CLR(cflag, CSIZE);
1392347ccbaSmycroft 		SET(cflag, CS8);
1402347ccbaSmycroft 		if (!ISSET(flags, RAW|PASS8))
1412347ccbaSmycroft 			SET(iflag, ISTRIP);
1422347ccbaSmycroft 		else
1432347ccbaSmycroft 			CLR(iflag, ISTRIP);
1442347ccbaSmycroft 		if (!ISSET(flags, RAW|LITOUT))
1452347ccbaSmycroft 			SET(oflag, OPOST);
1462347ccbaSmycroft 		else
1472347ccbaSmycroft 			CLR(oflag, OPOST);
1482347ccbaSmycroft 	} else {
1492347ccbaSmycroft 		CLR(cflag, CSIZE);
15049d5e896Smycroft 		SET(cflag, CS7);
1512347ccbaSmycroft 		SET(iflag, ISTRIP);
1522347ccbaSmycroft 		SET(oflag, OPOST);
1532347ccbaSmycroft 	}
1542347ccbaSmycroft 
1552347ccbaSmycroft 	tp->c_iflag = iflag;
1562347ccbaSmycroft 	tp->c_oflag = oflag;
1572347ccbaSmycroft 	tp->c_lflag = lflag;
1582347ccbaSmycroft 	tp->c_cflag = cflag;
1592347ccbaSmycroft }
1602347ccbaSmycroft 
1618e41ca80Shpeyerl void
sttyclearflags(struct termios * tp,int flags)162895dc72aSwiz sttyclearflags(struct termios *tp, int flags)
1638e41ca80Shpeyerl {
164fe7ed7ceSmrg 	tcflag_t iflag = tp->c_iflag;
165fe7ed7ceSmrg 	tcflag_t oflag = tp->c_oflag;
166fe7ed7ceSmrg 	tcflag_t lflag = tp->c_lflag;
167fe7ed7ceSmrg 	tcflag_t cflag = tp->c_cflag;
168fe7ed7ceSmrg 	int oflags = sttygetoflags(tp) & ~flags;
1698e41ca80Shpeyerl 
170780c7fbeSmycroft 	if (ISSET(flags, TANDEM))
171780c7fbeSmycroft 		CLR(iflag, IXOFF);
172780c7fbeSmycroft 	if (ISSET(flags, ECHO))
173780c7fbeSmycroft 		CLR(lflag, ECHO);
174780c7fbeSmycroft 	if (ISSET(flags, CRMOD)) {
175780c7fbeSmycroft 		CLR(iflag, ICRNL);
176780c7fbeSmycroft 		CLR(oflag, ONLCR);
1778e41ca80Shpeyerl 	}
178780c7fbeSmycroft 	if (ISSET(flags, XTABS))
179780c7fbeSmycroft 		CLR(oflag, OXTABS);
1808e41ca80Shpeyerl 
1818e41ca80Shpeyerl 
1828e41ca80Shpeyerl 	tp->c_iflag = iflag;
1838e41ca80Shpeyerl 	tp->c_oflag = oflag;
1848e41ca80Shpeyerl 	tp->c_lflag = lflag;
1858e41ca80Shpeyerl 	tp->c_cflag = cflag;
1862347ccbaSmycroft 
1872347ccbaSmycroft 	sttysetoflags(tp, oflags);
1888e41ca80Shpeyerl }
1898e41ca80Shpeyerl 
1908e41ca80Shpeyerl void
sttysetflags(struct termios * tp,int flags)191895dc72aSwiz sttysetflags(struct termios *tp, int flags)
1928e41ca80Shpeyerl {
193fe7ed7ceSmrg 	tcflag_t iflag = tp->c_iflag;
194fe7ed7ceSmrg 	tcflag_t oflag = tp->c_oflag;
195fe7ed7ceSmrg 	tcflag_t lflag = tp->c_lflag;
196fe7ed7ceSmrg 	tcflag_t cflag = tp->c_cflag;
197fe7ed7ceSmrg 	int oflags = sttygetoflags(tp) | flags;
1988e41ca80Shpeyerl 
199780c7fbeSmycroft 	if (ISSET(flags, TANDEM))
200780c7fbeSmycroft 		SET(iflag, IXOFF);
201780c7fbeSmycroft 	if (ISSET(flags, ECHO))
202780c7fbeSmycroft 		SET(lflag, ECHO);
203780c7fbeSmycroft 	if (ISSET(flags, CRMOD)) {
204780c7fbeSmycroft 		SET(iflag, ICRNL);
205780c7fbeSmycroft 		SET(oflag, ONLCR);
2068e41ca80Shpeyerl 	}
207780c7fbeSmycroft 	if (ISSET(flags, XTABS))
208780c7fbeSmycroft 		SET(oflag, OXTABS);
2098e41ca80Shpeyerl 
2108e41ca80Shpeyerl 	tp->c_iflag = iflag;
2118e41ca80Shpeyerl 	tp->c_oflag = oflag;
2128e41ca80Shpeyerl 	tp->c_lflag = lflag;
2138e41ca80Shpeyerl 	tp->c_cflag = cflag;
2142347ccbaSmycroft 
2152347ccbaSmycroft 	sttysetoflags(tp, oflags);
2168e41ca80Shpeyerl }
2178e41ca80Shpeyerl 
2188e41ca80Shpeyerl void
sttyclearlflags(struct termios * tp,int flags)219895dc72aSwiz sttyclearlflags(struct termios *tp, int flags)
2208e41ca80Shpeyerl {
221fe7ed7ceSmrg 	tcflag_t iflag = tp->c_iflag;
222fe7ed7ceSmrg 	tcflag_t oflag = tp->c_oflag;
223fe7ed7ceSmrg 	tcflag_t lflag = tp->c_lflag;
224fe7ed7ceSmrg 	tcflag_t cflag = tp->c_cflag;
225fe7ed7ceSmrg 	int oflags = sttygetoflags(tp) & ~flags;
2268e41ca80Shpeyerl 
2278e41ca80Shpeyerl 	/* Nothing we can do with CRTBS. */
228780c7fbeSmycroft 	if (ISSET(flags, PRTERA))
229780c7fbeSmycroft 		CLR(lflag, ECHOPRT);
230780c7fbeSmycroft 	if (ISSET(flags, CRTERA))
231780c7fbeSmycroft 		CLR(lflag, ECHOE);
2328e41ca80Shpeyerl 	/* Nothing we can do with TILDE. */
233780c7fbeSmycroft 	if (ISSET(flags, MDMBUF))
234780c7fbeSmycroft 		CLR(cflag, MDMBUF);
235780c7fbeSmycroft 	if (ISSET(flags, NOHANG))
236780c7fbeSmycroft 		SET(cflag, HUPCL);
237780c7fbeSmycroft 	if (ISSET(flags, CRTKIL))
238780c7fbeSmycroft 		CLR(lflag, ECHOKE);
239780c7fbeSmycroft 	if (ISSET(flags, CTLECH))
240780c7fbeSmycroft 		CLR(lflag, ECHOCTL);
241fde6ad08Smycroft 	if (ISSET(flags, DECCTQ))
242fde6ad08Smycroft 		SET(iflag, IXANY);
243780c7fbeSmycroft 	CLR(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
2448e41ca80Shpeyerl 
2458e41ca80Shpeyerl 	tp->c_iflag = iflag;
2468e41ca80Shpeyerl 	tp->c_oflag = oflag;
2478e41ca80Shpeyerl 	tp->c_lflag = lflag;
2488e41ca80Shpeyerl 	tp->c_cflag = cflag;
2492347ccbaSmycroft 
2502347ccbaSmycroft 	sttysetoflags(tp, oflags);
2518e41ca80Shpeyerl }
2528e41ca80Shpeyerl 
2538e41ca80Shpeyerl void
sttysetlflags(struct termios * tp,int flags)254895dc72aSwiz sttysetlflags(struct termios *tp, int flags)
2558e41ca80Shpeyerl {
256fe7ed7ceSmrg 	tcflag_t iflag = tp->c_iflag;
257fe7ed7ceSmrg 	tcflag_t oflag = tp->c_oflag;
258fe7ed7ceSmrg 	tcflag_t lflag = tp->c_lflag;
259fe7ed7ceSmrg 	tcflag_t cflag = tp->c_cflag;
260fe7ed7ceSmrg 	int oflags = sttygetoflags(tp) | flags;
2618e41ca80Shpeyerl 
2628e41ca80Shpeyerl 	/* Nothing we can do with CRTBS. */
263780c7fbeSmycroft 	if (ISSET(flags, PRTERA))
264780c7fbeSmycroft 		SET(lflag, ECHOPRT);
265780c7fbeSmycroft 	if (ISSET(flags, CRTERA))
266780c7fbeSmycroft 		SET(lflag, ECHOE);
2678e41ca80Shpeyerl 	/* Nothing we can do with TILDE. */
268780c7fbeSmycroft 	if (ISSET(flags, MDMBUF))
269780c7fbeSmycroft 		SET(cflag, MDMBUF);
270780c7fbeSmycroft 	if (ISSET(flags, NOHANG))
271780c7fbeSmycroft 		CLR(cflag, HUPCL);
272780c7fbeSmycroft 	if (ISSET(flags, CRTKIL))
273780c7fbeSmycroft 		SET(lflag, ECHOKE);
274780c7fbeSmycroft 	if (ISSET(flags, CTLECH))
275780c7fbeSmycroft 		SET(lflag, ECHOCTL);
276fde6ad08Smycroft 	if (ISSET(flags, DECCTQ))
277fde6ad08Smycroft 		CLR(iflag, IXANY);
278780c7fbeSmycroft 	SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
2798e41ca80Shpeyerl 
2808e41ca80Shpeyerl 	tp->c_iflag = iflag;
2818e41ca80Shpeyerl 	tp->c_oflag = oflag;
2828e41ca80Shpeyerl 	tp->c_lflag = lflag;
2838e41ca80Shpeyerl 	tp->c_cflag = cflag;
2842347ccbaSmycroft 
2852347ccbaSmycroft 	sttysetoflags(tp, oflags);
2868e41ca80Shpeyerl }
287