xref: /illumos-gate/usr/src/ucbcmd/stty/stty.c (revision 88f8b78a88cbdc6d8c1af5c3e54bc49d25095c98)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 
33 #include <stdio.h>
34 #include <ctype.h>
35 #include <sys/types.h>
36 #include <termio.h>
37 #include <sys/stermio.h>
38 #include <sys/termiox.h>
39 #include "stty.h"
40 
41 extern char *getenv();
42 extern void exit();
43 extern void perror();
44 
45 static char	*STTY="stty: ";
46 static char	*USAGE="usage: stty [-agh] [modes]\n";
47 static int	pitt = 0;
48 static struct termios cb;
49 static struct termio ocb; /* for non-streams devices */
50 static struct stio stio;
51 static struct termiox termiox;
52 static struct winsize winsize, owinsize;
53 static int term;
54 
55 void prmodes(int);
56 void pramodes(int);
57 void prachars(void);
58 void pcol(int, int);
59 void pit(unsigned char, char *, char *);
60 void delay(int, char *s);
61 void prspeed(char *, int);
62 void prencode(void);
63 
64 #define ioctl_desc	1
65 #define output		stderr
66 
67 int
68 main(int argc, char *argv[])
69 {
70 
71 	int i;
72 	char	*s_arg, *sttyparse();			/* s_arg: ptr to mode to be set */
73 	extern const struct	speeds	speeds[];
74 
75 	if (argc == 2) {
76 		/*
77 		 * "stty size", "stty speed" and "stty -g" are intended for
78 		 * use within backquotes; thus, they do the "fetch" "ioctl"
79 		 * from "/dev/tty" and always print their result on the
80 		 * standard output.
81 		 * Since their standard output is likely to be a pipe, they
82 		 * should not try to read the modes from the standard output.
83 		 */
84 		if (strcmp(argv[1], "size") == 0) {
85 			if ((i = open("/dev/tty", 0)) < 0) {
86 				perror("stty: Cannot open /dev/tty");
87 				exit(2);
88 			}
89 			if (ioctl(i, TIOCGWINSZ, &winsize) < 0) {
90 				perror("stty: TIOCGWINSZ");
91 				exit(2);
92 			}
93 			(void) printf("%d %d\n",winsize.ws_row,winsize.ws_col);
94 			exit(0);
95 		}
96 		else if (strcmp(argv[1], "speed") == 0) {
97 			if ((i = open("/dev/tty", 0)) < 0) {
98 				perror("stty: Cannot open /dev/tty");
99 				exit(2);
100 			}
101 			if((term = get_ttymode(i, &ocb, &cb, &stio, &termiox,
102 					&winsize)) < 0) {
103 				perror(STTY);
104 				exit(2);
105 			}
106 			if (term & TERMIOS) {
107 			    for(i=0; speeds[i].string; i++)
108 				if (cfgetospeed(&cb) == speeds[i].speed) {
109 					(void) printf("%s\n", speeds[i].string);
110 					exit(0);
111 				}
112 			} else {
113 			    for(i=0; speeds[i].string; i++)
114 				if ((cb.c_cflag&CBAUD) == speeds[i].speed) {
115 					(void) printf("%s\n", speeds[i].string);
116 					exit(0);
117 				}
118 			}
119 			(void) printf("unknown\n");
120 			exit(1);
121 		}
122                 else if (strcmp(argv[1], "-g") == 0) {
123 			if ((i = open("/dev/tty", 0)) < 0) {
124 				perror("stty: Cannot open /dev/tty");
125 				exit(2);
126 			}
127 			if((term = get_ttymode(i, &ocb, &cb, &stio, &termiox,
128 					&winsize)) < 0) {
129 				perror(STTY);
130 				exit(2);
131 			}
132 			prencode();
133 			exit(0);
134 		}
135 	}
136 
137 	if((term = get_ttymode(ioctl_desc, &ocb, &cb, &stio, &termiox, &winsize)) < 0) {
138 		perror(STTY);
139 		exit(2);
140 	}
141 	owinsize = winsize;
142 	if (argc == 1) {
143 		prmodes(0);
144 		exit(0);
145 	}
146 	if ((argc ==2) && strcmp(argv[1], "all") ==0) {
147 		prmodes(1);
148 		exit(0);
149 	}
150 	if ((argc ==2) && strcmp(argv[1], "everything") ==0) {
151 		pramodes(1);
152 		exit(0);
153 	}
154 	if ((argc == 2) && (argv[1][0] == '-') && (argv[1][2] == '\0'))
155 	switch(argv[1][1]) {
156 		case 'a':
157 			pramodes(0);
158 			exit(0);
159 		case 'h':
160 			pramodes(1);
161 			exit(0);
162 		default:
163 			(void) fprintf(stderr, "%s", USAGE);
164 			exit(2);
165 	}
166 	if (s_arg = sttyparse(argc, argv, term, &ocb, &cb, &termiox, &winsize)) {
167 		(void) fprintf(stderr, "unknown mode: %s\n", s_arg);
168 		exit(2);
169 	}
170 
171 	if(set_ttymode(ioctl_desc, term, &ocb, &cb, &stio, &termiox, &winsize, &owinsize) == -1) {
172 		perror(STTY);
173 		exit(2);
174 	}
175 	return (0);	/*NOTREACHED*/
176 }
177 
178 void
179 prmodes(int moremodes)
180 /* print modes, no options, argc is 1 */
181 {
182 	int m;
183 
184 	if (!(term & ASYNC)) {
185 		m = stio.imode;
186 		if (m & IUCLC) (void) fprintf(output, "iuclc ");
187 		else (void) fprintf(output, "-iuclc ");
188 		m = stio.omode;
189 		if (m & OLCUC) (void) fprintf(output, "olcuc ");
190 		else (void) fprintf(output, "-olcuc ");
191 		if (m & TAB3) (void) fprintf(output, "tab3 ");
192 		m = stio.lmode;
193 		if (m & XCASE) (void) fprintf(output, "xcase ");
194 		else (void) fprintf(output, "-xcase ");
195 		if (m & STFLUSH) (void) fprintf(output, "stflush ");
196 		else (void) fprintf(output, "-stflush ");
197 		if (m & STWRAP) (void)fprintf(output, "stwrap ");
198 		else (void) fprintf(output, "-stwrap ");
199 		if (m & STAPPL) (void) fprintf(output, "stappl ");
200 		else (void) fprintf(output, "-stappl ");
201 		(void) fprintf(output, "\n");
202 	}
203 	if (term & ASYNC) {
204 		m = cb.c_cflag;
205 		if ((term & TERMIOS) && cfgetispeed(&cb) != 0 &&
206 		    cfgetispeed(&cb) != cfgetospeed(&cb)) {
207 			prspeed("ispeed ", cfgetispeed(&cb));
208 			prspeed("ospeed ", cfgetospeed(&cb));
209 		} else
210 			prspeed("speed ", cfgetospeed(&cb));
211 		if (m&PARENB) {
212 			if((m&PAREXT) && (term & TERMIOS)) {
213 				if (m&PARODD)
214 					(void) fprintf(output,"markp ");
215 				else
216 					(void) fprintf(output,"spacep ");
217 			} else {
218 				if (m&PARODD)
219 					(void) fprintf(output,"oddp ");
220 				else
221 					(void) fprintf(output,"evenp ");
222 			}
223 		} else
224 			(void) fprintf(output,"-parity ");
225 		if(((m&PARENB) && !(m&CS7)) || (!(m&PARENB) && !(m&CS8)))
226 			(void) fprintf(output,"cs%c ",'5'+(m&CSIZE)/CS6);
227 		if (m&CSTOPB)
228 			(void) fprintf(output,"cstopb ");
229 		if (m&HUPCL)
230 			(void) fprintf(output,"hupcl ");
231 		if (!(m&CREAD))
232 			(void) fprintf(output,"-cread ");
233 		if (m&CLOCAL)
234 			(void) fprintf(output,"clocal ");
235 		if (m&LOBLK)
236 			(void) fprintf(output,"loblk ");
237 		(void) fprintf(output,"\n");
238 		if(ocb.c_line != 0)
239 			(void) fprintf(output,"line = %d; ", ocb.c_line);
240 		if(term & WINDOW) {
241 			(void)fprintf(output,"rows = %d; columns = %d;", winsize.ws_row, winsize.ws_col);
242 			(void)fprintf(output," ypixels = %d; xpixels = %d;\n", winsize.ws_ypixel, winsize.ws_xpixel);
243 		}
244 		if((cb.c_lflag&ICANON)== 0)
245 			(void) fprintf(output,"min = %d; time = %d;\n",
246 			cb.c_cc[VMIN], cb.c_cc[VTIME]);
247 		if (!moremodes) {
248 			if(cb.c_cc[VINTR] != CINTR)
249 				pit(cb.c_cc[VINTR], "intr", "; ");
250 			if(cb.c_cc[VQUIT] != CQUIT)
251 				pit(cb.c_cc[VQUIT], "quit", "; ");
252 			if(cb.c_cc[VERASE] != CERASE)
253 				pit(cb.c_cc[VERASE], "erase", "; ");
254 			if(cb.c_cc[VKILL] != CKILL)
255 				pit(cb.c_cc[VKILL], "kill", "; ");
256 			if(cb.c_cc[VEOF] != CEOF)
257 				pit(cb.c_cc[VEOF], "eof", "; ");
258 			if(cb.c_cc[VEOL] != CNUL)
259 				pit(cb.c_cc[VEOL], "eol", "; ");
260 			if(cb.c_cc[VEOL2] != CNUL)
261 				pit(cb.c_cc[VEOL2], "eol2", "; ");
262 			if(cb.c_cc[VSWTCH] != CSWTCH)
263 				pit(cb.c_cc[VSWTCH], "swtch", "; ");
264 			if(term & TERMIOS) {
265 				if(cb.c_cc[VSTART] != CSTART)
266 					pit(cb.c_cc[VSTART], "start", "; ");
267 				if(cb.c_cc[VSTOP] != CSTOP)
268 					pit(cb.c_cc[VSTOP], "stop", "; ");
269 				if(cb.c_cc[VSUSP] != CSUSP)
270 					pit(cb.c_cc[VSUSP], "susp", "; ");
271 				if(cb.c_cc[VDSUSP] != CDSUSP)
272 					pit(cb.c_cc[VDSUSP], "dsusp", "; ");
273 				if(cb.c_cc[VREPRINT] != CRPRNT)
274 					pit(cb.c_cc[VREPRINT], "rprnt", "; ");
275 				if(cb.c_cc[VDISCARD] != CFLUSH)
276 					pit(cb.c_cc[VDISCARD], "flush", "; ");
277 				if(cb.c_cc[VWERASE] != CWERASE)
278 					pit(cb.c_cc[VWERASE], "werase", "; ");
279 				if(cb.c_cc[VLNEXT] != CLNEXT)
280 					pit(cb.c_cc[VLNEXT], "lnext", "; ");
281 			}
282 		}
283 		if(pitt) (void) fprintf(output,"\n");
284 		m = cb.c_iflag;
285 		if (m&IGNBRK)
286 			(void) fprintf(output,"ignbrk ");
287 		else if (!(m&BRKINT))
288 			(void) fprintf(output,"-brkint ");
289 		if (!(m&INPCK))
290 			(void) fprintf(output,"-inpck ");
291 		else if (!(m&IGNPAR))
292 			(void) fprintf(output,"-ignpar ");
293 		if (m&PARMRK)
294 			(void) fprintf(output,"parmrk ");
295 		if (!(m&ISTRIP))
296 			(void) fprintf(output,"-istrip ");
297 		if (m&INLCR)
298 			(void) fprintf(output,"inlcr ");
299 		if (m&IGNCR)
300 			(void) fprintf(output,"igncr ");
301 		if (!(m&ICRNL))
302 			(void) fprintf(output,"-icrnl ");
303 		if (m&IUCLC)
304 			(void) fprintf(output,"iuclc ");
305 		if (!(m&IXON))
306 			(void) fprintf(output,"-ixon ");
307 		else if (m&IXANY)
308 			(void) fprintf(output,"ixany ");
309 		if (m&IXOFF)
310 			(void) fprintf(output,"ixoff ");
311 		if ((term & TERMIOS) && (m&IMAXBEL))
312 			(void) fprintf(output,"imaxbel ");
313 		m = cb.c_oflag;
314 		if (!(m&OPOST))
315 			(void) fprintf(output,"-opost ");
316 		else {
317 		if (m&OLCUC)
318 			(void) fprintf(output,"olcuc ");
319 		if (!(m&ONLCR))
320 			(void) fprintf(output,"-onlcr ");
321 		if (m&OCRNL)
322 			(void) fprintf(output,"ocrnl ");
323 		if (m&ONOCR)
324 			(void) fprintf(output,"onocr ");
325 		if (m&ONLRET)
326 			(void) fprintf(output,"onlret ");
327 		if (m&OFILL)
328 			if (m&OFDEL)
329 				(void) fprintf(output,"del-fill ");
330 			else
331 				(void) fprintf(output,"nul-fill ");
332 		delay((m&CRDLY)/CR1, "cr");
333 		delay((m&NLDLY)/NL1, "nl");
334 		if ((m&TABDLY) == XTABS)
335 			(void) fprintf(output,"-tabs ");
336 		else
337 			delay((m&TABDLY)/TAB1, "tab");
338 		delay((m&BSDLY)/BS1, "bs");
339 		delay((m&VTDLY)/VT1, "vt");
340 		delay((m&FFDLY)/FF1, "ff");
341 		}
342 		(void) fprintf(output,"\n");
343 		m = cb.c_lflag;
344 		if (!(m&ISIG))
345 			(void) fprintf(output,"-isig ");
346 		if (!(m&ICANON))
347 			(void) fprintf(output,"-icanon ");
348 		if (m&XCASE)
349 			(void) fprintf(output,"xcase ");
350 		if (!(m&ECHO))
351 			(void) fprintf(output,"-echo ");
352 		if (m&ECHOE) {
353 			if (m&ECHOKE)
354 				(void) fprintf(output,"crt ");
355 			else
356 				(void) fprintf(output,"echoe -echoke ");
357 		} else {
358 			if (!(m&ECHOPRT))
359 				(void) fprintf(output,"-echoprt ");
360 		}
361 		if (!(m&ECHOK))
362 			(void) fprintf(output,"-echok ");
363 		if (m&ECHONL)
364 			(void) fprintf(output,"echonl ");
365 		if (m&NOFLSH)
366 			(void) fprintf(output,"noflsh ");
367 		if (m&TOSTOP)
368 			(void) fprintf(output,"tostop ");
369 		if (!(m&ECHOCTL))
370 			(void) fprintf(output,"-echoctl ");
371 		if (m&DEFECHO)
372 			(void) fprintf(output,"defecho ");
373 		if (m&FLUSHO)
374 			(void) fprintf(output,"flusho ");
375 		if (m&PENDIN)
376 			(void) fprintf(output,"pendin ");
377 		if (m&IEXTEN)
378 			(void) fprintf(output,"iexten ");
379 		(void) fprintf(output,"\n");
380 	}
381 	if(term & FLOW) {
382 		m = termiox.x_hflag;
383 		if(m & RTSXOFF)
384 			(void) fprintf(output,"rtsxoff ");
385 		if(m & CTSXON)
386 			(void) fprintf(output,"ctsxon ");
387 		if(m & DTRXOFF)
388 			(void) fprintf(output,"dterxoff ");
389 		if(m & CDXON)
390 			(void) fprintf(output,"rlsdxon ");
391 		if(m & ISXOFF)
392 			(void) fprintf(output,"isxoff ");
393 		m = termiox.x_cflag;
394 		switch(m & XMTCLK)
395 		{
396 			case XCIBRG: (void)fprintf(output,"xcibrg ");
397 				     break;
398 			case XCTSET: (void)fprintf(output,"xctset ");
399 				     break;
400 			case XCRSET: (void)fprintf(output,"xcrset ");
401 		}
402 
403 		switch(m & RCVCLK)
404 		{
405 			case RCIBRG: (void)fprintf(output,"rcibrg ");
406 				     break;
407 			case RCTSET: (void)fprintf(output,"rctset ");
408 				     break;
409 			case RCRSET: (void)fprintf(output,"rcrset ");
410 		}
411 
412 		switch(m & TSETCLK)
413 		{
414 			case TSETCOFF: (void)fprintf(output,"tsetcoff ");
415 				     break;
416 			case TSETCRBRG: (void)fprintf(output,"tsetcrc ");
417 				     break;
418 			case TSETCTBRG: (void)fprintf(output,"tsetcxc ");
419 		}
420 
421 		switch(m & RSETCLK)
422 		{
423 			case RSETCOFF: (void)fprintf(output,"rsetcoff ");
424 				     break;
425 			case RSETCRBRG: (void)fprintf(output,"rsetcrc ");
426 				     break;
427 			case RSETCTBRG: (void)fprintf(output,"rsetcxc ");
428 		}
429 		(void) fprintf(output,"\n");
430 	}
431 	if(moremodes)
432 		prachars();
433 }
434 
435 void
436 pramodes(int tabform)
437 /* print all modes, -a option */
438 {
439 	int m;
440 
441 	m = cb.c_cflag;
442 	if(term & ASYNC) {
443 		if ((term & TERMIOS) && cfgetispeed(&cb) != 0 &&
444 		    cfgetispeed(&cb) != cfgetospeed(&cb)) {
445 			prspeed("ispeed ", cfgetispeed(&cb));
446 			prspeed("ospeed ", cfgetospeed(&cb));
447 		} else
448 			prspeed("speed ", cfgetospeed(&cb));
449 		if(!(term & TERMIOS))
450 			(void) fprintf(output,"line = %d; ", ocb.c_line);
451 		(void) fprintf(output,"\n");
452 		if(term & WINDOW) {
453 			(void)fprintf(output,"rows = %d columns = %d; ", winsize.ws_row, winsize.ws_col);
454 			(void)fprintf(output,"ypixels = %d xpixels = %d\n", winsize.ws_ypixel, winsize.ws_xpixel);
455 		}
456 		if((cb.c_lflag&ICANON)== 0)
457 			(void) fprintf(output,"min = %d; time = %d;\n", cb.c_cc[VMIN],
458 			cb.c_cc[VTIME]);
459 		if (!tabform) {
460 			pit(cb.c_cc[VINTR], "intr", "; ");
461 			pit(cb.c_cc[VQUIT], "quit", "; ");
462 			pit(cb.c_cc[VERASE], "erase", "; ");
463 			pit(cb.c_cc[VKILL], "kill", ";\n");
464 			pit(cb.c_cc[VEOF], "eof", "; ");
465 			pit(cb.c_cc[VEOL], "eol", "; ");
466 			pit(cb.c_cc[VEOL2], "eol2", "; ");
467 			pit(cb.c_cc[VSWTCH], "swtch", ";\n");
468 			if(term & TERMIOS) {
469 				pit(cb.c_cc[VSTART], "start", "; ");
470 				pit(cb.c_cc[VSTOP], "stop", "; ");
471 				pit(cb.c_cc[VSUSP], "susp", "; ");
472 				pit(cb.c_cc[VDSUSP], "dsusp", ";\n");
473 				pit(cb.c_cc[VREPRINT], "rprnt", "; ");
474 				pit(cb.c_cc[VDISCARD], "flush", "; ");
475 				pit(cb.c_cc[VWERASE], "werase", "; ");
476 				pit(cb.c_cc[VLNEXT], "lnext", ";\n");
477 			}
478 		}
479 	} else
480 		pit((unsigned)stio.tab, "ctab", "\n");
481 	m = cb.c_cflag;
482 	(void) fprintf(output,"-parenb "+((m&PARENB)!=0));
483 	(void) fprintf(output,"-parodd "+((m&PARODD)!=0));
484 	(void) fprintf(output,"cs%c ",'5'+(m&CSIZE)/CS6);
485 	(void) fprintf(output,"-cstopb "+((m&CSTOPB)!=0));
486 	(void) fprintf(output,"-hupcl "+((m&HUPCL)!=0));
487 	(void) fprintf(output,"-cread "+((m&CREAD)!=0));
488 	(void) fprintf(output,"-clocal "+((m&CLOCAL)!=0));
489 
490 	(void) fprintf(output,"-loblk "+((m&LOBLK)!=0));
491 	if(term & TERMIOS)
492 		(void) fprintf(output,"-parext "+((m&PAREXT)!=0));
493 
494 	(void) fprintf(output,"\n");
495 	m = cb.c_iflag;
496 	(void) fprintf(output,"-ignbrk "+((m&IGNBRK)!=0));
497 	(void) fprintf(output,"-brkint "+((m&BRKINT)!=0));
498 	(void) fprintf(output,"-ignpar "+((m&IGNPAR)!=0));
499 	(void) fprintf(output,"-parmrk "+((m&PARMRK)!=0));
500 	(void) fprintf(output,"-inpck "+((m&INPCK)!=0));
501 	(void) fprintf(output,"-istrip "+((m&ISTRIP)!=0));
502 	(void) fprintf(output,"-inlcr "+((m&INLCR)!=0));
503 	(void) fprintf(output,"-igncr "+((m&IGNCR)!=0));
504 	(void) fprintf(output,"-icrnl "+((m&ICRNL)!=0));
505 	(void) fprintf(output,"-iuclc "+((m&IUCLC)!=0));
506 	(void) fprintf(output,"\n");
507 	(void) fprintf(output,"-ixon "+((m&IXON)!=0));
508 	(void) fprintf(output,"-ixany "+((m&IXANY)!=0));
509 	(void) fprintf(output,"-ixoff "+((m&IXOFF)!=0));
510 	if(term & TERMIOS)
511 		(void) fprintf(output,"-imaxbel "+((m&IMAXBEL)!=0));
512 	(void) fprintf(output,"\n");
513 	m = cb.c_lflag;
514 	(void) fprintf(output,"-isig "+((m&ISIG)!=0));
515 	(void) fprintf(output,"-icanon "+((m&ICANON)!=0));
516 	(void) fprintf(output,"-xcase "+((m&XCASE)!=0));
517 	(void) fprintf(output,"-echo "+((m&ECHO)!=0));
518 	(void) fprintf(output,"-echoe "+((m&ECHOE)!=0));
519 	(void) fprintf(output,"-echok "+((m&ECHOK)!=0));
520 	(void) fprintf(output,"-echonl "+((m&ECHONL)!=0));
521 	(void) fprintf(output,"-noflsh "+((m&NOFLSH)!=0));
522 	if(term & TERMIOS) {
523 		(void) fprintf(output,"\n");
524 		(void) fprintf(output,"-tostop "+((m&TOSTOP)!=0));
525 		(void) fprintf(output,"-echoctl "+((m&ECHOCTL)!=0));
526 		(void) fprintf(output,"-echoprt "+((m&ECHOPRT)!=0));
527 		(void) fprintf(output,"-echoke "+((m&ECHOKE)!=0));
528 		(void) fprintf(output,"-defecho "+((m&DEFECHO)!=0));
529 		(void) fprintf(output,"-flusho "+((m&FLUSHO)!=0));
530 		(void) fprintf(output,"-pendin "+((m&PENDIN)!=0));
531 		(void) fprintf(output,"-iexten "+((m&IEXTEN)!=0));
532 	}
533 	if(!(term & ASYNC)) {
534 		(void) fprintf(output,"-stflush "+((m&STFLUSH)!=0));
535 		(void) fprintf(output,"-stwrap "+((m&STWRAP)!=0));
536 		(void) fprintf(output,"-stappl "+((m&STAPPL)!=0));
537 	}
538 	(void) fprintf(output,"\n");
539 	m = cb.c_oflag;
540 	(void) fprintf(output,"-opost "+((m&OPOST)!=0));
541 	(void) fprintf(output,"-olcuc "+((m&OLCUC)!=0));
542 	(void) fprintf(output,"-onlcr "+((m&ONLCR)!=0));
543 	(void) fprintf(output,"-ocrnl "+((m&OCRNL)!=0));
544 	(void) fprintf(output,"-onocr "+((m&ONOCR)!=0));
545 	(void) fprintf(output,"-onlret "+((m&ONLRET)!=0));
546 	(void) fprintf(output,"-ofill "+((m&OFILL)!=0));
547 	(void) fprintf(output,"-ofdel "+((m&OFDEL)!=0));
548 	delay((m&CRDLY)/CR1, "cr");
549 	delay((m&NLDLY)/NL1, "nl");
550 	if ((m&TABDLY) == XTABS)
551 		(void) fprintf(output,"-tabs ");
552 	else
553 		delay((m&TABDLY)/TAB1, "tab");
554 	delay((m&BSDLY)/BS1, "bs");
555 	delay((m&VTDLY)/VT1, "vt");
556 	delay((m&FFDLY)/FF1, "ff");
557 	(void) fprintf(output,"\n");
558 	if(term & FLOW) {
559 		m = termiox.x_hflag;
560 		(void) fprintf(output,"-rtsxoff "+((m&RTSXOFF)!=0));
561 		(void) fprintf(output,"-ctsxon "+((m&CTSXON)!=0));
562 		(void) fprintf(output,"-dterxoff "+((m&DTRXOFF)!=0));
563 		(void) fprintf(output,"-rlsdxon "+((m&CDXON)!=0));
564 		(void) fprintf(output,"-isxoff "+((m&ISXOFF)!=0));
565 		m = termiox.x_cflag;
566 		switch(m & XMTCLK)
567 		{
568 			case XCIBRG: (void)fprintf(output,"xcibrg ");
569 				     break;
570 			case XCTSET: (void)fprintf(output,"xctset ");
571 				     break;
572 			case XCRSET: (void)fprintf(output,"xcrset ");
573 		}
574 
575 		switch(m & RCVCLK)
576 		{
577 			case RCIBRG: (void)fprintf(output,"rcibrg ");
578 				     break;
579 			case RCTSET: (void)fprintf(output,"rctset ");
580 				     break;
581 			case RCRSET: (void)fprintf(output,"rcrset ");
582 		}
583 
584 		switch(m & TSETCLK)
585 		{
586 			case TSETCOFF: (void)fprintf(output,"tsetcoff ");
587 				     break;
588 			case TSETCRBRG: (void)fprintf(output,"tsetcrc ");
589 				     break;
590 			case TSETCTBRG: (void)fprintf(output,"tsetcxc ");
591 		}
592 
593 		switch(m & RSETCLK)
594 		{
595 			case RSETCOFF: (void)fprintf(output,"rsetcoff ");
596 				     break;
597 			case RSETCRBRG: (void)fprintf(output,"rsetcrc ");
598 				     break;
599 			case RSETCTBRG: (void)fprintf(output,"rsetcxc ");
600 		}
601 		(void) fprintf(output,"\n");
602 	}
603 	if (tabform)
604 		prachars();
605 }
606 
607 void
608 prachars(void)
609 {
610 	if ((cb.c_lflag&ICANON)==0)
611 		(void) fprintf(output,"min %d, time %d\n", cb.c_cc[VMIN],
612 		    cb.c_cc[VTIME]);
613 	(void) fprintf(output,"\
614 erase  kill   werase rprnt  flush  lnext  susp   intr   quit   stop   eof\
615 \n");
616 	pcol(cb.c_cc[VERASE], 0);
617 	pcol(cb.c_cc[VKILL], 0);
618 	pcol(cb.c_cc[VWERASE], 0);
619 	pcol(cb.c_cc[VREPRINT], 0);
620 	pcol(cb.c_cc[VDISCARD], 0);
621 	pcol(cb.c_cc[VLNEXT], 0);
622 	pcol(cb.c_cc[VSUSP], cb.c_cc[VDSUSP]);
623 	pcol(cb.c_cc[VINTR], 0);
624 	pcol(cb.c_cc[VQUIT], 0);
625 	pcol(cb.c_cc[VSTOP], cb.c_cc[VSTART]);
626 	if (cb.c_lflag&ICANON)
627 		pcol(cb.c_cc[VEOF], cb.c_cc[VEOL]);
628 	(void) fprintf(output,"\n");
629 	if (cb.c_cc[VEOL2] != 0 || cb.c_cc[VSWTCH] != 0) {
630 		(void) fprintf(output,"\
631 eol2  swtch\
632 \n");
633 		pcol(cb.c_cc[VEOL2], 0);
634 		pcol(cb.c_cc[VSWTCH], 0);
635 		(void) fprintf(output,"\n");
636 	}
637 }
638 
639 void
640 pcol(int ch1, int ch2)
641 {
642 	int nout = 0;
643 
644 	ch1 &= 0377;
645 	ch2 &= 0377;
646 	if (ch1 == ch2)
647 		ch2 = 0;
648 	for (; ch1 != 0 || ch2 != 0; ch1 = ch2, ch2 = 0) {
649 		if (ch1 == 0)
650 			continue;
651 		if (ch1 & 0200 && !isprint(ch1)) {
652 			(void) fprintf(output,"M-");
653 			nout += 2;
654 			ch1 &= ~ 0200;
655 		}
656 		if (ch1 == 0177) {
657 			(void) fprintf(output,"^");
658 			nout++;
659 			ch1 = '?';
660 		} else if (ch1 < ' ') {
661 			(void) fprintf(output,"^");
662 			nout++;
663 			ch1 += '@';
664 		}
665 		(void) fprintf(output,"%c", ch1);
666 		nout++;
667 		if (ch2 != 0) {
668 			(void) fprintf(output,"/");
669 			nout++;
670 		}
671 	}
672 	while (nout < 7) {
673 		(void) fprintf(output," ");
674 		nout++;
675 	}
676 }
677 
678 void
679 pit(unsigned char what, char *itsname, char *sep)
680 /* print function for prmodes() and pramodes() */
681 {
682 
683 	pitt++;
684 	(void) fprintf(output,"%s", itsname);
685 	if ((term & TERMIOS) && what == _POSIX_VDISABLE || !(term & TERMIOS) && what == 0200) {
686 		(void) fprintf(output," = <undef>%s", sep);
687 		return;
688 	}
689 	(void) fprintf(output," = ");
690 	if (what & 0200 && !isprint(what)) {
691 		(void) fprintf(output,"-");
692 		what &= ~ 0200;
693 	}
694 	if (what == 0177) {
695 		(void) fprintf(output,"^?%s", sep);
696 		return;
697 	} else if (what < ' ') {
698 		(void) fprintf(output,"^");
699 		what += '`';
700 	}
701 	(void) fprintf(output,"%c%s", what, sep);
702 }
703 
704 void
705 delay(int m, char *s)
706 {
707 	if(m)
708 		(void) fprintf(output,"%s%d ", s, m);
709 }
710 
711 long	speed[] = {
712 	0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,
713 	57600,76800,115200,153600,230400,307200,460800
714 };
715 
716 void
717 prspeed(char *c, int s)
718 {
719 
720 	(void) fprintf(output,"%s%d baud; ", c, speed[s]);
721 }
722 
723 /*
724  * print current settings for use with
725  * another stty cmd, used for -g option
726  */
727 void
728 prencode(void)
729 {
730 	int i, last;
731 
732 	/* Since the -g option is mostly used for redirecting to a file */
733 	/* We must print to stdout here, not stderr */
734 
735 	(void) printf("%x:%x:%x:%x:",cb.c_iflag,cb.c_oflag,cb.c_cflag,cb.c_lflag);
736 
737 	if(term & TERMIOS)
738 	/* last control slot is unused */
739 		last = NCCS - 2;
740 	else
741 		last = NCC - 1;
742 	for(i = 0; i < last; i++)
743 		(void) printf("%x:", cb.c_cc[i]);
744 	(void) printf("%x\n", cb.c_cc[last]);
745 }
746