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 1999-2002 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2014, Joyent, Inc.  All rights reserved.
26 */
27
28/*
29 * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
30 * All Rights Reserved
31 *
32 */
33
34#include <stdio.h>
35#include <ctype.h>
36#include <locale.h>
37#include <sys/types.h>
38#include <termio.h>
39#include <sys/stermio.h>
40#include <sys/termiox.h>
41#include <string.h>
42#include <stdlib.h>
43#include <limits.h>
44#ifdef EUC
45#include <sys/stat.h>
46#include <fcntl.h>
47#include <unistd.h>
48#include <sys/param.h>
49#include <sys/stropts.h>
50#include <sys/eucioctl.h>
51#include <sys/csiioctl.h>
52#include <sys/stream.h>
53#include <sys/termios.h>
54#include <sys/ldterm.h>
55#include <getwidth.h>
56#endif /* EUC */
57#include "stty.h"
58
59extern const char *not_supported[];
60
61extern char *getenv();
62extern void exit();
63extern void perror();
64extern int get_ttymode();
65extern int set_ttymode();
66
67static char *STTY = "stty: ";
68static int pitt = 0;
69static struct termios cb;
70static struct termio ocb; /* for non-streams devices */
71static struct stio stio;
72static struct termiox termiox;
73static struct winsize winsize, owinsize;
74static int term;
75#ifdef EUC
76static struct eucioc kwp;
77static eucwidth_t wp;
78static ldterm_cs_data_user_t cswp;	/* User side codeset width data */
79static ldterm_cs_data_user_t kcswp;	/* Kernel side codeset width data */
80static int invalid_ldterm_dat_file;
81#endif /* EUC */
82
83static void prmodes();
84static void pramodes();
85static void pit(unsigned char what, char *itsname, char *sep);
86static void delay(int m, char *s);
87static void prspeed(char *c, int s);
88static void prencode();
89
90int
91main(int argc, char *argv[])
92{
93	int i;
94	int fd;
95	char *s_arg, *sttyparse();	/* s_arg: ptr to mode to be set */
96#ifdef	EUC
97	char *lc;
98	char tmps[PATH_MAX];
99#endif	/* EUC */
100
101	(void) setlocale(LC_ALL, "");
102#if !defined(TEXT_DOMAIN)
103#define	TEXT_DOMAIN "SYS_TEST"
104#endif
105	(void) textdomain(TEXT_DOMAIN);
106
107#ifdef EUC
108	lc = setlocale(LC_CTYPE, (const char *)NULL);
109	if (lc) {
110		sprintf(tmps, _LDTERM_DAT_PATH, lc);
111
112		fd = open(tmps, O_RDONLY, 0);
113		if (fd != -1) {
114			if (read(fd, (void *)&cswp, sizeof (cswp)) <
115			    sizeof (cswp)) {
116				(void) fprintf(stderr, gettext(
117				    "cannot read entire %s file\n"), tmps);
118				exit(2);
119			}
120
121			(void) close(fd);
122
123			/*
124			 * If the ldterm.dat contains invalid data or
125			 * the current locale name is too long, we clear
126			 * the 'cswp' and flag the invalid ldterm.dat since
127			 * we are not going to use the data.
128			 */
129			if (cswp.version > LDTERM_DATA_VERSION ||
130			    cswp.codeset_type < LDTERM_CS_TYPE_MIN ||
131			    cswp.codeset_type > LDTERM_CS_TYPE_MAX ||
132			    strlen(lc) >= MAXNAMELEN ||
133			    (cswp.codeset_type == LDTERM_CS_TYPE_EUC &&
134			    cswp.csinfo_num > LDTERM_CS_TYPE_EUC_MAX_SUBCS) ||
135			    (cswp.codeset_type == LDTERM_CS_TYPE_PCCS &&
136			    (cswp.csinfo_num < LDTERM_CS_TYPE_PCCS_MIN_SUBCS ||
137			    cswp.csinfo_num > LDTERM_CS_TYPE_PCCS_MAX_SUBCS))) {
138				(void) memset((void *)&cswp, 0, sizeof (cswp));
139				invalid_ldterm_dat_file = 1;
140			} else {
141				(void) strcpy(cswp.locale_name, lc);
142			}
143		}
144	}
145
146	getwidth(&wp);
147#endif /* EUC */
148
149	if ((term = get_ttymode(0, &ocb, &cb, &stio, &termiox, &winsize
150#ifdef EUC
151	    /* */, &kwp, &kcswp
152#endif /* EUC */
153	    /* */)) < 0) {
154		perror(STTY);
155		exit(2);
156	}
157	owinsize = winsize;
158	if (argc == 1) {
159		prmodes();
160		exit(0);
161	}
162	if ((argc == 2) && (argv[1][0] == '-') && (argv[1][2] == '\0'))
163	switch (argv[1][1]) {
164		case 'a':
165			pramodes();
166			return (0);
167		case 'g':
168			prencode();
169			return (0);
170		case '-':
171			prmodes(); /* stty -- */
172			return (0);
173		default:
174			(void) fprintf(stderr, gettext(
175			    "usage: stty [-a| -g]\n"));
176			(void) fprintf(stderr, gettext(
177			    "       stty [modes]\n"));
178			return (2);
179	}
180
181	if ((argc == 3) && (argv[1][0] == '-') && (argv[1][2] == '\0') &&
182	    (argv[2][0] == '-') && (argv[2][1] == '-') && (argv[2][2] == '\0'))
183	switch (argv[1][1]) {
184	case 'a':
185		pramodes();
186		return (0);
187	case 'g':
188		prencode();
189		return (0);
190	default:
191		(void) fprintf(stderr, gettext(
192		    "usage: stty [-a| -g]\n"));
193		(void) fprintf(stderr, gettext(
194		    "       stty [modes]\n"));
195		return (2);
196	}
197	if ((argc >= 3) && (argv[1][0] == '-') && (argv[1][1] == '-') &&
198	    (argv[1][2] == '\0')) {
199		/* ignore -- */
200		--argc;
201		++argv;
202	}
203	if (s_arg = sttyparse(argc, argv, term, &ocb, &cb, &termiox, &winsize
204#ifdef EUC
205	    /* */, &wp, &kwp, &cswp, &kcswp
206#endif /* EUC */
207	    /* */)) {
208		char *s = s_arg;
209		if (*s == '-') s++;
210		for (i = 0; not_supported[i]; i++) {
211			if (strcmp(not_supported[i], s) == 0) {
212				(void) fprintf(stderr,
213				    gettext(
214				    "mode not supported on this device: %s\n"),
215				    s_arg);
216				exit(2);
217			}
218		}
219		(void) fprintf(stderr, gettext("unknown mode: %s\n"), s_arg);
220		return (2);
221	}
222
223	if (set_ttymode(0, term, &ocb, &cb, &stio, &termiox, &winsize, &owinsize
224#ifdef EUC
225	    /* */, &kwp, &kcswp, invalid_ldterm_dat_file
226#endif /* EUC */
227	    /* */) == -1) {
228		perror(STTY);
229		return (2);
230	}
231	return (0);
232}
233
234void
235prmodes(void)				/* print modes, no options, argc is 1 */
236{
237	int m;
238
239	if (!(term & ASYNC)) {
240		m = stio.imode;
241		if (m & IUCLC)
242			(void) printf("iuclc ");
243		else
244			(void) printf("-iuclc ");
245		m = stio.omode;
246		if (m & OLCUC)
247			(void) printf("olcuc ");
248		else
249			(void) printf("-olcuc ");
250		if (m & TAB3)
251			(void) printf("tab3 ");
252		m = stio.lmode;
253		if (m & XCASE)
254			(void) printf("xcase ");
255		else
256			(void) printf("-xcase ");
257		if (m & STFLUSH)
258			(void) printf("stflush ");
259		else
260			(void) printf("-stflush ");
261		if (m & STWRAP)
262			(void) printf("stwrap ");
263		else
264			(void) printf("-stwrap ");
265		if (m & STAPPL)
266			(void) printf("stappl ");
267		else
268			(void) printf("-stappl ");
269		(void) printf("\n");
270	}
271	if (term & ASYNC) {
272		m = cb.c_cflag;
273		if ((term & TERMIOS) && cfgetispeed(&cb) != 0 &&
274		    cfgetispeed(&cb) != cfgetospeed(&cb)) {
275			prspeed("ispeed ", cfgetispeed(&cb));
276			prspeed("ospeed ", cfgetospeed(&cb));
277		} else
278			prspeed("speed ", cfgetospeed(&cb));
279		if (m&PARENB) {
280			if ((m&PAREXT) && (term & TERMIOS)) {
281				if (m&PARODD)
282					(void) printf("markp ");
283				else
284					(void) printf("spacep ");
285			} else {
286				if (m&PARODD)
287					(void) printf("oddp ");
288				else
289					(void) printf("evenp ");
290			}
291		} else
292			(void) printf("-parity ");
293		if (((m&PARENB) && !(m&CS7)) || (!(m&PARENB) && !(m&CS8)))
294			(void) printf("cs%c ", '5'+(m&CSIZE)/CS6);
295		if (m&CSTOPB)
296			(void) printf("cstopb ");
297		if (m&HUPCL)
298			(void) printf("hupcl ");
299		if (!(m&CREAD))
300			(void) printf("-cread ");
301		if (m&CLOCAL)
302			(void) printf("clocal ");
303		if (m&LOBLK)
304			(void) printf("loblk ");
305		(void) printf("\n");
306		if (ocb.c_line != 0)
307			(void) printf(gettext("line = %d; "), ocb.c_line);
308		if (term & WINDOW) {
309			(void) printf(gettext("rows = %d; columns = %d;"),
310			    winsize.ws_row, winsize.ws_col);
311			(void) printf(gettext(
312			    " ypixels = %d; xpixels = %d;\n"),
313			    winsize.ws_ypixel, winsize.ws_xpixel);
314		}
315		if ((cb.c_lflag&ICANON) == 0)
316			(void) printf(gettext("min = %d; time = %d;\n"),
317			    cb.c_cc[VMIN], cb.c_cc[VTIME]);
318		if (cb.c_cc[VINTR] != CINTR)
319			pit(cb.c_cc[VINTR], "intr", "; ");
320		if (cb.c_cc[VQUIT] != CQUIT)
321			pit(cb.c_cc[VQUIT], "quit", "; ");
322		if (cb.c_cc[VERASE] != CERASE)
323			pit(cb.c_cc[VERASE], "erase", "; ");
324		if (term & TERMIOS) {
325			if (cb.c_cc[VERASE2] != CERASE2)
326				pit(cb.c_cc[VERASE], "erase2", "; ");
327		}
328		if (cb.c_cc[VKILL] != CKILL)
329			pit(cb.c_cc[VKILL], "kill", "; ");
330		if (cb.c_cc[VEOF] != CEOF)
331			pit(cb.c_cc[VEOF], "eof", "; ");
332		if (cb.c_cc[VEOL] != CNUL)
333			pit(cb.c_cc[VEOL], "eol", "; ");
334		if (cb.c_cc[VEOL2] != CNUL)
335			pit(cb.c_cc[VEOL2], "eol2", "; ");
336		if (cb.c_cc[VSWTCH] != CSWTCH)
337			pit(cb.c_cc[VSWTCH], "swtch", "; ");
338		if (term & TERMIOS) {
339			if (cb.c_cc[VSTART] != CSTART)
340				pit(cb.c_cc[VSTART], "start", "; ");
341			if (cb.c_cc[VSTOP] != CSTOP)
342				pit(cb.c_cc[VSTOP], "stop", "; ");
343			if (cb.c_cc[VSUSP] != CSUSP)
344				pit(cb.c_cc[VSUSP], "susp", "; ");
345			if (cb.c_cc[VDSUSP] != CDSUSP)
346				pit(cb.c_cc[VDSUSP], "dsusp", "; ");
347			if (cb.c_cc[VREPRINT] != CRPRNT)
348				pit(cb.c_cc[VREPRINT], "rprnt", "; ");
349			if (cb.c_cc[VDISCARD] != CFLUSH)
350				pit(cb.c_cc[VDISCARD], "flush", "; ");
351			if (cb.c_cc[VWERASE] != CWERASE)
352				pit(cb.c_cc[VWERASE], "werase", "; ");
353			if (cb.c_cc[VLNEXT] != CLNEXT)
354				pit(cb.c_cc[VLNEXT], "lnext", "; ");
355			if (cb.c_cc[VSTATUS] != CSTATUS)
356				pit(cb.c_cc[VSTATUS], "status", "; ");
357		}
358		if (pitt) (void) printf("\n");
359		m = cb.c_iflag;
360		if (m&IGNBRK)
361			(void) printf("ignbrk ");
362		else if (m&BRKINT)
363			(void) printf("brkint ");
364		if (!(m&INPCK))
365			(void) printf("-inpck ");
366		else if (m&IGNPAR)
367			(void) printf("ignpar ");
368		if (m&PARMRK)
369			(void) printf("parmrk ");
370		if (!(m&ISTRIP))
371			(void) printf("-istrip ");
372		if (m&INLCR)
373			(void) printf("inlcr ");
374		if (m&IGNCR)
375			(void) printf("igncr ");
376		if (m&ICRNL)
377			(void) printf("icrnl ");
378		if (m&IUCLC)
379			(void) printf("iuclc ");
380		if (!(m&IXON))
381			(void) printf("-ixon ");
382		else if (!(m&IXANY))
383			(void) printf("-ixany ");
384		if (m&IXOFF)
385			(void) printf("ixoff ");
386		if ((term & TERMIOS) && (m&IMAXBEL))
387			(void) printf("imaxbel ");
388		m = cb.c_oflag;
389		if (!(m&OPOST))
390			(void) printf("-opost ");
391		else {
392			if (m&OLCUC)
393				(void) printf("olcuc ");
394			if (m&ONLCR)
395				(void) printf("onlcr ");
396			if (m&OCRNL)
397				(void) printf("ocrnl ");
398			if (m&ONOCR)
399				(void) printf("onocr ");
400			if (m&ONLRET)
401				(void) printf("onlret ");
402			if (m&OFILL)
403				if (m&OFDEL)
404					(void) printf("del-fill ");
405				else
406					(void) printf("nul-fill ");
407			delay((m&CRDLY)/CR1, "cr");
408			delay((m&NLDLY)/NL1, "nl");
409			delay((m&TABDLY)/TAB1, "tab");
410			delay((m&BSDLY)/BS1, "bs");
411			delay((m&VTDLY)/VT1, "vt");
412			delay((m&FFDLY)/FF1, "ff");
413		}
414		(void) printf("\n");
415		m = cb.c_lflag;
416		if (!(m&ISIG))
417			(void) printf("-isig ");
418		if (!(m&ICANON))
419			(void) printf("-icanon ");
420		if (m&XCASE)
421			(void) printf("xcase ");
422		(void) printf("-echo "+((m&ECHO) != 0));
423		(void) printf("-echoe "+((m&ECHOE) != 0));
424		(void) printf("-echok "+((m&ECHOK) != 0));
425		if (m&ECHONL)
426			(void) printf("echonl ");
427		if (m&NOFLSH)
428			(void) printf("noflsh ");
429		if (m&TOSTOP)
430			(void) printf("tostop ");
431		if (m&ECHOCTL)
432			(void) printf("echoctl ");
433		if (m&ECHOPRT)
434			(void) printf("echoprt ");
435		if (m&ECHOKE)
436			(void) printf("echoke ");
437		if (m&DEFECHO)
438			(void) printf("defecho ");
439		if (m&FLUSHO)
440			(void) printf("flusho ");
441		if (m&PENDIN)
442			(void) printf("pendin ");
443		if (m&IEXTEN)
444			(void) printf("iexten ");
445		(void) printf("\n");
446	}
447	if (term & FLOW) {
448		m = termiox.x_hflag;
449		if (m & RTSXOFF)
450			(void) printf("rtsxoff ");
451		if (m & CTSXON)
452			(void) printf("ctsxon ");
453		if (m & DTRXOFF)
454			(void) printf("dtrxoff ");
455		if (m & CDXON)
456			(void) printf("cdxon ");
457		if (m & ISXOFF)
458			(void) printf("isxoff ");
459		m = termiox.x_cflag;
460		switch (m & XMTCLK) {
461			case XCIBRG: (void)printf("xcibrg ");
462					break;
463			case XCTSET: (void)printf("xctset ");
464					break;
465			case XCRSET: (void)printf("xcrset ");
466		}
467
468		switch (m & RCVCLK) {
469			case RCIBRG: (void)printf("rcibrg ");
470					break;
471			case RCTSET: (void)printf("rctset ");
472					break;
473			case RCRSET: (void)printf("rcrset ");
474		}
475
476		switch (m & TSETCLK) {
477			case TSETCOFF: (void)printf("tsetcoff ");
478					break;
479			case TSETCRBRG: (void)printf("tsetcrbrg ");
480					break;
481			case TSETCTBRG: (void)printf("tsetctbrg ");
482					break;
483			case TSETCTSET: (void)printf("tsetctset ");
484					break;
485			case TSETCRSET: (void)printf("tsetcrset ");
486		}
487
488		switch (m & RSETCLK) {
489			case RSETCOFF: (void)printf("rsetcoff ");
490					break;
491			case RSETCRBRG: (void)printf("rsetcrbrg ");
492					break;
493			case RSETCTBRG: (void)printf("rsetctbrg ");
494					break;
495			case RSETCTSET: (void)printf("rsetctset ");
496					break;
497			case RSETCRSET: (void)printf("rsetcrset ");
498		}
499		(void) printf("\n");
500	}
501}
502
503void
504pramodes(void)				/* print all modes, -a option */
505{
506	int m;
507
508	m = cb.c_cflag;
509	if (term & ASYNC) {
510		if ((term & TERMIOS) && cfgetispeed(&cb) != 0 &&
511		    cfgetispeed(&cb) != cfgetospeed(&cb)) {
512			prspeed("ispeed ", cfgetispeed(&cb));
513			prspeed("ospeed ", cfgetospeed(&cb));
514		} else
515			prspeed("speed ", cfgetospeed(&cb));
516		if (!(term & TERMIOS))
517			(void) printf(gettext("line = %d; "), ocb.c_line);
518		(void) printf("\n");
519		if (term & WINDOW) {
520			(void) printf(gettext("rows = %d; columns = %d;"),
521			    winsize.ws_row, winsize.ws_col);
522			(void) printf(gettext(
523			    " ypixels = %d; xpixels = %d;\n"),
524			    winsize.ws_ypixel, winsize.ws_xpixel);
525		}
526#ifdef EUC
527		if ((term & CSIW) && kcswp.locale_name[0]) {
528			(void) printf("csdata %s\n", kcswp.locale_name);
529		} else {
530			(void) printf("csdata ?\n");
531		}
532		/*
533		 * If kwp.eucw[0] is zero, it means the current codeset type
534		 * in the ldterm is not EUC.
535		 */
536		if ((term & EUCW) && kwp.eucw[0]) {
537			(void) printf("eucw %d:%d:%d:%d, ", kwp.eucw[0],
538			    kwp.eucw[1], kwp.eucw[2], kwp.eucw[3]);
539			(void) printf("scrw %d:%d:%d:%d\n", kwp.scrw[0],
540			    kwp.scrw[1], kwp.scrw[2], kwp.scrw[3]);
541		} else
542			(void) printf("eucw ?, scrw ?\n");
543#endif /* EUC */
544		if ((cb.c_lflag&ICANON) == 0)
545			(void) printf(gettext("min = %d; time = %d;\n"),
546			    cb.c_cc[VMIN], cb.c_cc[VTIME]);
547		pit(cb.c_cc[VINTR], "intr", "; ");
548		pit(cb.c_cc[VQUIT], "quit", "; ");
549		pit(cb.c_cc[VERASE], "erase", "; ");
550		if (term & TERMIOS)
551			pit(cb.c_cc[VERASE2], "erase2", "; ");
552		pit(cb.c_cc[VKILL], "kill", ";\n");
553		pit(cb.c_cc[VEOF], "eof", "; ");
554		pit(cb.c_cc[VEOL], "eol", "; ");
555		pit(cb.c_cc[VEOL2], "eol2", "; ");
556		pit(cb.c_cc[VSWTCH], "swtch", ";\n");
557		if (term & TERMIOS) {
558			pit(cb.c_cc[VSTART], "start", "; ");
559			pit(cb.c_cc[VSTOP], "stop", "; ");
560			pit(cb.c_cc[VSUSP], "susp", "; ");
561			pit(cb.c_cc[VDSUSP], "dsusp", ";\n");
562			pit(cb.c_cc[VREPRINT], "rprnt", "; ");
563			pit(cb.c_cc[VDISCARD], "flush", "; ");
564			pit(cb.c_cc[VWERASE], "werase", "; ");
565			pit(cb.c_cc[VLNEXT], "lnext", ";\n");
566			pit(cb.c_cc[VSTATUS], "status", ";\n");
567		}
568	} else
569		pit((unsigned)stio.tab, "ctab", "\n");
570	m = cb.c_cflag;
571	(void) printf("-parenb "+((m&PARENB) != 0));
572	(void) printf("-parodd "+((m&PARODD) != 0));
573	(void) printf("cs%c ", '5'+(m&CSIZE)/CS6);
574	(void) printf("-cstopb "+((m&CSTOPB) != 0));
575	(void) printf("-hupcl "+((m&HUPCL) != 0));
576	(void) printf("-cread "+((m&CREAD) != 0));
577	(void) printf("-clocal "+((m&CLOCAL) != 0));
578
579	(void) printf("-loblk "+((m&LOBLK) != 0));
580	(void) printf("-crtscts "+((m&CRTSCTS) != 0));
581	(void) printf("-crtsxoff "+((m&CRTSXOFF) != 0));
582	if (term & TERMIOS)
583		(void) printf("-parext "+((m&PAREXT) != 0));
584
585	(void) printf("\n");
586	m = cb.c_iflag;
587	(void) printf("-ignbrk "+((m&IGNBRK) != 0));
588	(void) printf("-brkint "+((m&BRKINT) != 0));
589	(void) printf("-ignpar "+((m&IGNPAR) != 0));
590	(void) printf("-parmrk "+((m&PARMRK) != 0));
591	(void) printf("-inpck "+((m&INPCK) != 0));
592	(void) printf("-istrip "+((m&ISTRIP) != 0));
593	(void) printf("-inlcr "+((m&INLCR) != 0));
594	(void) printf("-igncr "+((m&IGNCR) != 0));
595	(void) printf("-icrnl "+((m&ICRNL) != 0));
596	(void) printf("-iuclc "+((m&IUCLC) != 0));
597	(void) printf("\n");
598	(void) printf("-ixon "+((m&IXON) != 0));
599	(void) printf("-ixany "+((m&IXANY) != 0));
600	(void) printf("-ixoff "+((m&IXOFF) != 0));
601	if (term & TERMIOS)
602		(void) printf("-imaxbel "+((m&IMAXBEL) != 0));
603	(void) printf("\n");
604	m = cb.c_lflag;
605	(void) printf("-isig "+((m&ISIG) != 0));
606	(void) printf("-icanon "+((m&ICANON) != 0));
607	(void) printf("-xcase "+((m&XCASE) != 0));
608	(void) printf("-echo "+((m&ECHO) != 0));
609	(void) printf("-echoe "+((m&ECHOE) != 0));
610	(void) printf("-echok "+((m&ECHOK) != 0));
611	(void) printf("-echonl "+((m&ECHONL) != 0));
612	(void) printf("-noflsh "+((m&NOFLSH) != 0));
613	if (term & TERMIOS) {
614		(void) printf("\n");
615		(void) printf("-tostop "+((m&TOSTOP) != 0));
616		(void) printf("-echoctl "+((m&ECHOCTL) != 0));
617		(void) printf("-echoprt "+((m&ECHOPRT) != 0));
618		(void) printf("-echoke "+((m&ECHOKE) != 0));
619		(void) printf("-defecho "+((m&DEFECHO) != 0));
620		(void) printf("-flusho "+((m&FLUSHO) != 0));
621		(void) printf("-pendin "+((m&PENDIN) != 0));
622		(void) printf("-iexten "+((m&IEXTEN) != 0));
623	}
624	if (!(term & ASYNC)) {
625		(void) printf("-stflush "+((m&STFLUSH) != 0));
626		(void) printf("-stwrap "+((m&STWRAP) != 0));
627		(void) printf("-stappl "+((m&STAPPL) != 0));
628	}
629	(void) printf("\n");
630	m = cb.c_oflag;
631	(void) printf("-opost "+((m&OPOST) != 0));
632	(void) printf("-olcuc "+((m&OLCUC) != 0));
633	(void) printf("-onlcr "+((m&ONLCR) != 0));
634	(void) printf("-ocrnl "+((m&OCRNL) != 0));
635	(void) printf("-onocr "+((m&ONOCR) != 0));
636	(void) printf("-onlret "+((m&ONLRET) != 0));
637	(void) printf("-ofill "+((m&OFILL) != 0));
638	(void) printf("-ofdel "+((m&OFDEL) != 0));
639	delay((m&CRDLY)/CR1, "cr");
640	delay((m&NLDLY)/NL1, "nl");
641	delay((m&TABDLY)/TAB1, "tab");
642	delay((m&BSDLY)/BS1, "bs");
643	delay((m&VTDLY)/VT1, "vt");
644	delay((m&FFDLY)/FF1, "ff");
645	(void) printf("\n");
646	if (term & FLOW) {
647		m = termiox.x_hflag;
648		(void) printf("-rtsxoff "+((m&RTSXOFF) != 0));
649		(void) printf("-ctsxon "+((m&CTSXON) != 0));
650		(void) printf("-dtrxoff "+((m&DTRXOFF) != 0));
651		(void) printf("-cdxon "+((m&CDXON) != 0));
652		(void) printf("-isxoff "+((m&ISXOFF) != 0));
653		m = termiox.x_cflag;
654		switch (m & XMTCLK) {
655			case XCIBRG: (void)printf("xcibrg ");
656					break;
657			case XCTSET: (void)printf("xctset ");
658					break;
659			case XCRSET: (void)printf("xcrset ");
660		}
661
662		switch (m & RCVCLK) {
663			case RCIBRG: (void)printf("rcibrg ");
664					break;
665			case RCTSET: (void)printf("rctset ");
666					break;
667			case RCRSET: (void)printf("rcrset ");
668		}
669
670		switch (m & TSETCLK) {
671			case TSETCOFF: (void)printf("tsetcoff ");
672					break;
673			case TSETCRBRG: (void)printf("tsetcrbrg ");
674					break;
675			case TSETCTBRG: (void)printf("tsetctbrg ");
676					break;
677			case TSETCTSET: (void)printf("tsetctset ");
678					break;
679			case TSETCRSET: (void)printf("tsetcrset ");
680		}
681
682		switch (m & RSETCLK) {
683			case RSETCOFF: (void)printf("rsetcoff ");
684					break;
685			case RSETCRBRG: (void)printf("rsetcrbrg ");
686					break;
687			case RSETCTBRG: (void)printf("rsetctbrg ");
688					break;
689			case RSETCTSET: (void)printf("rsetctset ");
690					break;
691			case RSETCRSET: (void)printf("rsetcrset ");
692		}
693		(void) printf("\n");
694	}
695}
696
697/* print function for prmodes() and pramodes() */
698void
699pit(unsigned char what, char *itsname, char *sep)
700{
701
702	pitt++;
703	(void) printf("%s", itsname);
704	if ((term & TERMIOS) && what == _POSIX_VDISABLE ||
705	    !(term & TERMIOS) && what == 0200) {
706		(void) printf(" = <undef>%s", sep);
707		return;
708	}
709	(void) printf(" = ");
710	if (what & 0200 && !isprint(what)) {
711		(void) printf("-");
712		what &= ~ 0200;
713	}
714	if (what == 0177) {
715		(void) printf("^?%s", sep);
716		return;
717	} else if (what < ' ') {
718		(void) printf("^");
719		what += '`';
720		if (what > 'z')
721			what -= 'a' -'A';
722	}
723	(void) printf("%c%s", what, sep);
724}
725
726void
727delay(int m, char *s)
728{
729	if (m)
730		(void) printf("%s%d ", s, m);
731}
732
733void
734prspeed(char *c, int scode)
735{
736	int sval = -1;
737	int i;
738
739	for (i = 0; speeds[i].string; i++) {
740		if (speeds[i].code == scode) {
741			sval = speeds[i].value;
742			break;
743		}
744	}
745
746	(void) printf("%s%d baud; ", c, sval);
747}
748
749/* print current settings for use with  */
750void
751prencode(void)		/* another stty cmd, used for -g option */
752{
753	int i, last;
754
755	/*
756	 * Although there are only 16 control chars defined as of April 1995,
757	 * prencode() and encode() will not have to be changed if up to MAX_CC
758	 * control chars are defined in the future.  A maximum of MAX_CC rather
759	 * than NCCS control chars are printed because the last control slot
760	 * is unused.  "stty -g" prints out a total of NUM_FIELDS fields
761	 * (NUM_MODES modes + MAX_CC control chars).  First print the input,
762	 * output, control, and line discipline modes.
763	 */
764	(void) printf("%x:%x:%x:%x", cb.c_iflag, cb.c_oflag, cb.c_cflag,
765	    cb.c_lflag);
766
767	/* Print the control character fields. */
768	if (term & TERMIOS)
769		last = MAX_CC;
770	else
771		last = NCC;
772#ifdef EUC
773	if (term & CSIW) {
774		for (i = 0; i < MAX_CC; i++)
775			(void) printf(":%x", (i >= last) ? 0 : cb.c_cc[i]);
776		/*
777		 * Print out ldterm_cs_data_user_t data fields for
778		 * PSARC/1999/140 TCR2. This change introduces additional
779		 * 44 fields that come from the ldterm_cs_data_user_t data
780		 * structure.
781		 */
782		(void) printf(":%x:%x:%x:", kcswp.version, kcswp.codeset_type,
783		    kcswp.csinfo_num);
784		if (*kcswp.locale_name == '\0') {
785			(void) printf("00");
786		} else {
787			for (i = 0; kcswp.locale_name[i] && i < MAXNAMELEN; i++)
788				(void) printf("%02x", kcswp.locale_name[i]);
789		}
790		for (i = 0; i < LDTERM_CS_MAX_CODESETS; i++)
791			(void) printf(":%x:%x:%x:%x",
792			    kcswp.eucpc_data[i].byte_length,
793			    kcswp.eucpc_data[i].screen_width,
794			    kcswp.eucpc_data[i].msb_start,
795			    kcswp.eucpc_data[i].msb_end);
796	} else {
797#endif /* EUC */
798		for (i = 0; i < last; i++)
799			(void) printf(":%x", cb.c_cc[i]);
800#ifdef EUC
801	}
802#endif /* EUC */
803	(void) printf("\n");
804}
805