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