fix errno scoping for ANSI C
[unix-history] / usr / src / bin / stty / stty.c
CommitLineData
18949a0b 1/*
c086ab51 2 * Copyright (c) 1980, 1989 Regents of the University of California.
18949a0b
DF
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
ba3dc8b4 7#ifndef lint
18949a0b 8char copyright[] =
c086ab51 9"@(#) Copyright (c) 1980, 1989 Regents of the University of California.\n\
18949a0b
DF
10 All rights reserved.\n";
11#endif not lint
12
13#ifndef lint
6b85d402 14static char sccsid[] = "@(#)stty.c 5.10 (Berkeley) %G%";
18949a0b
DF
15#endif not lint
16
16b6b22b
BJ
17/*
18 * set teletype modes
19 */
20
2ea9e68e
MT
21#include <sys/types.h>
22#include <sys/stat.h>
4f05342b 23#include <sys/ioctl.h>
2ea9e68e
MT
24#include <sys/syslog.h>
25#define KERNEL
26#include <sys/tty.h>
27#undef KERNEL
28#include <sys/termios.h>
29#include <sys/file.h>
30#include <errno.h>
31#include <ctype.h>
14fd0bf8 32#include <stdio.h>
16b6b22b 33
b24648a6 34#define eq(s1, s2) (strcmp((s1), (s2)) == 0)
2ea9e68e 35#define WRAPCOL 65
2ea9e68e 36
b24648a6 37struct modes {
2ea9e68e
MT
38 char *name;
39 long set;
40 long unset;
41};
42
b24648a6 43struct modes imodes[] = {
2ea9e68e
MT
44 "ignbrk", IGNBRK, 0,
45 "-ignbrk", 0, IGNBRK,
46 "brkint", BRKINT, 0,
47 "-brkint", 0, BRKINT,
48 "ignpar", IGNPAR, 0,
49 "-ignpar", 0, IGNPAR,
50 "parmrk", PARMRK, 0,
51 "-parmrk", 0, PARMRK,
52 "inpck", INPCK, 0,
53 "-inpck", 0, INPCK,
54 "istrip", ISTRIP, 0,
55 "-istrip", 0, ISTRIP,
56 "inlcr", INLCR, 0,
57 "-inlcr", 0, INLCR,
58 "igncr", IGNCR, 0,
59 "-igncr", 0, IGNCR,
60 "icrnl", ICRNL, 0,
61 "-icrnl", 0, ICRNL,
62 "ixon", IXON, 0,
63 "-ixon", 0, IXON,
64 "flow", IXON, 0,
65 "-flow", 0, IXON,
66 "ixoff", IXOFF, 0,
67 "-ixoff", 0, IXOFF,
68 "tandem", IXOFF, 0,
69 "-tandem", 0, IXOFF,
70 "ixany", IXANY, 0,
71 "-ixany", 0, IXANY,
72 "decctlq", 0, IXANY,
73 "-decctlq", IXANY, 0,
74 "imaxbel", IMAXBEL, 0,
75 "-imaxbel", 0, IMAXBEL,
76 0
77};
78
b24648a6 79struct modes omodes[] = {
2ea9e68e
MT
80 "opost", OPOST, 0,
81 "-opost", 0, OPOST,
82 "-litout", OPOST, 0,
83 "litout", 0, OPOST,
84 "onlcr", ONLCR, 0,
85 "-onlcr", 0, ONLCR,
86 "tabs", 0, OXTABS, /* "preserve" tabs */
87 "-tabs", OXTABS, 0,
6b85d402
MT
88 "xtabs", OXTABS, 0,
89 "-xtabs", 0, OXTABS,
2ea9e68e
MT
90 "oxtabs", OXTABS, 0,
91 "-oxtabs", 0, OXTABS,
92 0
16b6b22b
BJ
93};
94
b24648a6 95struct modes cmodes[] = {
2ea9e68e
MT
96 "cs5", CS5, CSIZE,
97 "cs6", CS6, CSIZE,
98 "cs7", CS7, CSIZE,
99 "cs8", CS8, CSIZE,
100 "cstopb", CSTOPB, 0,
101 "-cstopb", 0, CSTOPB,
102 "cread", CREAD, 0,
103 "-cread", 0, CREAD,
104 "parenb", PARENB, 0,
105 "-parenb", 0, PARENB,
106 "parodd", PARODD, 0,
107 "-parodd", 0, PARODD,
108 "parity", PARENB | CS7, PARODD | CSIZE,
109 "evenp", PARENB | CS7, PARODD | CSIZE,
110 "oddp", PARENB | CS7 | PARODD, CSIZE,
111 "-parity", CS8, PARODD | PARENB | CSIZE,
c086ab51 112 "pass8", CS8, PARODD | PARENB | CSIZE,
2ea9e68e
MT
113 "-evenp", CS8, PARODD | PARENB | CSIZE,
114 "-oddp", CS8, PARODD | PARENB | CSIZE,
115 "hupcl", HUPCL, 0,
116 "-hupcl", 0, HUPCL,
117 "hup", HUPCL, 0,
118 "-hup", 0, HUPCL,
119 "clocal", CLOCAL, 0,
120 "-clocal", 0, CLOCAL,
121 "crtscts", CRTSCTS, 0,
122 "-crtscts", 0, CRTSCTS,
16b6b22b
BJ
123 0
124};
16b6b22b 125
b24648a6 126struct modes lmodes[] = {
2ea9e68e
MT
127 "echo", ECHO, 0,
128 "-echo", 0, ECHO,
129 "echoe", ECHOE, 0,
130 "-echoe", 0, ECHOE,
131 "crterase", ECHOE, 0,
132 "-crterase", 0, ECHOE,
133 "crtbs", ECHOE, 0, /* crtbs not supported, close enough */
134 "-crtbs", 0, ECHOE,
135 "echok", ECHOK, 0,
136 "-echok", 0, ECHOK,
137 "echoke", ECHOKE, 0,
138 "-echoke", 0, ECHOKE,
139 "crtkill", ECHOKE, 0,
140 "-crtkill", 0, ECHOKE,
141 "altwerase", ALTWERASE, 0,
142 "-altwerase", 0, ALTWERASE,
143 "iexten", IEXTEN, 0,
144 "-iexten", 0, IEXTEN,
145 "echonl", ECHONL, 0,
146 "-echonl", 0, ECHONL,
147 "echoctl", ECHOCTL, 0,
148 "-echoctl", 0, ECHOCTL,
149 "ctlecho", ECHOCTL, 0,
150 "-ctlecho", 0, ECHOCTL,
151 "echoprt", ECHOPRT, 0,
152 "-echoprt", 0, ECHOPRT,
153 "prterase", ECHOPRT, 0,
154 "-prterase", 0, ECHOPRT,
155 "isig", ISIG, 0,
156 "-isig", 0, ISIG,
157 "icanon", ICANON, 0,
158 "-icanon", 0, ICANON,
159 "noflsh", NOFLSH, 0,
160 "-noflsh", 0, NOFLSH,
161 "tostop", TOSTOP, 0,
162 "-tostop", 0, TOSTOP,
163 "mdmbuf", MDMBUF, 0,
164 "-mdmbuf", 0, MDMBUF,
165 "nohang", NOHANG, 0,
166 "-nohang", 0, NOHANG,
167 "flusho", FLUSHO, 0,
168 "-flusho", 0, FLUSHO,
169 "pendin", PENDIN, 0,
170 "-pendin", 0, PENDIN,
171 "crt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT,
172 "-crt", ECHOK, ECHOE|ECHOKE|ECHOCTL,
173 "newcrt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT,
174 "-newcrt", ECHOK, ECHOE|ECHOKE|ECHOCTL,
175 0
176};
177
178/*
179 * Special control characters.
180 *
181 * Each entry has a list of names. The first is the primary name
182 * and is used when printing the control character in the "name = val;"
183 * form. The second is an abbreviation which is guaranteed to be less
184 * than or equal to four characters in length and is primarily used
185 * when printing the values in columunar form (guarantees all will
186 * fit within 80 cols). The rest are optional aliases.
187 * All names are recognized on the command line.
188 */
b24648a6
MT
189#define MAXNAMES 3
190struct {
6b85d402 191 char *names[MAXNAMES+1];
2ea9e68e
MT
192 int sub;
193 u_char def;
194} cchars[] = {
195 { "erase", "era" }, VERASE, CERASE,
196 { "werase", "wera" }, VWERASE, CWERASE,
197 { "kill", "kill" }, VKILL, CKILL,
198 { "intr", "int" }, VINTR, CINTR,
199 { "quit", "quit" }, VQUIT, CQUIT,
200 { "susp", "susp" }, VSUSP, CSUSP,
201 { "dsusp", "dsus" }, VDSUSP, CDSUSP,
202 { "eof", "eof" }, VEOF, CEOF,
203 { "eol", "eol", "brk" }, VEOL, CEOL,
204 { "eol2", "eol2" }, VEOL2, CEOL,
205 { "stop", "stop", "xoff" }, VSTOP, CSTOP,
206 { "start", "star", "xon" }, VSTART, CSTART,
207 { "lnext", "lnxt" }, VLNEXT, CLNEXT,
208 { "flusho", "fls", "flush" }, VFLUSHO, CFLUSHO,
209 { "reprint", "rpnt", "rprnt" }, VREPRINT, CREPRINT,
c086ab51 210 { "info", "info" }, VINFO, CINFO,
2ea9e68e
MT
211 0
212};
213
b24648a6
MT
214struct winsize win;
215int ldisc;
216int dodisc;
217int debug = 0;
218int trace, dotrace;
2ea9e68e
MT
219
220#define OUT stdout /* informational output stream */
221#define ERR stderr /* error message stream */
222#define CTL 0 /* default control descriptor */
b24648a6 223int ctl = CTL;
2ea9e68e
MT
224
225extern errno;
2ea9e68e
MT
226
227#define NORMAL 0 /* only print modes differing from defaults */
228#define ALL 1 /* print all modes - POSIX standard format */
229#define ALL_BSD 2 /* print all modes - using BSD shorthand for cc's */
230#define GFMT 3 /* print modes in a form that can be re-input to stty */
231
b24648a6 232
2ea9e68e
MT
233main(argc, argv)
234 char *argv[];
16b6b22b 235{
2ea9e68e
MT
236 struct termios t;
237 int i, fmt = NORMAL;
238 extern char *optarg;
239 extern int optind;
240 int ch;
241
242 argc--, argv++;
243 if (argc > 0 && eq(argv[0], "-a")) {
244 fmt = ALL;
245 argc--, argv++;
16b6b22b 246 }
2ea9e68e
MT
247 if (argc > 0 && eq(argv[0], "-f")) {
248 argc--, argv++;
249 if ((ctl = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0)
250 syserrexit(*argv);
251 argc--, argv++;
16b6b22b 252 }
2ea9e68e
MT
253 if (ioctl(ctl, TIOCGETD, &ldisc) < 0)
254 syserrexit("TIOCGETD");
255 if (tcgetattr(ctl, &t) < 0)
256 syserrexit("tcgetattr");
257 if (ioctl(ctl, TIOCGWINSZ, &win) < 0)
b24648a6 258 warning("TIOCGWINSZ: %s", strerror(errno));
2ea9e68e 259 checkredirect(); /* conversion aid */
2ea9e68e
MT
260
261 if (argc == 0 || fmt) {
262 prmode(&t, ldisc, fmt);
ba3dc8b4 263 exit(0);
2ea9e68e
MT
264 } else if (argc == 1 && strlen(argv[0]) > 2 && *(argv[0]+2) == ':') {
265 gfmtset(argv[0]);
266 goto setit;
ba3dc8b4 267 }
2ea9e68e
MT
268
269 while (*argv) {
270 if (eq("everything", *argv)) {
271 prmode(&t, ldisc, ALL_BSD);
272 exit(0);
16b6b22b 273 }
2ea9e68e
MT
274 if (eq("all", *argv)) {
275 prmode(&t, ldisc, ALL);
276 exit(0);
16b6b22b 277 }
2ea9e68e
MT
278 if (eq("old", *argv)) {
279 goto next;
16b6b22b 280 }
2ea9e68e
MT
281 if (eq("new", *argv)) {
282 goto next;
16b6b22b 283 }
2ea9e68e
MT
284 if (eq("nl", *argv)) {
285 t.c_iflag &= ~ICRNL;
286 t.c_oflag &= ~ONLCR;
287 goto next;
5e9810bc 288 }
2ea9e68e
MT
289 if (eq("-nl", *argv)) {
290 t.c_iflag |= ICRNL;
291 t.c_oflag |= ONLCR;
292 goto next;
16b6b22b 293 }
2ea9e68e
MT
294 if (eq("dec", *argv)){
295 t.c_cc[VERASE] = (u_char)0177;
296 t.c_cc[VKILL] = CTRL('u');
297 t.c_cc[VINTR] = CTRL('c');
298 t.c_lflag &= ~ECHOPRT;
299 t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
300 t.c_iflag &= ~IXANY;
301 goto next;
16b6b22b 302 }
c086ab51
MK
303 if (eq("raw", *argv)) {
304 cfmakeraw(&t);
305 t.c_cflag &= ~(CSIZE|PARENB);
306 t.c_cflag |= CS8;
307 goto next;
308 }
309 if (eq("cooked", *argv) || eq("-raw", *argv) ||
310 eq("sane", *argv)) {
311 t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL);
312 t.c_iflag = TTYDEF_IFLAG;
313 t.c_iflag |= ICRNL;
314 /* preserve user-preference flags in lflag */
315#define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
316 t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP);
317 t.c_oflag = TTYDEF_OFLAG;
c086ab51
MK
318 goto next;
319 }
2ea9e68e
MT
320 if (eq("rows", *argv)) {
321 if (*(argv+1) == 0)
322 goto setit;
4f05342b 323 win.ws_row = atoi(*++argv);
2ea9e68e
MT
324 goto next;
325 }
326 if (eq("ispeed", *argv)) {
327 int code;
328 if (*(argv+1) == 0)
329 errexit("missing ispeed");
330 cfsetispeed(&t, atoi(*++argv));
331 goto next;
332 }
333 if (eq("ospeed", *argv)) {
2ea9e68e
MT
334 if (*(argv+1) == 0)
335 errexit("missing ospeed");
336 cfsetospeed(&t, atoi(*++argv));
337 goto next;
4f05342b 338 }
2ea9e68e
MT
339 if (eq("cols", *argv) || eq("columns", *argv)) {
340 if (*(argv+1) == 0)
341 goto setit;
4f05342b 342 win.ws_col = atoi(*++argv);
2ea9e68e 343 goto next;
4f05342b 344 }
2ea9e68e
MT
345 if (eq("size", *argv)) {
346 put("%d %d\n", win.ws_row, win.ws_col);
d6f0b7e6
MK
347 exit(0);
348 }
2ea9e68e
MT
349 if (eq("speed", *argv)) {
350 put("%d\n", cfgetospeed(&t));
351 exit(0);
352 }
353 for (i=0; imodes[i].name; i++)
354 if (eq(imodes[i].name, *argv)) {
355 t.c_iflag &= ~imodes[i].unset;
356 t.c_iflag |= imodes[i].set;
357 goto next;
358 }
359 for (i=0; omodes[i].name; i++)
360 if (eq(omodes[i].name, *argv)) {
361 t.c_oflag &= ~omodes[i].unset;
362 t.c_oflag |= omodes[i].set;
363 goto next;
16b6b22b 364 }
2ea9e68e
MT
365 for (i=0; cmodes[i].name; i++)
366 if (eq(cmodes[i].name, *argv)) {
367 t.c_cflag &= ~cmodes[i].unset;
368 t.c_cflag |= cmodes[i].set;
369 goto next;
370 }
371 for (i=0; lmodes[i].name; i++)
372 if (eq(lmodes[i].name, *argv)) {
373 t.c_lflag &= ~lmodes[i].unset;
374 t.c_lflag |= lmodes[i].set;
375 goto next;
376 }
377 for (i=0; *cchars[i].names; i++) {
378 char **cp = cchars[i].names;
379 while (*cp) {
380 if (eq(*cp, *argv)) {
381 if (*++argv == 0)
382 goto setit;
383 if (eq(*argv, "undef") ||
384 eq(*argv, "disable"))
385 t.c_cc[cchars[i].sub] =
386 _POSIX_VDISABLE;
387 else if (**argv == '^')
388 t.c_cc[cchars[i].sub] =
389 ((*argv)[1] == '?') ? 0177 :
390 ((*argv)[1] == '-') ?
391 _POSIX_VDISABLE :
392 (*argv)[1] & 037;
393 else
394 t.c_cc[cchars[i].sub] = **argv;
395 goto next;
16b6b22b 396 }
2ea9e68e 397 cp++;
16b6b22b 398 }
2ea9e68e
MT
399 }
400 if (isdigit(**argv)) {
401 cfsetospeed(&t, atoi(*argv));
402 cfsetispeed(&t, atoi(*argv));
403 goto next;
404 }
405 /* didn't match anything */
406 errexit("unknown option: %s", *argv);
407 exit(1);
408next:
409 argv++;
16b6b22b 410 }
2ea9e68e
MT
411setit:
412 if (tcsetattr(ctl, 0, &t) < 0)
413 syserrexit("tcsetattr");
414 if (ioctl(ctl, TIOCSWINSZ, &win) < 0)
415 warning("can't set window size");
416
417 exit(0);
16b6b22b
BJ
418}
419
2ea9e68e 420gfmtset() {
16b6b22b
BJ
421}
422
2ea9e68e
MT
423prmode(tp, ldisc, fmt)
424 struct termios *tp;
16b6b22b 425{
2ea9e68e
MT
426 long i = tp->c_iflag,
427 o = tp->c_oflag,
428 c = tp->c_cflag,
429 l = tp->c_lflag;
430 u_char *cc = tp->c_cc;
431 int ispeed = cfgetispeed(tp),
432 ospeed = cfgetospeed(tp);
433 char unknown[32],
434 *ld;
435 char *ccval();
436
16b6b22b 437
2ea9e68e
MT
438 /*
439 * line discipline
440 */
441 if (ldisc != TTYDISC) {
442 switch(ldisc) {
443 case TABLDISC:
444 ld = "tablet";
445 break;
446 case SLIPDISC:
b24648a6 447 ld = "slip";
16b6b22b 448 break;
2ea9e68e
MT
449 default:
450 sprintf(unknown, "#%d", ldisc);
451 ld = unknown;
16b6b22b 452 }
2ea9e68e
MT
453 put("%s disc; ", ld);
454 }
455 /*
456 * line speed
457 */
458 if (ispeed != ospeed)
459 put("ispeed %d baud; ospeed %d baud;",
460 ispeed, ospeed);
461 else
462 put("speed %d baud;", ispeed);
463 if (fmt)
464 put(" %d rows; %d columns;", win.ws_row, win.ws_col);
465 put("\n");
466
467#define lput(n, f, d) if (fmt || on(f) != d) mdput(n+on(f))
468 /*
469 * "local" flags
470 */
471#define on(f) ((l&f) != 0)
472 if (debug) mdput("LFLAG: ");
473 lput("-icanon ",ICANON, 1);
474 lput("-isig ", ISIG, 1);
475 lput("-iexten ", IEXTEN, 1);
476 lput("-echo ",ECHO, 1);
477 lput("-echoe ",ECHOE, 0);
478 lput("-echok ",ECHOK, 0);
479 lput("-echoke ",ECHOKE, 0);
480 lput("-echonl ",ECHONL, 0);
481 lput("-echoctl ",ECHOCTL, 0);
482 lput("-echoprt ",ECHOPRT, 0);
483 lput("-altwerase ",ALTWERASE, 0);
484 lput("-noflsh ",NOFLSH, 0);
485 lput("-tostop ",TOSTOP, 0);
486 lput("-mdmbuf ",MDMBUF, 0);
487 lput("-nohang ",NOHANG, 0);
488 lput("-flusho ",FLUSHO, 0);
489 lput("-pendin ",PENDIN, 0);
490 /*
491 * input flags
492 */
493#undef on
494#define on(f) ((i&f) != 0)
495 mdput(0);
496 if (debug) mdput("IFLAG: ");
497 lput("-istrip ", ISTRIP, 0);
498 lput("-icrnl ", ICRNL, 1);
499 lput("-inlcr ", INLCR, 0);
500 lput("-igncr ", IGNCR, 0);
501 lput("-ixon ", IXON, 1);
502 lput("-ixoff ", IXOFF, 0);
503 lput("-ixany ", IXANY, 1);
504 lput("-imaxbel ", IMAXBEL, 1);
505 lput("-ignbrk ", IGNBRK, 0);
506 lput("-brkint ", BRKINT, 1);
507 lput("-inpck ", INPCK, 0);
508 lput("-ignpar ", IGNPAR, 0);
509 lput("-parmrk ", PARMRK, 0);
510#undef on
511 /*
512 * output flags
513 */
514#define on(f) ((o&f) != 0)
515 mdput(0);
516 if (debug) mdput("OFLAG: ");
517 lput("-opost ", OPOST, 1);
518 lput("-onlcr ", ONLCR, 1);
519 lput("-oxtabs ", OXTABS, 1);
520#undef on
521 /*
522 * control flags (hardware state)
523 */
524#define on(f) ((c&f) != 0)
525 mdput(0);
526 if (debug) mdput("CFLAG: ");
527 lput("-cread ", CREAD, 1);
528 switch(c&CSIZE) {
529 case CS5: mdput("cs5 "); break;
530 case CS6: mdput("cs6 "); break;
531 case CS7: mdput("cs7 "); break;
532 case CS8: mdput("cs8 "); break;
533 }
534 mdput("-parenb "+on(PARENB));
535 lput("-parodd ", PARODD, 0);
536 lput("-hupcl ", HUPCL, 1);
537 lput("-clocal ", CLOCAL, 0);
538 lput("-cstopb ", CSTOPB, 0);
539 lput("-crtscts ", CRTSCTS, 0);
540 mdput(0);
541#undef on
542 /*
543 * special control characters
544 */
545 if (debug) mdput("CCHARS: ");
546 if (fmt != 2) {
547 for (i=0; *cchars[i].names; i++) {
548 char temp[64];
549
550 if (fmt || cc[cchars[i].sub] != cchars[i].def) {
551 sprintf(temp, "%s = %s; ", *cchars[i].names,
552 ccval(cc[cchars[i].sub]), fmt);
553 mdput(temp);
554 }
16b6b22b 555 }
2ea9e68e
MT
556 mdput(0);
557 } else {
558 for (i=0; *cchars[i].names; i++)
559 put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0),
560 *(cchars[i].names+1));
561 printf("\n");
562 for (i=0; *cchars[i].names; i++)
563 put("%*s", strlen(*(cchars[i].names+1)) + (i>0?1:0),
564 ccval(cc[cchars[i].sub], fmt));
565 printf("\n");
16b6b22b
BJ
566 }
567}
568
2ea9e68e
MT
569/*
570 * gross, but since we're changing the control descriptor
571 * from 1 to 0, most users will be probably be doing
572 * "stty > /dev/sometty" by accident. If 1 and 2 are both ttys,
573 * but not the same, assume that 1 was incorrectly redirected.
574 */
575checkredirect() {
576 struct stat st1, st2;
577
578 if (isatty(1) && isatty(2) && fstat(1, &st1) != -1 &&
579 fstat(2, &st2) != -1 && (st1.st_rdev != st2.st_rdev))
580warning("stdout appears redirected, but stdin is the control descriptor");
581}
2ea9e68e 582
b24648a6 583char *
2ea9e68e
MT
584ccval(c, fmt)
585 unsigned char c;
16b6b22b 586{
2ea9e68e
MT
587 static char buf[128];
588 char *bp;
589
590 *buf = 0, bp = buf;
591 if (c == _POSIX_VDISABLE)
592 if (fmt == 2)
593 return("<u>");
594 else
595 return("<undef>");
596 if (c & 0200) {
597 strcat(buf, "M-");
598 *bp++ = 'M';
599 *bp++ = '-';
600 c &= 0177;
601 }
602 if (c == 0177) {
603 *bp++ = '^';
604 *bp++ = '?';
16b6b22b 605 }
2ea9e68e
MT
606 else if (c < 040) {
607 *bp++ = '^';
608 *bp++ = c + '@';
16b6b22b 609 }
2ea9e68e
MT
610 else
611 *bp++ = c;
612 *bp = 0;
613 return(buf);
16b6b22b
BJ
614}
615
b24648a6 616
2ea9e68e
MT
617mdput(s)
618 char *s;
16b6b22b 619{
2ea9e68e 620 static int col = 0;
16b6b22b 621
2ea9e68e
MT
622 if (s == (char *)0) {
623 if (col) {
624 put("\n");
625 col = 0;
626 }
16b6b22b
BJ
627 return;
628 }
2ea9e68e
MT
629 if ((col += strlen(s)) > WRAPCOL) {
630 put("\n");
631 col = strlen(s);
16b6b22b 632 }
2ea9e68e 633 put(s);
16b6b22b
BJ
634}
635
b24648a6
MT
636#include <varargs.h>
637
638put(va_alist)
639 va_dcl
16b6b22b 640{
b24648a6
MT
641 char *fmt;
642 va_list ap;
643
644 va_start(ap);
645 fmt = va_arg(ap, char *);
646 (void) vfprintf(OUT, fmt, ap);
647 va_end(ap);
16b6b22b
BJ
648}
649
b24648a6
MT
650
651warning(va_alist)
652 va_dcl
2ea9e68e 653{
b24648a6
MT
654 char *fmt;
655 va_list ap;
656
2ea9e68e 657 fprintf(ERR, "stty: warning: ");
b24648a6
MT
658 va_start(ap);
659 fmt = va_arg(ap, char *);
660 (void) vfprintf(ERR, fmt, ap);
661 va_end(ap);
2ea9e68e
MT
662 fprintf(ERR, "\n");
663}
16b6b22b 664
b24648a6
MT
665
666errexit(va_alist)
667 va_dcl
16b6b22b 668{
b24648a6
MT
669 char *fmt;
670 va_list ap;
671
2ea9e68e 672 fprintf(ERR, "stty: ");
b24648a6
MT
673 va_start(ap);
674 fmt = va_arg(ap, char *);
675 (void) vfprintf(ERR, fmt, ap);
676 va_end(ap);
2ea9e68e
MT
677 fprintf(ERR, "\n");
678 exit(1);
679}
16b6b22b 680
b24648a6
MT
681
682syserrexit(va_alist)
683 va_dcl
2ea9e68e 684{
b24648a6
MT
685 char *fmt;
686 va_list ap;
687
2ea9e68e 688 fprintf(ERR, "stty: ");
b24648a6
MT
689 va_start(ap);
690 fmt = va_arg(ap, char *);
691 (void) vfprintf(ERR, fmt, ap);
692 va_end(ap);
693 fprintf(ERR, ": %s\n", strerror(errno));
2ea9e68e 694 exit(1);
16b6b22b 695}