138494Sobrien/*-
2310490Scy * Copyright (c) 1991, 1993, 1994
338494Sobrien *	The Regents of the University of California.  All rights reserved.
438494Sobrien *
538494Sobrien * Redistribution and use in source and binary forms, with or without
638494Sobrien * modification, are permitted provided that the following conditions
738494Sobrien * are met:
838494Sobrien * 1. Redistributions of source code must retain the above copyright
938494Sobrien *    notice, this list of conditions and the following disclaimer.
1038494Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1138494Sobrien *    notice, this list of conditions and the following disclaimer in the
1238494Sobrien *    documentation and/or other materials provided with the distribution.
1338494Sobrien * 3. Neither the name of the University nor the names of its contributors
1438494Sobrien *    may be used to endorse or promote products derived from this software
1538494Sobrien *    without specific prior written permission.
1638494Sobrien *
1738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19310490Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2038494Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2738494Sobrien * SUCH DAMAGE.
2838494Sobrien */
2938494Sobrien
3038494Sobrien#include <sys/types.h>
3138494Sobrien
3238494Sobrien#include <stddef.h>
3338494Sobrien#include <stdio.h>
3438494Sobrien#include <string.h>
3538494Sobrien
36174294Sobrien#include "stty.h"
3738494Sobrien#include "extern.h"
3838494Sobrien
3938494Sobrienstatic void  binit(const char *);
4038494Sobrienstatic void  bput(const char *);
4138494Sobrienstatic const char *ccval(struct cchar *, int);
4238494Sobrien
4338494Sobrienvoid
4438494Sobrienprint(struct termios *tp, struct winsize *wp, int ldisc, enum FMT fmt)
4538494Sobrien{
4638494Sobrien	struct cchar *p;
4738494Sobrien	long tmp;
4838494Sobrien	u_char *cc;
4938494Sobrien	int cnt, ispeed, ospeed;
5038494Sobrien	char buf1[100], buf2[100];
5138494Sobrien
5238494Sobrien	cnt = 0;
5338494Sobrien
5438494Sobrien	/* Line discipline. */
5538494Sobrien	if (ldisc != TTYDISC) {
5638494Sobrien		switch(ldisc) {
5738494Sobrien		case SLIPDISC:
5838494Sobrien			cnt += printf("slip disc; ");
5938494Sobrien			break;
6038494Sobrien		case PPPDISC:
6138494Sobrien			cnt += printf("ppp disc; ");
6238494Sobrien			break;
6338494Sobrien		default:
6438494Sobrien			cnt += printf("#%d disc; ", ldisc);
6538494Sobrien			break;
6638494Sobrien		}
6738494Sobrien	}
6838494Sobrien
6938494Sobrien	/* Line speed. */
7038494Sobrien	ispeed = cfgetispeed(tp);
7138494Sobrien	ospeed = cfgetospeed(tp);
7238494Sobrien	if (ispeed != ospeed)
7338494Sobrien		cnt +=
7438494Sobrien		    printf("ispeed %d baud; ospeed %d baud;", ispeed, ospeed);
7538494Sobrien	else
7638494Sobrien		cnt += printf("speed %d baud;", ispeed);
7738494Sobrien	if (fmt >= BSD)
7838494Sobrien		cnt += printf(" %d rows; %d columns;", wp->ws_row, wp->ws_col);
79174294Sobrien	if (cnt)
8038494Sobrien		(void)printf("\n");
8182794Sobrien
8282794Sobrien#define	on(f)	((tmp & (f)) != 0)
8382794Sobrien#define put(n, f, d) \
8482794Sobrien	if (fmt >= BSD || on(f) != (d)) \
8538494Sobrien		bput((n) + on(f));
8638494Sobrien
8738494Sobrien	/* "local" flags */
8838494Sobrien	tmp = tp->c_lflag;
8982794Sobrien	binit("lflags");
9082794Sobrien	put("-icanon", ICANON, 1);
91119679Smbr	put("-isig", ISIG, 1);
9282794Sobrien	put("-iexten", IEXTEN, 1);
9382794Sobrien	put("-echo", ECHO, 1);
9482794Sobrien	put("-echoe", ECHOE, 0);
9538494Sobrien	put("-echok", ECHOK, 0);
9638494Sobrien	put("-echoke", ECHOKE, 0);
9738494Sobrien	put("-echonl", ECHONL, 0);
9838494Sobrien	put("-echoctl", ECHOCTL, 0);
9938494Sobrien	put("-echoprt", ECHOPRT, 0);
10038494Sobrien	put("-altwerase", ALTWERASE, 0);
10138494Sobrien	put("-noflsh", NOFLSH, 0);
10238494Sobrien	put("-tostop", TOSTOP, 0);
103310490Scy	put("-flusho", FLUSHO, 0);
10482794Sobrien	put("-pendin", PENDIN, 0);
10538494Sobrien	put("-nokerninfo", NOKERNINFO, 0);
10638494Sobrien	put("-extproc", EXTPROC, 0);
10738494Sobrien
10838494Sobrien	/* input flags */
10938494Sobrien	tmp = tp->c_iflag;
11038494Sobrien	binit("iflags");
11138494Sobrien	put("-istrip", ISTRIP, 0);
11238494Sobrien	put("-icrnl", ICRNL, 1);
11338494Sobrien	put("-inlcr", INLCR, 0);
114310490Scy	put("-igncr", IGNCR, 0);
11538494Sobrien	put("-ixon", IXON, 1);
11638494Sobrien	put("-ixoff", IXOFF, 0);
11738494Sobrien	put("-ixany", IXANY, 1);
11838494Sobrien	put("-imaxbel", IMAXBEL, 1);
11938494Sobrien	put("-ignbrk", IGNBRK, 0);
12038494Sobrien	put("-brkint", BRKINT, 1);
12138494Sobrien	put("-inpck", INPCK, 0);
12238494Sobrien	put("-ignpar", IGNPAR, 0);
123310490Scy	put("-parmrk", PARMRK, 0);
12438494Sobrien	put("-iutf8", IUTF8, 1);
12538494Sobrien
12638494Sobrien	/* output flags */
12738494Sobrien	tmp = tp->c_oflag;
12838494Sobrien	binit("oflags");
12938494Sobrien	put("-opost", OPOST, 1);
13038494Sobrien	put("-onlcr", ONLCR, 1);
13138494Sobrien	put("-ocrnl", OCRNL, 0);
13238494Sobrien	switch(tmp&TABDLY) {
133	case TAB0:
134		bput("tab0");
135		break;
136	case TAB3:
137		bput("tab3");
138		break;
139	}
140	put("-onocr", ONOCR, 0);
141	put("-onlret", ONLRET, 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");
150		break;
151	case CS6:
152		bput("cs6");
153		break;
154	case CS7:
155		bput("cs7");
156		break;
157	case CS8:
158		bput("cs8");
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	switch(tmp & (CCTS_OFLOW | CRTS_IFLOW)) {
167	case CCTS_OFLOW:
168		bput("ctsflow");
169		break;
170	case CRTS_IFLOW:
171		bput("rtsflow");
172		break;
173	default:
174		put("-crtscts", CCTS_OFLOW | CRTS_IFLOW, 0);
175		break;
176	}
177	put("-dsrflow", CDSR_OFLOW, 0);
178	put("-dtrflow", CDTR_IFLOW, 0);
179	put("-mdmbuf", MDMBUF, 0);	/* XXX mdmbuf ==  dtrflow */
180	if (on(CNO_RTSDTR))
181		bput("-rtsdtr");
182	else {
183		if (fmt >= BSD)
184			bput("rtsdtr");
185	}
186
187	/* special control characters */
188	cc = tp->c_cc;
189	if (fmt == POSIX) {
190		binit("cchars");
191		for (p = cchars1; p->name; ++p) {
192			(void)snprintf(buf1, sizeof(buf1), "%s = %s;",
193			    p->name, ccval(p, cc[p->sub]));
194			bput(buf1);
195		}
196		binit(NULL);
197	} else {
198		binit(NULL);
199		for (p = cchars1, cnt = 0; p->name; ++p) {
200			if (fmt != BSD && cc[p->sub] == p->def)
201				continue;
202#define	WD	"%-8s"
203			(void)snprintf(buf1 + cnt * 8, sizeof(buf1) - cnt * 8,
204			    WD, p->name);
205			(void)snprintf(buf2 + cnt * 8, sizeof(buf2) - cnt * 8,
206			    WD, ccval(p, cc[p->sub]));
207			if (++cnt == LINELENGTH / 8) {
208				cnt = 0;
209				(void)printf("%s\n", buf1);
210				(void)printf("%s\n", buf2);
211			}
212		}
213		if (cnt) {
214			(void)printf("%s\n", buf1);
215			(void)printf("%s\n", buf2);
216		}
217	}
218}
219
220static int col;
221static const char *label;
222
223static void
224binit(const char *lb)
225{
226
227	if (col) {
228		(void)printf("\n");
229		col = 0;
230	}
231	label = lb;
232}
233
234static void
235bput(const char *s)
236{
237
238	if (col == 0) {
239		col = printf("%s: %s", label, s);
240		return;
241	}
242	if ((col + strlen(s)) > LINELENGTH) {
243		(void)printf("\n\t");
244		col = printf("%s", s) + 8;
245		return;
246	}
247	col += printf(" %s", s);
248}
249
250static const char *
251ccval(struct cchar *p, int c)
252{
253	static char buf[5];
254	char *bp;
255
256	if (p->sub == VMIN || p->sub == VTIME) {
257		(void)snprintf(buf, sizeof(buf), "%d", c);
258		return (buf);
259	}
260	if (c == _POSIX_VDISABLE)
261		return ("<undef>");
262	bp = buf;
263	if (c & 0200) {
264		*bp++ = 'M';
265		*bp++ = '-';
266		c &= 0177;
267	}
268	if (c == 0177) {
269		*bp++ = '^';
270		*bp++ = '?';
271	}
272	else if (c < 040) {
273		*bp++ = '^';
274		*bp++ = c + '@';
275	}
276	else
277		*bp++ = c;
278	*bp = '\0';
279	return (buf);
280}
281