1 /* $NetBSD: subr.c,v 1.35 2013/08/11 16:36:30 dholland Exp $ */
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "from: @(#)subr.c 8.1 (Berkeley) 6/4/93";
37 __RCSID("$NetBSD: subr.c,v 1.35 2013/08/11 16:36:30 dholland Exp $");
46 #endif /* !defined(__minix) */
47 #include <sys/param.h>
48 #include <sys/ioctl.h>
59 #include "pathnames.h"
61 extern struct termios tmode
, omode
;
64 static void compatflags(long);
65 #endif /* !defined(__minix) */
71 gettable(const char *name
, char *buf
)
75 struct gettyflags
*fp
;
78 dba
[0] = _PATH_GETTYTAB
;
81 if (cgetent(&buf
, dba
, name
) != 0)
84 for (sp
= gettystrs
; sp
->field
; sp
++)
85 (void)cgetstr(buf
, sp
->field
, &sp
->value
);
86 for (np
= gettynums
; np
->field
; np
++) {
87 if (cgetnum(buf
, np
->field
, &n
) == -1)
94 for (fp
= gettyflags
; fp
->field
; fp
++) {
95 if (cgetcap(buf
, fp
->field
, ':') == NULL
)
99 fp
->value
= 1 ^ fp
->invrt
;
103 printf("name=\"%s\", buf=\"%s\"\n", name
, buf
);
104 for (sp
= gettystrs
; sp
->field
; sp
++)
105 printf("cgetstr: %s=%s\n", sp
->field
, sp
->value
);
106 for (np
= gettynums
; np
->field
; np
++)
107 printf("cgetnum: %s=%d\n", np
->field
, np
->value
);
108 for (fp
= gettyflags
; fp
->field
; fp
++)
109 printf("cgetflags: %s='%c' set='%c'\n", fp
->field
,
110 fp
->value
+ '0', fp
->set
+ '0');
118 struct gettystrs
*sp
;
119 struct gettynums
*np
;
120 struct gettyflags
*fp
;
122 for (sp
= gettystrs
; sp
->field
; sp
++)
124 sp
->defalt
= sp
->value
;
125 for (np
= gettynums
; np
->field
; np
++)
127 np
->defalt
= np
->value
;
128 for (fp
= gettyflags
; fp
->field
; fp
++)
130 fp
->defalt
= fp
->value
;
132 fp
->defalt
= fp
->invrt
;
138 struct gettystrs
*sp
;
139 struct gettynums
*np
;
140 struct gettyflags
*fp
;
142 for (sp
= gettystrs
; sp
->field
; sp
++)
144 sp
->value
= sp
->defalt
? estrdup(sp
->defalt
) : NULL
;
145 for (np
= gettynums
; np
->field
; np
++)
147 np
->value
= np
->defalt
;
148 for (fp
= gettyflags
; fp
->field
; fp
++)
150 fp
->value
= fp
->defalt
;
155 &ER
, &KL
, &IN
, &QU
, &XN
, &XF
, &ET
, &BK
,
156 &SU
, &DS
, &RP
, &FL
, &WE
, &LN
, &ST
, &B2
, 0
161 &tmode
.c_cc
[VERASE
], &tmode
.c_cc
[VKILL
], &tmode
.c_cc
[VINTR
],
162 &tmode
.c_cc
[VQUIT
], &tmode
.c_cc
[VSTART
], &tmode
.c_cc
[VSTOP
],
163 &tmode
.c_cc
[VEOF
], &tmode
.c_cc
[VEOL
], &tmode
.c_cc
[VSUSP
],
164 &tmode
.c_cc
[VDSUSP
], &tmode
.c_cc
[VREPRINT
], &tmode
.c_cc
[VDISCARD
],
165 &tmode
.c_cc
[VWERASE
], &tmode
.c_cc
[VLNEXT
], &tmode
.c_cc
[VSTATUS
],
166 &tmode
.c_cc
[VEOL2
], 0
175 for (i
= 0; charnames
[i
]; i
++) {
180 *charvars
[i
] = _POSIX_VDISABLE
;
184 /* Macros to clear/set/test flags. */
185 #define SET(t, f) (t) |= (f)
186 #define CLR(t, f) (t) &= ~(f)
187 #define ISSET(t, f) ((t) & (f))
192 tcflag_t iflag
, oflag
, cflag
, lflag
;
219 if (C0set
&& I0set
&& L0set
&& O0set
) {
228 if (C1set
&& I1set
&& L1set
&& O1set
) {
237 if (C2set
&& I2set
&& L2set
&& O2set
) {
247 iflag
= omode
.c_iflag
;
248 oflag
= omode
.c_oflag
;
249 cflag
= omode
.c_cflag
;
250 lflag
= omode
.c_lflag
;
253 CLR(cflag
, CSIZE
|PARENB
);
255 CLR(iflag
, ISTRIP
|INPCK
|IGNPAR
);
256 } else if (AP
|| EP
|| OP
) {
258 SET(cflag
, CS7
|PARENB
);
261 SET(iflag
, INPCK
|IGNPAR
);
265 } else if (EP
&& !OP
) {
266 SET(iflag
, INPCK
|IGNPAR
);
270 } else if (AP
|| (EP
&& OP
)) {
271 CLR(iflag
, INPCK
|IGNPAR
);
274 } /* else, leave as is */
286 #if !defined(__minix)
291 #endif /* !defined(__minix) */
295 SET(oflag
, ONLCR
|OPOST
);
301 #if !defined(__minix)
303 SET(oflag
, OXTABS
|OPOST
);
306 #endif /* !defined(__minix) */
312 if (n
== 1) { /* read mode flags */
316 CLR(cflag
, CSIZE
|PARENB
);
338 #if !defined(__minix)
348 #endif /* !defined(__minix) */
355 #if !defined(__minix)
360 #endif /* !defined(__minix) */
368 tmode
.c_iflag
= iflag
;
369 tmode
.c_oflag
= oflag
;
370 tmode
.c_cflag
= cflag
;
371 tmode
.c_lflag
= lflag
;
376 * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
379 compatflags(long flags
)
381 tcflag_t iflag
, oflag
, cflag
, lflag
;
383 iflag
= BRKINT
|ICRNL
|IMAXBEL
|IXON
|IXANY
;
384 oflag
= OPOST
|ONLCR
|OXTABS
;
386 lflag
= ICANON
|ISIG
|IEXTEN
;
388 if (ISSET(flags
, TANDEM
))
392 if (ISSET(flags
, ECHO
))
396 if (ISSET(flags
, CRMOD
)) {
403 if (ISSET(flags
, XTABS
))
409 if (ISSET(flags
, RAW
)) {
411 CLR(lflag
, ISIG
|ICANON
|IEXTEN
);
414 SET(iflag
, BRKINT
|IXON
|IMAXBEL
);
415 SET(lflag
, ISIG
|IEXTEN
);
416 if (ISSET(flags
, CBREAK
))
420 switch (ISSET(flags
, ANYP
)) {
441 /* Nothing we can do with CRTBS. */
442 if (ISSET(flags
, PRTERA
))
446 if (ISSET(flags
, CRTERA
))
450 #if !defined(__minix)
451 /* Nothing we can do with TILDE. */
452 if (ISSET(flags
, MDMBUF
))
456 #endif /* !defined(__minix) */
457 if (ISSET(flags
, NOHANG
))
462 #if !defined(__minix)
463 if (ISSET(flags
, CRTKIL
))
467 #endif /* !defined(__minix) */
468 if (ISSET(flags
, CTLECH
))
472 if (!ISSET(flags
, DECCTQ
))
476 CLR(lflag
, TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
);
477 SET(lflag
, ISSET(flags
, TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
));
479 if (ISSET(flags
, RAW
|LITOUT
|PASS8
)) {
482 if (!ISSET(flags
, RAW
|PASS8
))
486 if (!ISSET(flags
, RAW
|LITOUT
))
497 tmode
.c_iflag
= iflag
;
498 tmode
.c_oflag
= oflag
;
499 tmode
.c_cflag
= cflag
;
500 tmode
.c_lflag
= lflag
;
506 unsigned delay
; /* delay in ms */
511 * below are random guesses, I can't be bothered checking
514 struct delayval crdelay
[] = {
523 struct delayval nldelay
[] = {
524 { 1, NL1
}, /* special, calculated */
531 struct delayval bsdelay
[] = {
536 struct delayval ffdelay
[] = {
542 struct delayval tbdelay
[] = {
545 { 3, XTABS
}, /* this is expand tabs */
555 f
= adelay(CD
, crdelay
);
556 f
|= adelay(ND
, nldelay
);
557 f
|= adelay(FD
, ffdelay
);
558 f
|= adelay(TD
, tbdelay
);
559 f
|= adelay(BD
, bsdelay
);
564 adelay(int ms
, struct delayval
*dp
)
568 while (dp
->delay
&& ms
> dp
->delay
)
574 char editedhost
[MAXHOSTNAMELEN
];
577 edithost(const char *pat
)
580 char *res
= editedhost
;
602 if (res
== &editedhost
[sizeof editedhost
- 1]) {
609 (void)strncpy(res
, host
,
610 sizeof editedhost
- (res
- editedhost
) - 1);
613 editedhost
[sizeof editedhost
- 1] = '\0';
619 static char termbuf
[128] = "TERM=";
625 (void)strlcat(termbuf
, TT
, sizeof(termbuf
));
628 if ((p
= EV
) != NULL
) {
630 while ((q
= strchr(q
, ',')) != NULL
) {
642 * This speed select mechanism is written for the Develcon DATASWITCH.
643 * The Develcon sends a string of the form "B{speed}\n" at a predefined
644 * baud rate. This string indicates the user's actual speed.
645 * The routine below returns the terminal type mapped from derived speed.
651 { "B110", "std.110" },
652 { "B134", "std.134" },
653 { "B150", "std.150" },
654 { "B300", "std.300" },
655 { "B600", "std.600" },
656 { "B1200", "std.1200" },
657 { "B2400", "std.2400" },
658 { "B4800", "std.4800" },
659 { "B9600", "std.9600" },
660 { "B19200", "std.19200" },
668 const char *type
= "default";
669 struct portselect
*ps
;
673 for (len
= 0; len
< sizeof (baud
) - 1; len
++) {
674 if (read(STDIN_FILENO
, &c
, 1) <= 0)
677 if (c
== '\n' || c
== '\r')
680 len
= 0; /* in case of leading garbage */
684 for (ps
= portspeeds
; ps
->ps_baud
; ps
++)
685 if (strcmp(ps
->ps_baud
, baud
) == 0) {
689 (void)sleep(2); /* wait for connection to complete */
694 * This auto-baud speed select mechanism is written for the Micom 600
695 * portselector. Selection is done by looking at how the character '\r'
696 * is garbled at the different speeds.
698 #include <sys/time.h>
703 struct pollfd set
[1];
704 struct timespec timeout
;
706 const char *type
= "9600-baud";
708 (void)tcflush(0, TCIOFLUSH
);
709 set
[0].fd
= STDIN_FILENO
;
710 set
[0].events
= POLLIN
;
711 if (poll(set
, 1, 5000) <= 0)
713 if (read(STDIN_FILENO
, &c
, 1) != 1)
716 timeout
.tv_nsec
= 20000;
717 (void)nanosleep(&timeout
, NULL
);
718 (void)tcflush(0, TCIOFLUSH
);
721 case 0200: /* 300-baud */
725 case 0346: /* 1200-baud */
729 case 015: /* 2400-baud */
734 default: /* 4800-baud */
738 case 0377: /* 9600-baud */