1 /* $NetBSD: subr.c,v 1.32 2006/11/16 04:15:13 christos 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.32 2006/11/16 04:15:13 christos Exp $");
45 #include <sys/param.h>
46 #include <sys/ioctl.h>
56 #include "pathnames.h"
58 extern struct termios tmode
, omode
;
60 static void compatflags(long);
66 gettable(char *name
, char *buf
)
70 struct gettyflags
*fp
;
73 dba
[0] = _PATH_GETTYTAB
;
76 if (cgetent(&buf
, dba
, name
) != 0)
79 for (sp
= gettystrs
; sp
->field
; sp
++)
80 (void)cgetstr(buf
, sp
->field
, &sp
->value
);
81 for (np
= gettynums
; np
->field
; np
++) {
82 if (cgetnum(buf
, np
->field
, &n
) == -1)
89 for (fp
= gettyflags
; fp
->field
; fp
++) {
90 if (cgetcap(buf
, fp
->field
, ':') == NULL
)
94 fp
->value
= 1 ^ fp
->invrt
;
98 printf("name=\"%s\", buf=\"%s\"\n", name
, buf
);
99 for (sp
= gettystrs
; sp
->field
; sp
++)
100 printf("cgetstr: %s=%s\n", sp
->field
, sp
->value
);
101 for (np
= gettynums
; np
->field
; np
++)
102 printf("cgetnum: %s=%d\n", np
->field
, np
->value
);
103 for (fp
= gettyflags
; fp
->field
; fp
++)
104 printf("cgetflags: %s='%c' set='%c'\n", fp
->field
,
105 fp
->value
+ '0', fp
->set
+ '0');
113 struct gettystrs
*sp
;
114 struct gettynums
*np
;
115 struct gettyflags
*fp
;
117 for (sp
= gettystrs
; sp
->field
; sp
++)
119 sp
->defalt
= sp
->value
;
120 for (np
= gettynums
; np
->field
; np
++)
122 np
->defalt
= np
->value
;
123 for (fp
= gettyflags
; fp
->field
; fp
++)
125 fp
->defalt
= fp
->value
;
127 fp
->defalt
= fp
->invrt
;
133 struct gettystrs
*sp
;
134 struct gettynums
*np
;
135 struct gettyflags
*fp
;
137 for (sp
= gettystrs
; sp
->field
; sp
++)
139 sp
->value
= sp
->defalt
;
140 for (np
= gettynums
; np
->field
; np
++)
142 np
->value
= np
->defalt
;
143 for (fp
= gettyflags
; fp
->field
; fp
++)
145 fp
->value
= fp
->defalt
;
150 &ER
, &KL
, &IN
, &QU
, &XN
, &XF
, &ET
, &BK
,
151 &SU
, &DS
, &RP
, &FL
, &WE
, &LN
, &ST
, &B2
, 0
156 &tmode
.c_cc
[VERASE
], &tmode
.c_cc
[VKILL
], &tmode
.c_cc
[VINTR
],
157 &tmode
.c_cc
[VQUIT
], &tmode
.c_cc
[VSTART
], &tmode
.c_cc
[VSTOP
],
158 &tmode
.c_cc
[VEOF
], &tmode
.c_cc
[VEOL
], &tmode
.c_cc
[VSUSP
],
159 &tmode
.c_cc
[VDSUSP
], &tmode
.c_cc
[VREPRINT
], &tmode
.c_cc
[VDISCARD
],
160 &tmode
.c_cc
[VWERASE
], &tmode
.c_cc
[VLNEXT
], &tmode
.c_cc
[VSTATUS
],
161 &tmode
.c_cc
[VEOL2
], 0
170 for (i
= 0; charnames
[i
]; i
++) {
175 *charvars
[i
] = _POSIX_VDISABLE
;
179 /* Macros to clear/set/test flags. */
180 #define SET(t, f) (t) |= (f)
181 #define CLR(t, f) (t) &= ~(f)
182 #define ISSET(t, f) ((t) & (f))
187 tcflag_t iflag
, oflag
, cflag
, lflag
;
214 if (C0set
&& I0set
&& L0set
&& O0set
) {
223 if (C1set
&& I1set
&& L1set
&& O1set
) {
232 if (C2set
&& I2set
&& L2set
&& O2set
) {
242 iflag
= omode
.c_iflag
;
243 oflag
= omode
.c_oflag
;
244 cflag
= omode
.c_cflag
;
245 lflag
= omode
.c_lflag
;
248 CLR(cflag
, CSIZE
|PARENB
);
250 CLR(iflag
, ISTRIP
|INPCK
|IGNPAR
);
251 } else if (AP
|| EP
|| OP
) {
253 SET(cflag
, CS7
|PARENB
);
256 SET(iflag
, INPCK
|IGNPAR
);
260 } else if (EP
&& !OP
) {
261 SET(iflag
, INPCK
|IGNPAR
);
265 } else if (AP
|| (EP
&& OP
)) {
266 CLR(iflag
, INPCK
|IGNPAR
);
269 } /* else, leave as is */
288 SET(oflag
, ONLCR
|OPOST
);
295 SET(oflag
, OXTABS
|OPOST
);
303 if (n
== 1) { /* read mode flags */
307 CLR(cflag
, CSIZE
|PARENB
);
355 tmode
.c_iflag
= iflag
;
356 tmode
.c_oflag
= oflag
;
357 tmode
.c_cflag
= cflag
;
358 tmode
.c_lflag
= lflag
;
363 * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
366 compatflags(long flags
)
368 tcflag_t iflag
, oflag
, cflag
, lflag
;
370 iflag
= BRKINT
|ICRNL
|IMAXBEL
|IXON
|IXANY
;
371 oflag
= OPOST
|ONLCR
|OXTABS
;
373 lflag
= ICANON
|ISIG
|IEXTEN
;
375 if (ISSET(flags
, TANDEM
))
379 if (ISSET(flags
, ECHO
))
383 if (ISSET(flags
, CRMOD
)) {
390 if (ISSET(flags
, XTABS
))
396 if (ISSET(flags
, RAW
)) {
398 CLR(lflag
, ISIG
|ICANON
|IEXTEN
);
401 SET(iflag
, BRKINT
|IXON
|IMAXBEL
);
402 SET(lflag
, ISIG
|IEXTEN
);
403 if (ISSET(flags
, CBREAK
))
407 switch (ISSET(flags
, ANYP
)) {
428 /* Nothing we can do with CRTBS. */
429 if (ISSET(flags
, PRTERA
))
433 if (ISSET(flags
, CRTERA
))
437 /* Nothing we can do with TILDE. */
438 if (ISSET(flags
, MDMBUF
))
442 if (ISSET(flags
, NOHANG
))
446 if (ISSET(flags
, CRTKIL
))
450 if (ISSET(flags
, CTLECH
))
454 if (!ISSET(flags
, DECCTQ
))
458 CLR(lflag
, TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
);
459 SET(lflag
, ISSET(flags
, TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
));
461 if (ISSET(flags
, RAW
|LITOUT
|PASS8
)) {
464 if (!ISSET(flags
, RAW
|PASS8
))
468 if (!ISSET(flags
, RAW
|LITOUT
))
479 tmode
.c_iflag
= iflag
;
480 tmode
.c_oflag
= oflag
;
481 tmode
.c_cflag
= cflag
;
482 tmode
.c_lflag
= lflag
;
488 unsigned delay
; /* delay in ms */
493 * below are random guesses, I can't be bothered checking
496 struct delayval crdelay
[] = {
505 struct delayval nldelay
[] = {
506 { 1, NL1
}, /* special, calculated */
513 struct delayval bsdelay
[] = {
518 struct delayval ffdelay
[] = {
524 struct delayval tbdelay
[] = {
527 { 3, XTABS
}, /* this is expand tabs */
537 f
= adelay(CD
, crdelay
);
538 f
|= adelay(ND
, nldelay
);
539 f
|= adelay(FD
, ffdelay
);
540 f
|= adelay(TD
, tbdelay
);
541 f
|= adelay(BD
, bsdelay
);
546 adelay(int ms
, struct delayval
*dp
)
550 while (dp
->delay
&& ms
> dp
->delay
)
556 char editedhost
[MAXHOSTNAMELEN
];
562 char *res
= editedhost
;
584 if (res
== &editedhost
[sizeof editedhost
- 1]) {
591 (void)strncpy(res
, host
,
592 sizeof editedhost
- (res
- editedhost
) - 1);
595 editedhost
[sizeof editedhost
- 1] = '\0';
601 static char termbuf
[128] = "TERM=";
607 (void)strlcat(termbuf
, TT
, sizeof(termbuf
));
610 if ((p
= EV
) != NULL
) {
612 while ((q
= strchr(q
, ',')) != NULL
) {
624 * This speed select mechanism is written for the Develcon DATASWITCH.
625 * The Develcon sends a string of the form "B{speed}\n" at a predefined
626 * baud rate. This string indicates the user's actual speed.
627 * The routine below returns the terminal type mapped from derived speed.
633 { "B110", "std.110" },
634 { "B134", "std.134" },
635 { "B150", "std.150" },
636 { "B300", "std.300" },
637 { "B600", "std.600" },
638 { "B1200", "std.1200" },
639 { "B2400", "std.2400" },
640 { "B4800", "std.4800" },
641 { "B9600", "std.9600" },
642 { "B19200", "std.19200" },
649 char c
, baud
[20], *type
= "default";
650 struct portselect
*ps
;
654 for (len
= 0; len
< sizeof (baud
) - 1; len
++) {
655 if (read(STDIN_FILENO
, &c
, 1) <= 0)
658 if (c
== '\n' || c
== '\r')
661 len
= 0; /* in case of leading garbage */
665 for (ps
= portspeeds
; ps
->ps_baud
; ps
++)
666 if (strcmp(ps
->ps_baud
, baud
) == 0) {
670 (void)sleep(2); /* wait for connection to complete */
675 * This auto-baud speed select mechanism is written for the Micom 600
676 * portselector. Selection is done by looking at how the character '\r'
677 * is garbled at the different speeds.
679 #include <sys/time.h>
684 struct pollfd set
[1];
685 struct timespec timeout
;
686 char c
, *type
= "9600-baud";
688 (void)tcflush(0, TCIOFLUSH
);
689 set
[0].fd
= STDIN_FILENO
;
690 set
[0].events
= POLLIN
;
691 if (poll(set
, 1, 5000) <= 0)
693 if (read(STDIN_FILENO
, &c
, 1) != 1)
696 timeout
.tv_nsec
= 20000;
697 (void)nanosleep(&timeout
, NULL
);
698 (void)tcflush(0, TCIOFLUSH
);
701 case 0200: /* 300-baud */
705 case 0346: /* 1200-baud */
709 case 015: /* 2400-baud */
714 default: /* 4800-baud */
718 case 0377: /* 9600-baud */