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