1/*	$OpenBSD: print.c,v 1.16 2017/04/28 22:16:43 millert Exp $	*/
2/*	$NetBSD: print.c,v 1.11 1996/05/07 18:20:10 jtc Exp $	*/
3
4/*-
5 * Copyright (c) 1991, 1993, 1994
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/types.h>
34
35#include <stddef.h>
36#include <stdio.h>
37#include <string.h>
38#include <termios.h>
39
40#include "stty.h"
41#include "extern.h"
42
43static void  binit(char *);
44static void  bput(const char *, unsigned int);
45static char *ccval(const struct cchar *, int);
46
47void
48print(struct termios *tp, struct winsize *wp, int ldisc, enum FMT fmt)
49{
50	const struct cchar *p;
51	long tmp;
52	u_char *cc;
53	int cnt, ispeed, ospeed;
54	char buf1[100], buf2[100];
55
56	cnt = 0;
57
58	/* Line discipline. */
59	if (ldisc != TTYDISC) {
60		switch(ldisc) {
61		case PPPDISC:
62			cnt += printf("ppp disc; ");
63			break;
64		case NMEADISC:
65			cnt += printf("nmea disc; ");
66			break;
67		default:
68			cnt += printf("#%d disc; ", ldisc);
69			break;
70		}
71	}
72
73	/* Line speed. */
74	ispeed = cfgetispeed(tp);
75	ospeed = cfgetospeed(tp);
76	if (ispeed != ospeed)
77		cnt +=
78		    printf("ispeed %d baud; ospeed %d baud;", ispeed, ospeed);
79	else
80		cnt += printf("speed %d baud;", ispeed);
81	if (fmt >= BSD)
82		cnt += printf(" %d rows; %d columns;", wp->ws_row, wp->ws_col);
83	if (cnt)
84		(void)printf("\n");
85
86#define	on(f)	((tmp&f) != 0)
87#define put(n, f, d) \
88	if (fmt >= BSD || on(f) != d) \
89		bput(n, on(f));
90
91	/* "local" flags */
92	tmp = tp->c_lflag;
93	binit("lflags");
94	put("-icanon", ICANON, 1);
95	put("-isig", ISIG, 1);
96	put("-iexten", IEXTEN, 1);
97	put("-echo", ECHO, 1);
98	put("-echoe", ECHOE, 0);
99	put("-echok", ECHOK, 0);
100	put("-echoke", ECHOKE, 0);
101	put("-echonl", ECHONL, 0);
102	put("-echoctl", ECHOCTL, 0);
103	put("-echoprt", ECHOPRT, 0);
104	put("-altwerase", ALTWERASE, 0);
105	put("-noflsh", NOFLSH, 0);
106	put("-tostop", TOSTOP, 0);
107	put("-flusho", FLUSHO, 0);
108	put("-pendin", PENDIN, 0);
109	put("-nokerninfo", NOKERNINFO, 0);
110	put("-extproc", EXTPROC, 0);
111	put("-xcase", XCASE, 0);
112
113	/* input flags */
114	tmp = tp->c_iflag;
115	binit("iflags");
116	put("-istrip", ISTRIP, 0);
117	put("-icrnl", ICRNL, 1);
118	put("-inlcr", INLCR, 0);
119	put("-igncr", IGNCR, 0);
120	put("-iuclc", IUCLC, 0);
121	put("-ixon", IXON, 1);
122	put("-ixoff", IXOFF, 0);
123	put("-ixany", IXANY, 1);
124	put("-imaxbel", IMAXBEL, 1);
125	put("-ignbrk", IGNBRK, 0);
126	put("-brkint", BRKINT, 1);
127	put("-inpck", INPCK, 0);
128	put("-ignpar", IGNPAR, 0);
129	put("-parmrk", PARMRK, 0);
130
131	/* output flags */
132	tmp = tp->c_oflag;
133	binit("oflags");
134	put("-opost", OPOST, 1);
135	put("-onlcr", ONLCR, 1);
136	put("-ocrnl", OCRNL, 0);
137	put("-onocr", ONOCR, 0);
138	put("-onlret", ONLRET, 0);
139	put("-olcuc", OLCUC, 0);
140	put("-oxtabs", OXTABS, 1);
141	put("-onoeot", ONOEOT, 0);
142
143	/* control flags (hardware state) */
144	tmp = tp->c_cflag;
145	binit("cflags");
146	put("-cread", CREAD, 1);
147	switch(tmp&CSIZE) {
148	case CS5:
149		bput("cs5", 0);
150		break;
151	case CS6:
152		bput("cs6", 0);
153		break;
154	case CS7:
155		bput("cs7", 0);
156		break;
157	case CS8:
158		bput("cs8", 0);
159		break;
160	}
161	bput("-parenb", on(PARENB));
162	put("-parodd", PARODD, 0);
163	put("-hupcl", HUPCL, 1);
164	put("-clocal", CLOCAL, 0);
165	put("-cstopb", CSTOPB, 0);
166	put("-crtscts", CRTSCTS, 0);
167	put("-mdmbuf", MDMBUF, 0);
168
169	/* special control characters */
170	cc = tp->c_cc;
171	if (fmt == POSIX) {
172		binit("cchars");
173		for (p = cchars1; p->name; ++p) {
174			(void)snprintf(buf1, sizeof(buf1), "%s = %s;",
175			    p->name, ccval(p, cc[p->sub]));
176			bput(buf1, 0);
177		}
178		binit(NULL);
179	} else {
180		binit(NULL);
181		for (p = cchars1, cnt = 0; p->name; ++p) {
182			if (fmt != BSD && cc[p->sub] == p->def)
183				continue;
184#define	WD	"%-8s"
185			(void)snprintf(buf1 + cnt * 8, sizeof(buf1) - cnt * 8,
186			    WD, p->name);
187			(void)snprintf(buf2 + cnt * 8, sizeof(buf2) - cnt * 8,
188			    WD, ccval(p, cc[p->sub]));
189			if (++cnt == LINELENGTH / 8) {
190				cnt = 0;
191				(void)printf("%s\n", buf1);
192				(void)printf("%s\n", buf2);
193			}
194		}
195		if (cnt) {
196			(void)printf("%s\n", buf1);
197			(void)printf("%s\n", buf2);
198		}
199	}
200}
201
202static int col;
203static char *label;
204
205static void
206binit(char *lb)
207{
208
209	if (col) {
210		(void)printf("\n");
211		col = 0;
212	}
213	label = lb;
214}
215
216static void
217bput(const char *s, unsigned int off)
218{
219	s += off;
220
221	if (col == 0) {
222		col = printf("%s: %s", label, s);
223		return;
224	}
225	if ((col + strlen(s)) > LINELENGTH) {
226		(void)printf("\n\t");
227		col = printf("%s", s) + 8;
228		return;
229	}
230	col += printf(" %s", s);
231}
232
233static char *
234ccval(const struct cchar *p, int c)
235{
236	static char buf[5];
237	char *bp;
238
239	if (p->sub == VMIN || p->sub == VTIME) {
240		(void)snprintf(buf, sizeof(buf), "%d", c);
241		return (buf);
242	}
243	if (c == _POSIX_VDISABLE)
244		return ("<undef>");
245	bp = buf;
246	if (c & 0200) {
247		*bp++ = 'M';
248		*bp++ = '-';
249		c &= 0177;
250	}
251	if (c == 0177) {
252		*bp++ = '^';
253		*bp++ = '?';
254	}
255	else if (c < 040) {
256		*bp++ = '^';
257		*bp++ = c + '@';
258	}
259	else
260		*bp++ = c;
261	*bp = '\0';
262	return (buf);
263}
264