xref: /original-bsd/sys/kern/tty_compat.c (revision 75965087)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)tty_compat.c	7.9 (Berkeley) 04/20/91
7  */
8 
9 /*
10  * mapping routines for old line discipline (yuck)
11  */
12 #ifdef COMPAT_43
13 
14 #include "param.h"
15 #include "systm.h"
16 #include "ioctl.h"
17 #include "tty.h"
18 #include "termios.h"
19 #include "proc.h"
20 #include "file.h"
21 #include "conf.h"
22 #include "dkstat.h"
23 #include "kernel.h"
24 #include "syslog.h"
25 
26 int ttydebug = 0;
27 
28 static struct speedtab compatspeeds[] = {
29 	38400,	15,
30 	19200,	14,
31 	9600,	13,
32 	4800,	12,
33 	2400,	11,
34 	1800,	10,
35 	1200,	9,
36 	600,	8,
37 	300,	7,
38 	200,	6,
39 	150,	5,
40 	134,	4,
41 	110,	3,
42 	75,	2,
43 	50,	1,
44 	0,	0,
45 	-1,	-1,
46 };
47 static int compatspcodes[16] = {
48 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
49 	1800, 2400, 4800, 9600, 19200, 38400,
50 };
51 
52 /*ARGSUSED*/
53 ttcompat(tp, com, data, flag)
54 	register struct tty *tp;
55 	caddr_t data;
56 {
57 
58 	switch (com) {
59 	case TIOCGETP: {
60 		register struct sgttyb *sg = (struct sgttyb *)data;
61 		register u_char *cc = tp->t_cc;
62 		register speed;
63 
64 		speed = ttspeedtab(tp->t_ospeed, compatspeeds);
65 		sg->sg_ospeed = (speed == -1) ? 15 : speed;
66 		if (tp->t_ispeed == 0)
67 			sg->sg_ispeed = sg->sg_ospeed;
68 		else {
69 			speed = ttspeedtab(tp->t_ispeed, compatspeeds);
70 			sg->sg_ispeed = (speed == -1) ? 15 : speed;
71 		}
72 		sg->sg_erase = cc[VERASE];
73 		sg->sg_kill = cc[VKILL];
74 		sg->sg_flags = ttcompatgetflags(tp);
75 		break;
76 	}
77 
78 	case TIOCSETP:
79 	case TIOCSETN: {
80 		register struct sgttyb *sg = (struct sgttyb *)data;
81 		struct termios term;
82 		int speed;
83 
84 		term = tp->t_termios;
85 		if ((speed = sg->sg_ispeed) > 15 || speed < 0)
86 			term.c_ispeed = speed;
87 		else
88 			term.c_ispeed = compatspcodes[speed];
89 		if ((speed = sg->sg_ospeed) > 15 || speed < 0)
90 			term.c_ospeed = speed;
91 		else
92 			term.c_ospeed = compatspcodes[speed];
93 		term.c_cc[VERASE] = sg->sg_erase;
94 		term.c_cc[VKILL] = sg->sg_kill;
95 		tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff;
96 		ttcompatsetflags(tp, &term);
97 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
98 			&term, flag));
99 	}
100 
101 	case TIOCGETC: {
102 		struct tchars *tc = (struct tchars *)data;
103 		register u_char *cc = tp->t_cc;
104 
105 		tc->t_intrc = cc[VINTR];
106 		tc->t_quitc = cc[VQUIT];
107 		tc->t_startc = cc[VSTART];
108 		tc->t_stopc = cc[VSTOP];
109 		tc->t_eofc = cc[VEOF];
110 		tc->t_brkc = cc[VEOL];
111 		break;
112 	}
113 	case TIOCSETC: {
114 		struct tchars *tc = (struct tchars *)data;
115 		register u_char *cc = tp->t_cc;
116 
117 		cc[VINTR] = tc->t_intrc;
118 		cc[VQUIT] = tc->t_quitc;
119 		cc[VSTART] = tc->t_startc;
120 		cc[VSTOP] = tc->t_stopc;
121 		cc[VEOF] = tc->t_eofc;
122 		cc[VEOL] = tc->t_brkc;
123 		if (tc->t_brkc == -1)
124 			cc[VEOL2] = _POSIX_VDISABLE;
125 		break;
126 	}
127 	case TIOCSLTC: {
128 		struct ltchars *ltc = (struct ltchars *)data;
129 		register u_char *cc = tp->t_cc;
130 
131 		cc[VSUSP] = ltc->t_suspc;
132 		cc[VDSUSP] = ltc->t_dsuspc;
133 		cc[VREPRINT] = ltc->t_rprntc;
134 		cc[VDISCARD] = ltc->t_flushc;
135 		cc[VWERASE] = ltc->t_werasc;
136 		cc[VLNEXT] = ltc->t_lnextc;
137 		break;
138 	}
139 	case TIOCGLTC: {
140 		struct ltchars *ltc = (struct ltchars *)data;
141 		register u_char *cc = tp->t_cc;
142 
143 		ltc->t_suspc = cc[VSUSP];
144 		ltc->t_dsuspc = cc[VDSUSP];
145 		ltc->t_rprntc = cc[VREPRINT];
146 		ltc->t_flushc = cc[VDISCARD];
147 		ltc->t_werasc = cc[VWERASE];
148 		ltc->t_lnextc = cc[VLNEXT];
149 		break;
150 	}
151 	case TIOCLBIS:
152 	case TIOCLBIC:
153 	case TIOCLSET: {
154 		struct termios term;
155 
156 		term = tp->t_termios;
157 		if (com == TIOCLSET)
158 			tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
159 		else {
160 			tp->t_flags =
161 			 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
162 			if (com == TIOCLBIS)
163 				tp->t_flags |= *(int *)data<<16;
164 			else
165 				tp->t_flags &= ~(*(int *)data<<16);
166 		}
167 		ttcompatsetlflags(tp, &term);
168 		return (ttioctl(tp, TIOCSETA, &term, flag));
169 	}
170 	case TIOCLGET:
171 		*(int *)data = ttcompatgetflags(tp)>>16;
172 		if (ttydebug)
173 			printf("CLGET: returning %x\n", *(int *)data);
174 		break;
175 
176 	case OTIOCGETD:
177 		*(int *)data = tp->t_line ? tp->t_line : 2;
178 		break;
179 
180 	case OTIOCSETD: {
181 		int ldisczero = 0;
182 
183 		return (ttioctl(tp, TIOCSETD,
184 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
185 	    }
186 
187 	case OTIOCCONS:
188 		*(int *)data = 1;
189 		return (ttioctl(tp, TIOCCONS, data, flag));
190 
191 	default:
192 		return (-1);
193 	}
194 	return (0);
195 }
196 
197 ttcompatgetflags(tp)
198 	register struct tty *tp;
199 {
200 	register long iflag = tp->t_iflag;
201 	register long lflag = tp->t_lflag;
202 	register long oflag = tp->t_oflag;
203 	register long cflag = tp->t_cflag;
204 	register flags = 0;
205 
206 	if (iflag&IXOFF)
207 		flags |= TANDEM;
208 	if (iflag&ICRNL || oflag&ONLCR)
209 		flags |= CRMOD;
210 	if (cflag&PARENB) {
211 		if (iflag&INPCK) {
212 			if (cflag&PARODD)
213 				flags |= ODDP;
214 			else
215 				flags |= EVENP;
216 		} else
217 			flags |= EVENP | ODDP;
218 	} else {
219 		if ((tp->t_flags&LITOUT) && !(oflag&OPOST))
220 			flags |= LITOUT;
221 		if (tp->t_flags&PASS8)
222 			flags |= PASS8;
223 	}
224 
225 	if ((lflag&ICANON) == 0) {
226 		/* fudge */
227 		if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB)
228 			flags |= CBREAK;
229 		else
230 			flags |= RAW;
231 	}
232 	if (oflag&OXTABS)
233 		flags |= XTABS;
234 	if (lflag&ECHOE)
235 		flags |= CRTERA|CRTBS;
236 	if (lflag&ECHOKE)
237 		flags |= CRTKIL|CRTBS;
238 	if (lflag&ECHOPRT)
239 		flags |= PRTERA;
240 	if (lflag&ECHOCTL)
241 		flags |= CTLECH;
242 	if ((iflag&IXANY) == 0)
243 		flags |= DECCTQ;
244 	flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
245 if (ttydebug)
246 	printf("getflags: %x\n", flags);
247 	return (flags);
248 }
249 
250 ttcompatsetflags(tp, t)
251 	register struct tty *tp;
252 	register struct termios *t;
253 {
254 	register flags = tp->t_flags;
255 	register long iflag = t->c_iflag;
256 	register long oflag = t->c_oflag;
257 	register long lflag = t->c_lflag;
258 	register long cflag = t->c_cflag;
259 
260 	if (flags & RAW) {
261 		iflag &= IXOFF;
262 		oflag &= ~OPOST;
263 		lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
264 	} else {
265 		iflag |= BRKINT|IXON|IMAXBEL;
266 		oflag |= OPOST;
267 		lflag |= ISIG|IEXTEN|ECHOCTL;	/* XXX was echoctl on ? */
268 		if (flags & XTABS)
269 			oflag |= OXTABS;
270 		else
271 			oflag &= ~OXTABS;
272 		if (flags & CBREAK)
273 			lflag &= ~ICANON;
274 		else
275 			lflag |= ICANON;
276 		if (flags&CRMOD) {
277 			iflag |= ICRNL;
278 			oflag |= ONLCR;
279 		} else {
280 			iflag &= ~ICRNL;
281 			oflag &= ~ONLCR;
282 		}
283 	}
284 	if (flags&ECHO)
285 		lflag |= ECHO;
286 	else
287 		lflag &= ~ECHO;
288 
289 	if (flags&(RAW|LITOUT|PASS8)) {
290 		cflag &= ~(CSIZE|PARENB);
291 		cflag |= CS8;
292 		if ((flags&(RAW|PASS8)) == 0)
293 			iflag |= ISTRIP;
294 		else
295 			iflag &= ~ISTRIP;
296 	} else {
297 		cflag &= ~CSIZE;
298 		cflag |= CS7|PARENB;
299 		iflag |= ISTRIP;
300 	}
301 	if ((flags&(EVENP|ODDP)) == EVENP) {
302 		iflag |= INPCK;
303 		cflag &= ~PARODD;
304 	} else if ((flags&(EVENP|ODDP)) == ODDP) {
305 		iflag |= INPCK;
306 		cflag |= PARODD;
307 	} else
308 		iflag &= ~INPCK;
309 	if (flags&LITOUT)
310 		oflag &= ~OPOST;	/* move earlier ? */
311 	if (flags&TANDEM)
312 		iflag |= IXOFF;
313 	else
314 		iflag &= ~IXOFF;
315 	t->c_iflag = iflag;
316 	t->c_oflag = oflag;
317 	t->c_lflag = lflag;
318 	t->c_cflag = cflag;
319 }
320 
321 ttcompatsetlflags(tp, t)
322 	register struct tty *tp;
323 	register struct termios *t;
324 {
325 	register flags = tp->t_flags;
326 	register long iflag = t->c_iflag;
327 	register long oflag = t->c_oflag;
328 	register long lflag = t->c_lflag;
329 	register long cflag = t->c_cflag;
330 
331 	if (flags&CRTERA)
332 		lflag |= ECHOE;
333 	else
334 		lflag &= ~ECHOE;
335 	if (flags&CRTKIL)
336 		lflag |= ECHOKE;
337 	else
338 		lflag &= ~ECHOKE;
339 	if (flags&PRTERA)
340 		lflag |= ECHOPRT;
341 	else
342 		lflag &= ~ECHOPRT;
343 	if (flags&CTLECH)
344 		lflag |= ECHOCTL;
345 	else
346 		lflag &= ~ECHOCTL;
347 	if ((flags&DECCTQ) == 0)
348 		lflag |= IXANY;
349 	else
350 		lflag &= ~IXANY;
351 	lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
352 	lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
353 	if (flags&(LITOUT|PASS8)) {
354 		iflag &= ~ISTRIP;
355 		cflag &= ~(CSIZE|PARENB);
356 		cflag |= CS8;
357 		if (flags&LITOUT)
358 			oflag &= ~OPOST;
359 		if ((flags&(PASS8|RAW)) == 0)
360 			iflag |= ISTRIP;
361 	} else if ((flags&RAW) == 0) {
362 		cflag &= ~CSIZE;
363 		cflag |= CS7|PARENB;
364 		oflag |= OPOST;
365 	}
366 	t->c_iflag = iflag;
367 	t->c_oflag = oflag;
368 	t->c_lflag = lflag;
369 	t->c_cflag = cflag;
370 }
371 #endif	/* COMPAT_43 */
372