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