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