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