Home | History | Annotate | Line # | Download | only in lpd
      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
     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
     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
    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
    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
    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
    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