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