xref: /netbsd-src/sys/compat/common/tty_43.c (revision 481fca6e59249d8ffcf24fef7cfbe7b131bfb080)
1 /*	$NetBSD: tty_43.c,v 1.10 2000/03/30 11:27:14 augustss Exp $	*/
2 
3 /*-
4  * Copyright (c) 1982, 1986, 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
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. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)tty_compat.c	8.2 (Berkeley) 1/9/95
36  */
37 
38 /*
39  * mapping routines for old line discipline (yuck)
40  */
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/ioctl.h>
44 #include <sys/proc.h>
45 #include <sys/tty.h>
46 #include <sys/termios.h>
47 #include <sys/file.h>
48 #include <sys/kernel.h>
49 #include <sys/syslog.h>
50 #include <sys/ioctl_compat.h>
51 
52 /*
53  * XXX libcompat files should be included with config attributes
54  */
55 #ifdef COMPAT_OLDTTY
56 
57 int ttydebug = 0;
58 
59 static struct speedtab compatspeeds[] = {
60 #define MAX_SPEED	17
61 	{ 115200, 17 },
62 	{ 57600, 16 },
63 	{ 38400, 15 },
64 	{ 19200, 14 },
65 	{ 9600,	13 },
66 	{ 4800,	12 },
67 	{ 2400,	11 },
68 	{ 1800,	10 },
69 	{ 1200,	9 },
70 	{ 600,	8 },
71 	{ 300,	7 },
72 	{ 200,	6 },
73 	{ 150,	5 },
74 	{ 134,	4 },
75 	{ 110,	3 },
76 	{ 75,	2 },
77 	{ 50,	1 },
78 	{ 0,	0 },
79 	{ -1,	-1 },
80 };
81 static int compatspcodes[] = {
82 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
83 	1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200
84 };
85 
86 /* Macros to clear/set/test flags. */
87 #define	SET(t, f)	(t) |= (f)
88 #define	CLR(t, f)	(t) &= ~(f)
89 #define	ISSET(t, f)	((t) & (f))
90 
91 int ttcompatgetflags __P((struct tty *));
92 void ttcompatsetflags __P((struct tty *, struct termios *));
93 void ttcompatsetlflags __P((struct tty *, struct termios *));
94 
95 /*ARGSUSED*/
96 int
97 ttcompat(tp, com, data, flag, p)
98 	struct tty *tp;
99 	u_long com;
100 	caddr_t data;
101 	int flag;
102 	struct proc *p;
103 {
104 
105 	switch (com) {
106 	case TIOCGETP: {
107 		struct sgttyb *sg = (struct sgttyb *)data;
108 		u_char *cc = tp->t_cc;
109 		int speed;
110 
111 		speed = ttspeedtab(tp->t_ospeed, compatspeeds);
112 		sg->sg_ospeed = (speed == -1) ? MAX_SPEED : speed;
113 		if (tp->t_ispeed == 0)
114 			sg->sg_ispeed = sg->sg_ospeed;
115 		else {
116 			speed = ttspeedtab(tp->t_ispeed, compatspeeds);
117 			sg->sg_ispeed = (speed == -1) ? MAX_SPEED : speed;
118 		}
119 		sg->sg_erase = cc[VERASE];
120 		sg->sg_kill = cc[VKILL];
121 		sg->sg_flags = ttcompatgetflags(tp);
122 		break;
123 	}
124 
125 	case TIOCSETP:
126 	case TIOCSETN: {
127 		struct sgttyb *sg = (struct sgttyb *)data;
128 		struct termios term;
129 		int speed;
130 
131 		term = tp->t_termios;
132 		if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0)
133 			term.c_ispeed = speed;
134 		else
135 			term.c_ispeed = compatspcodes[speed];
136 		if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0)
137 			term.c_ospeed = speed;
138 		else
139 			term.c_ospeed = compatspcodes[speed];
140 		term.c_cc[VERASE] = sg->sg_erase;
141 		term.c_cc[VKILL] = sg->sg_kill;
142 		tp->t_flags = (ttcompatgetflags(tp)&0xffff0000) | (sg->sg_flags&0xffff);
143 		ttcompatsetflags(tp, &term);
144 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
145 			(caddr_t)&term, flag, p));
146 	}
147 
148 	case TIOCGETC: {
149 		struct tchars *tc = (struct tchars *)data;
150 		u_char *cc = tp->t_cc;
151 
152 		tc->t_intrc = cc[VINTR];
153 		tc->t_quitc = cc[VQUIT];
154 		tc->t_startc = cc[VSTART];
155 		tc->t_stopc = cc[VSTOP];
156 		tc->t_eofc = cc[VEOF];
157 		tc->t_brkc = cc[VEOL];
158 		break;
159 	}
160 	case TIOCSETC: {
161 		struct tchars *tc = (struct tchars *)data;
162 		u_char *cc = tp->t_cc;
163 
164 		cc[VINTR] = tc->t_intrc;
165 		cc[VQUIT] = tc->t_quitc;
166 		cc[VSTART] = tc->t_startc;
167 		cc[VSTOP] = tc->t_stopc;
168 		cc[VEOF] = tc->t_eofc;
169 		cc[VEOL] = tc->t_brkc;
170 		if (tc->t_brkc == (char)-1)
171 			cc[VEOL2] = _POSIX_VDISABLE;
172 		break;
173 	}
174 	case TIOCSLTC: {
175 		struct ltchars *ltc = (struct ltchars *)data;
176 		u_char *cc = tp->t_cc;
177 
178 		cc[VSUSP] = ltc->t_suspc;
179 		cc[VDSUSP] = ltc->t_dsuspc;
180 		cc[VREPRINT] = ltc->t_rprntc;
181 		cc[VDISCARD] = ltc->t_flushc;
182 		cc[VWERASE] = ltc->t_werasc;
183 		cc[VLNEXT] = ltc->t_lnextc;
184 		break;
185 	}
186 	case TIOCGLTC: {
187 		struct ltchars *ltc = (struct ltchars *)data;
188 		u_char *cc = tp->t_cc;
189 
190 		ltc->t_suspc = cc[VSUSP];
191 		ltc->t_dsuspc = cc[VDSUSP];
192 		ltc->t_rprntc = cc[VREPRINT];
193 		ltc->t_flushc = cc[VDISCARD];
194 		ltc->t_werasc = cc[VWERASE];
195 		ltc->t_lnextc = cc[VLNEXT];
196 		break;
197 	}
198 	case TIOCLBIS:
199 	case TIOCLBIC:
200 	case TIOCLSET: {
201 		struct termios term;
202 		int flags;
203 
204 		term = tp->t_termios;
205 		flags = ttcompatgetflags(tp);
206 		switch (com) {
207 		case TIOCLSET:
208 			tp->t_flags = (flags&0xffff) | (*(int *)data<<16);
209 			break;
210 		case TIOCLBIS:
211 			tp->t_flags = flags | (*(int *)data<<16);
212 			break;
213 		case TIOCLBIC:
214 			tp->t_flags = flags & ~(*(int *)data<<16);
215 			break;
216 		}
217 		ttcompatsetlflags(tp, &term);
218 		return (ttioctl(tp, TIOCSETA, (caddr_t)&term, flag, p));
219 	}
220 	case TIOCLGET:
221 		*(int *)data = ttcompatgetflags(tp)>>16;
222 		if (ttydebug)
223 			printf("CLGET: returning %x\n", *(int *)data);
224 		break;
225 
226 	case OTIOCGETD:
227 		*(int *)data = tp->t_line ? tp->t_line : 2;
228 		break;
229 
230 	case OTIOCSETD: {
231 		int ldisczero = 0;
232 
233 		return (ttioctl(tp, TIOCSETD,
234 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag,
235 			p));
236 	    }
237 
238 	case OTIOCCONS:
239 		*(int *)data = 1;
240 		return (ttioctl(tp, TIOCCONS, data, flag, p));
241 
242 	case TIOCHPCL:
243 		SET(tp->t_cflag, HUPCL);
244 		break;
245 
246 	case TIOCGSID:
247 		if (tp->t_session == NULL)
248 			return ENOTTY;
249 
250 		if (tp->t_session->s_leader == NULL)
251 			return ENOTTY;
252 
253 		*(int *) data =  tp->t_session->s_leader->p_pid;
254 		break;
255 
256 	default:
257 		return (-1);
258 	}
259 	return (0);
260 }
261 
262 int
263 ttcompatgetflags(tp)
264 	struct tty *tp;
265 {
266 	tcflag_t iflag = tp->t_iflag;
267 	tcflag_t lflag = tp->t_lflag;
268 	tcflag_t oflag = tp->t_oflag;
269 	tcflag_t cflag = tp->t_cflag;
270 	int flags = 0;
271 
272 	if (ISSET(iflag, IXOFF))
273 		SET(flags, TANDEM);
274 	if (ISSET(iflag, ICRNL) || ISSET(oflag, ONLCR))
275 		SET(flags, CRMOD);
276 	if (ISSET(cflag, PARENB)) {
277 		if (ISSET(iflag, INPCK)) {
278 			if (ISSET(cflag, PARODD))
279 				SET(flags, ODDP);
280 			else
281 				SET(flags, EVENP);
282 		} else
283 			SET(flags, ANYP);
284 	}
285 
286 	if (!ISSET(lflag, ICANON)) {
287 		/* fudge */
288 		if (ISSET(iflag, IXON) || ISSET(lflag, ISIG|IEXTEN) ||
289 		    ISSET(cflag, PARENB))
290 			SET(flags, CBREAK);
291 		else
292 			SET(flags, RAW);
293 	}
294 
295 	if (ISSET(flags, RAW))
296 		SET(flags, ISSET(tp->t_flags, LITOUT|PASS8));
297 	else if (ISSET(cflag, CSIZE) == CS8) {
298 		if (!ISSET(oflag, OPOST))
299 			SET(flags, LITOUT);
300 		if (!ISSET(iflag, ISTRIP))
301 			SET(flags, PASS8);
302 	}
303 
304 	if (ISSET(cflag, MDMBUF))
305 		SET(flags, MDMBUF);
306 	if (!ISSET(cflag, HUPCL))
307 		SET(flags, NOHANG);
308 	if (ISSET(oflag, OXTABS))
309 		SET(flags, XTABS);
310 	if (ISSET(lflag, ECHOE))
311 		SET(flags, CRTERA|CRTBS);
312 	if (ISSET(lflag, ECHOKE))
313 		SET(flags, CRTKIL|CRTBS);
314 	if (ISSET(lflag, ECHOPRT))
315 		SET(flags, PRTERA);
316 	if (ISSET(lflag, ECHOCTL))
317 		SET(flags, CTLECH);
318 	if (!ISSET(iflag, IXANY))
319 		SET(flags, DECCTQ);
320 	SET(flags, ISSET(lflag, ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH));
321 	if (ttydebug)
322 		printf("getflags: %x\n", flags);
323 	return (flags);
324 }
325 
326 void
327 ttcompatsetflags(tp, t)
328 	struct tty *tp;
329 	struct termios *t;
330 {
331 	int flags = tp->t_flags;
332 	tcflag_t iflag = t->c_iflag;
333 	tcflag_t oflag = t->c_oflag;
334 	tcflag_t lflag = t->c_lflag;
335 	tcflag_t cflag = t->c_cflag;
336 
337 	if (ISSET(flags, TANDEM))
338 		SET(iflag, IXOFF);
339 	else
340 		CLR(iflag, IXOFF);
341 	if (ISSET(flags, ECHO))
342 		SET(lflag, ECHO);
343 	else
344 		CLR(lflag, ECHO);
345 	if (ISSET(flags, CRMOD)) {
346 		SET(iflag, ICRNL);
347 		SET(oflag, ONLCR);
348 	} else {
349 		CLR(iflag, ICRNL);
350 		CLR(oflag, ONLCR);
351 	}
352 	if (ISSET(flags, XTABS))
353 		SET(oflag, OXTABS);
354 	else
355 		CLR(oflag, OXTABS);
356 
357 
358 	if (ISSET(flags, RAW)) {
359 		iflag &= IXOFF;
360 		CLR(lflag, ISIG|ICANON|IEXTEN);
361 		CLR(cflag, PARENB);
362 	} else {
363 		SET(iflag, BRKINT|IXON|IMAXBEL);
364 		SET(lflag, ISIG|IEXTEN);
365 		if (ISSET(flags, CBREAK))
366 			CLR(lflag, ICANON);
367 		else
368 			SET(lflag, ICANON);
369 		switch (ISSET(flags, ANYP)) {
370 		case 0:
371 			CLR(cflag, PARENB);
372 			break;
373 		case ANYP:
374 			SET(cflag, PARENB);
375 			CLR(iflag, INPCK);
376 			break;
377 		case EVENP:
378 			SET(cflag, PARENB);
379 			SET(iflag, INPCK);
380 			CLR(cflag, PARODD);
381 			break;
382 		case ODDP:
383 			SET(cflag, PARENB);
384 			SET(iflag, INPCK);
385 			SET(cflag, PARODD);
386 			break;
387 		}
388 	}
389 
390 	if (ISSET(flags, RAW|LITOUT|PASS8)) {
391 		CLR(cflag, CSIZE);
392 		SET(cflag, CS8);
393 		if (!ISSET(flags, RAW|PASS8))
394 			SET(iflag, ISTRIP);
395 		else
396 			CLR(iflag, ISTRIP);
397 		if (!ISSET(flags, RAW|LITOUT))
398 			SET(oflag, OPOST);
399 		else
400 			CLR(oflag, OPOST);
401 	} else {
402 		CLR(cflag, CSIZE);
403 		SET(cflag, CS7);
404 		SET(iflag, ISTRIP);
405 		SET(oflag, OPOST);
406 	}
407 
408 	t->c_iflag = iflag;
409 	t->c_oflag = oflag;
410 	t->c_lflag = lflag;
411 	t->c_cflag = cflag;
412 }
413 
414 void
415 ttcompatsetlflags(tp, t)
416 	struct tty *tp;
417 	struct termios *t;
418 {
419 	int flags = tp->t_flags;
420 	tcflag_t iflag = t->c_iflag;
421 	tcflag_t oflag = t->c_oflag;
422 	tcflag_t lflag = t->c_lflag;
423 	tcflag_t cflag = t->c_cflag;
424 
425 	/* Nothing we can do with CRTBS. */
426 	if (ISSET(flags, PRTERA))
427 		SET(lflag, ECHOPRT);
428 	else
429 		CLR(lflag, ECHOPRT);
430 	if (ISSET(flags, CRTERA))
431 		SET(lflag, ECHOE);
432 	else
433 		CLR(lflag, ECHOE);
434 	/* Nothing we can do with TILDE. */
435 	if (ISSET(flags, MDMBUF))
436 		SET(cflag, MDMBUF);
437 	else
438 		CLR(cflag, MDMBUF);
439 	if (ISSET(flags, NOHANG))
440 		CLR(cflag, HUPCL);
441 	else
442 		SET(cflag, HUPCL);
443 	if (ISSET(flags, CRTKIL))
444 		SET(lflag, ECHOKE);
445 	else
446 		CLR(lflag, ECHOKE);
447 	if (ISSET(flags, CTLECH))
448 		SET(lflag, ECHOCTL);
449 	else
450 		CLR(lflag, ECHOCTL);
451 	if (!ISSET(flags, DECCTQ))
452 		SET(iflag, IXANY);
453 	else
454 		CLR(iflag, IXANY);
455 	CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
456 	SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
457 
458 	if (ISSET(flags, RAW|LITOUT|PASS8)) {
459 		CLR(cflag, CSIZE);
460 		SET(cflag, CS8);
461 		if (!ISSET(flags, RAW|PASS8))
462 			SET(iflag, ISTRIP);
463 		else
464 			CLR(iflag, ISTRIP);
465 		if (!ISSET(flags, RAW|LITOUT))
466 			SET(oflag, OPOST);
467 		else
468 			CLR(oflag, OPOST);
469 	} else {
470 		CLR(cflag, CSIZE);
471 		SET(cflag, CS7);
472 		SET(iflag, ISTRIP);
473 		SET(oflag, OPOST);
474 	}
475 
476 	t->c_iflag = iflag;
477 	t->c_oflag = oflag;
478 	t->c_lflag = lflag;
479 	t->c_cflag = cflag;
480 }
481 
482 #endif /* COMPAT_OLDTTY */
483