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