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