18a16b7a1SPedro F. Giffuni /*-
28a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni *
458f0484fSRodney W. Grimes * Copyright (c) 1989, 1993
558f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved.
658f0484fSRodney W. Grimes *
758f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without
858f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions
958f0484fSRodney W. Grimes * are met:
1058f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright
1158f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer.
1258f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright
1358f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the
1458f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution.
15fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors
1658f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software
1758f0484fSRodney W. Grimes * without specific prior written permission.
1858f0484fSRodney W. Grimes *
1958f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2058f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2158f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2258f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2358f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2458f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2558f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2658f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2758f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2858f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2958f0484fSRodney W. Grimes * SUCH DAMAGE.
3058f0484fSRodney W. Grimes */
3158f0484fSRodney W. Grimes
3208942298SNathan Whitehorn #include <sys/types.h>
33c25e946cSEnji Cooper #include <sys/stat.h>
3408942298SNathan Whitehorn #include <sys/sysctl.h>
3508942298SNathan Whitehorn
36eea7b35fSEnji Cooper #include <ctype.h>
37eea7b35fSEnji Cooper #include <stdio.h>
38eea7b35fSEnji Cooper #include <stdlib.h>
39eea7b35fSEnji Cooper #include <string.h>
40eea7b35fSEnji Cooper #include <ttyent.h>
41eea7b35fSEnji Cooper
4258f0484fSRodney W. Grimes static char zapchar;
4358f0484fSRodney W. Grimes static FILE *tf;
445fae0297SJoerg Wunsch static size_t lbsize;
455fae0297SJoerg Wunsch static char *line;
465fae0297SJoerg Wunsch
475fae0297SJoerg Wunsch #define MALLOCCHUNK 100
485fae0297SJoerg Wunsch
49b231cb39SDavid E. O'Brien static char *skip(char *);
50b231cb39SDavid E. O'Brien static char *value(char *);
5158f0484fSRodney W. Grimes
5258f0484fSRodney W. Grimes struct ttyent *
getttynam(const char * tty)532c201a9aSEd Schouten getttynam(const char *tty)
5458f0484fSRodney W. Grimes {
55b231cb39SDavid E. O'Brien struct ttyent *t;
5658f0484fSRodney W. Grimes
575afcddaeSDavid Nugent if (strncmp(tty, "/dev/", 5) == 0)
58b06ebb32SDavid Nugent tty += 5;
5958f0484fSRodney W. Grimes setttyent();
6051295a4dSJordan K. Hubbard while ( (t = getttyent()) )
6158f0484fSRodney W. Grimes if (!strcmp(tty, t->ty_name))
6258f0484fSRodney W. Grimes break;
6358f0484fSRodney W. Grimes endttyent();
6458f0484fSRodney W. Grimes return (t);
6558f0484fSRodney W. Grimes }
6658f0484fSRodney W. Grimes
6708942298SNathan Whitehorn static int
auto_tty_status(const char * ty_name)6808942298SNathan Whitehorn auto_tty_status(const char *ty_name)
6908942298SNathan Whitehorn {
7008942298SNathan Whitehorn size_t len;
7108942298SNathan Whitehorn char *buf, *cons, *nextcons;
72*1cde387cSEdward Tomasz Napierala int rv;
73*1cde387cSEdward Tomasz Napierala
74*1cde387cSEdward Tomasz Napierala rv = TTY_IFCONSOLE;
7508942298SNathan Whitehorn
7608942298SNathan Whitehorn /* Check if this is an enabled kernel console line */
7708942298SNathan Whitehorn buf = NULL;
7808942298SNathan Whitehorn if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1)
79*1cde387cSEdward Tomasz Napierala return (rv); /* Errors mean don't enable */
8008942298SNathan Whitehorn buf = malloc(len);
8108942298SNathan Whitehorn if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1)
8208942298SNathan Whitehorn goto done;
8308942298SNathan Whitehorn
8408942298SNathan Whitehorn if ((cons = strchr(buf, '/')) == NULL)
8508942298SNathan Whitehorn goto done;
8608942298SNathan Whitehorn *cons = '\0';
8708942298SNathan Whitehorn nextcons = buf;
8808942298SNathan Whitehorn while ((cons = strsep(&nextcons, ",")) != NULL && strlen(cons) != 0) {
8908942298SNathan Whitehorn if (strcmp(cons, ty_name) == 0) {
90*1cde387cSEdward Tomasz Napierala rv |= TTY_ON;
91*1cde387cSEdward Tomasz Napierala break;
9208942298SNathan Whitehorn }
9308942298SNathan Whitehorn }
9408942298SNathan Whitehorn
9508942298SNathan Whitehorn done:
9608942298SNathan Whitehorn free(buf);
97*1cde387cSEdward Tomasz Napierala return (rv);
9808942298SNathan Whitehorn }
9908942298SNathan Whitehorn
10037b58350SWarner Losh static int
auto_exists_status(const char * ty_name)10137b58350SWarner Losh auto_exists_status(const char *ty_name)
10237b58350SWarner Losh {
10337b58350SWarner Losh struct stat sb;
10437b58350SWarner Losh char *dev;
10537b58350SWarner Losh int rv;
10637b58350SWarner Losh
107*1cde387cSEdward Tomasz Napierala rv = TTY_IFEXISTS;
10837b58350SWarner Losh if (*ty_name == '/')
10937b58350SWarner Losh asprintf(&dev, "%s", ty_name);
11037b58350SWarner Losh else
11137b58350SWarner Losh asprintf(&dev, "/dev/%s", ty_name);
11262fd382cSWarner Losh if (dev != NULL && stat(dev, &sb) == 0)
113*1cde387cSEdward Tomasz Napierala rv |= TTY_ON;
11437b58350SWarner Losh free(dev);
11537b58350SWarner Losh return (rv);
11637b58350SWarner Losh }
11737b58350SWarner Losh
11858f0484fSRodney W. Grimes struct ttyent *
getttyent(void)1192c201a9aSEd Schouten getttyent(void)
12058f0484fSRodney W. Grimes {
12158f0484fSRodney W. Grimes static struct ttyent tty;
122b231cb39SDavid E. O'Brien char *p;
123b231cb39SDavid E. O'Brien int c;
1245fae0297SJoerg Wunsch size_t i;
12558f0484fSRodney W. Grimes
12658f0484fSRodney W. Grimes if (!tf && !setttyent())
12758f0484fSRodney W. Grimes return (NULL);
12858f0484fSRodney W. Grimes for (;;) {
129bcc7f0f4SEd Schouten if (!fgets(p = line, lbsize, tf))
13058f0484fSRodney W. Grimes return (NULL);
1315fae0297SJoerg Wunsch /* extend buffer if line was too big, and retry */
132b3608ae1SEd Schouten while (!strchr(p, '\n') && !feof(tf)) {
1335fae0297SJoerg Wunsch i = strlen(p);
1345fae0297SJoerg Wunsch lbsize += MALLOCCHUNK;
135a098bfd7SJoerg Wunsch if ((p = realloc(line, lbsize)) == NULL) {
1365fae0297SJoerg Wunsch (void)endttyent();
1375fae0297SJoerg Wunsch return (NULL);
1385fae0297SJoerg Wunsch }
139a098bfd7SJoerg Wunsch line = p;
1405fae0297SJoerg Wunsch if (!fgets(&line[i], lbsize - i, tf))
1415fae0297SJoerg Wunsch return (NULL);
14258f0484fSRodney W. Grimes }
14349435560SAndrey A. Chernov while (isspace((unsigned char)*p))
14458f0484fSRodney W. Grimes ++p;
14558f0484fSRodney W. Grimes if (*p && *p != '#')
14658f0484fSRodney W. Grimes break;
14758f0484fSRodney W. Grimes }
14858f0484fSRodney W. Grimes
14949435560SAndrey A. Chernov #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1])
150b06ebb32SDavid Nugent #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
151b06ebb32SDavid Nugent
15258f0484fSRodney W. Grimes zapchar = 0;
15358f0484fSRodney W. Grimes tty.ty_name = p;
15450007d44SMatthew N. Dodd tty.ty_status = 0;
15550007d44SMatthew N. Dodd tty.ty_window = NULL;
15650007d44SMatthew N. Dodd tty.ty_group = _TTYS_NOGROUP;
15750007d44SMatthew N. Dodd
15858f0484fSRodney W. Grimes p = skip(p);
15958f0484fSRodney W. Grimes if (!*(tty.ty_getty = p))
16058f0484fSRodney W. Grimes tty.ty_getty = tty.ty_type = NULL;
16158f0484fSRodney W. Grimes else {
16258f0484fSRodney W. Grimes p = skip(p);
16358f0484fSRodney W. Grimes if (!*(tty.ty_type = p))
16458f0484fSRodney W. Grimes tty.ty_type = NULL;
165b06ebb32SDavid Nugent else {
166b06ebb32SDavid Nugent /* compatibility kludge: handle network/dialup specially */
167b06ebb32SDavid Nugent if (scmp(_TTYS_DIALUP))
168b06ebb32SDavid Nugent tty.ty_status |= TTY_DIALUP;
169b06ebb32SDavid Nugent else if (scmp(_TTYS_NETWORK))
170b06ebb32SDavid Nugent tty.ty_status |= TTY_NETWORK;
17158f0484fSRodney W. Grimes p = skip(p);
17258f0484fSRodney W. Grimes }
173b06ebb32SDavid Nugent }
17458f0484fSRodney W. Grimes
17558f0484fSRodney W. Grimes for (; *p; p = skip(p)) {
17658f0484fSRodney W. Grimes if (scmp(_TTYS_OFF))
17758f0484fSRodney W. Grimes tty.ty_status &= ~TTY_ON;
17858f0484fSRodney W. Grimes else if (scmp(_TTYS_ON))
17958f0484fSRodney W. Grimes tty.ty_status |= TTY_ON;
18008942298SNathan Whitehorn else if (scmp(_TTYS_ONIFCONSOLE))
18108942298SNathan Whitehorn tty.ty_status |= auto_tty_status(tty.ty_name);
18237b58350SWarner Losh else if (scmp(_TTYS_ONIFEXISTS))
18337b58350SWarner Losh tty.ty_status |= auto_exists_status(tty.ty_name);
18458f0484fSRodney W. Grimes else if (scmp(_TTYS_SECURE))
18558f0484fSRodney W. Grimes tty.ty_status |= TTY_SECURE;
186a60c8a80SDavid Nugent else if (scmp(_TTYS_INSECURE))
187a60c8a80SDavid Nugent tty.ty_status &= ~TTY_SECURE;
188b06ebb32SDavid Nugent else if (scmp(_TTYS_DIALUP))
189b06ebb32SDavid Nugent tty.ty_status |= TTY_DIALUP;
190b06ebb32SDavid Nugent else if (scmp(_TTYS_NETWORK))
191b06ebb32SDavid Nugent tty.ty_status |= TTY_NETWORK;
19258f0484fSRodney W. Grimes else if (vcmp(_TTYS_WINDOW))
19358f0484fSRodney W. Grimes tty.ty_window = value(p);
1944ae89ecdSDavid Nugent else if (vcmp(_TTYS_GROUP))
1954ae89ecdSDavid Nugent tty.ty_group = value(p);
19658f0484fSRodney W. Grimes else
19758f0484fSRodney W. Grimes break;
19858f0484fSRodney W. Grimes }
19958f0484fSRodney W. Grimes
20058f0484fSRodney W. Grimes if (zapchar == '#' || *p == '#')
20158f0484fSRodney W. Grimes while ((c = *++p) == ' ' || c == '\t')
20258f0484fSRodney W. Grimes ;
20358f0484fSRodney W. Grimes tty.ty_comment = p;
20458f0484fSRodney W. Grimes if (*p == 0)
20558f0484fSRodney W. Grimes tty.ty_comment = 0;
206b3608ae1SEd Schouten if ((p = strchr(p, '\n')))
20758f0484fSRodney W. Grimes *p = '\0';
20858f0484fSRodney W. Grimes return (&tty);
20958f0484fSRodney W. Grimes }
21058f0484fSRodney W. Grimes
21158f0484fSRodney W. Grimes #define QUOTED 1
21258f0484fSRodney W. Grimes
21358f0484fSRodney W. Grimes /*
21458f0484fSRodney W. Grimes * Skip over the current field, removing quotes, and return a pointer to
21558f0484fSRodney W. Grimes * the next field.
21658f0484fSRodney W. Grimes */
21758f0484fSRodney W. Grimes static char *
skip(char * p)2182c201a9aSEd Schouten skip(char *p)
21958f0484fSRodney W. Grimes {
220b231cb39SDavid E. O'Brien char *t;
221b231cb39SDavid E. O'Brien int c, q;
22258f0484fSRodney W. Grimes
22358f0484fSRodney W. Grimes for (q = 0, t = p; (c = *p) != '\0'; p++) {
22458f0484fSRodney W. Grimes if (c == '"') {
22558f0484fSRodney W. Grimes q ^= QUOTED; /* obscure, but nice */
22658f0484fSRodney W. Grimes continue;
22758f0484fSRodney W. Grimes }
22858f0484fSRodney W. Grimes if (q == QUOTED && *p == '\\' && *(p+1) == '"')
22958f0484fSRodney W. Grimes p++;
23058f0484fSRodney W. Grimes *t++ = *p;
23158f0484fSRodney W. Grimes if (q == QUOTED)
23258f0484fSRodney W. Grimes continue;
23358f0484fSRodney W. Grimes if (c == '#') {
23458f0484fSRodney W. Grimes zapchar = c;
23558f0484fSRodney W. Grimes *p = 0;
23658f0484fSRodney W. Grimes break;
23758f0484fSRodney W. Grimes }
23858f0484fSRodney W. Grimes if (c == '\t' || c == ' ' || c == '\n') {
23958f0484fSRodney W. Grimes zapchar = c;
24058f0484fSRodney W. Grimes *p++ = 0;
24158f0484fSRodney W. Grimes while ((c = *p) == '\t' || c == ' ' || c == '\n')
24258f0484fSRodney W. Grimes p++;
24358f0484fSRodney W. Grimes break;
24458f0484fSRodney W. Grimes }
24558f0484fSRodney W. Grimes }
24658f0484fSRodney W. Grimes *--t = '\0';
24758f0484fSRodney W. Grimes return (p);
24858f0484fSRodney W. Grimes }
24958f0484fSRodney W. Grimes
25058f0484fSRodney W. Grimes static char *
value(char * p)2512c201a9aSEd Schouten value(char *p)
25258f0484fSRodney W. Grimes {
25358f0484fSRodney W. Grimes
254b3608ae1SEd Schouten return ((p = strchr(p, '=')) ? ++p : NULL);
25558f0484fSRodney W. Grimes }
25658f0484fSRodney W. Grimes
25758f0484fSRodney W. Grimes int
setttyent(void)2582c201a9aSEd Schouten setttyent(void)
25958f0484fSRodney W. Grimes {
26058f0484fSRodney W. Grimes
2615fae0297SJoerg Wunsch if (line == NULL) {
2625fae0297SJoerg Wunsch if ((line = malloc(MALLOCCHUNK)) == NULL)
2635fae0297SJoerg Wunsch return (0);
2645fae0297SJoerg Wunsch lbsize = MALLOCCHUNK;
2655fae0297SJoerg Wunsch }
26658f0484fSRodney W. Grimes if (tf) {
267e78bad23SJeffrey Hsu rewind(tf);
26858f0484fSRodney W. Grimes return (1);
2691084b38bSJilles Tjoelker } else if ( (tf = fopen(_PATH_TTYS, "re")) )
27058f0484fSRodney W. Grimes return (1);
27158f0484fSRodney W. Grimes return (0);
27258f0484fSRodney W. Grimes }
27358f0484fSRodney W. Grimes
27458f0484fSRodney W. Grimes int
endttyent(void)2752c201a9aSEd Schouten endttyent(void)
27658f0484fSRodney W. Grimes {
27758f0484fSRodney W. Grimes int rval;
27858f0484fSRodney W. Grimes
2794e176059SJoerg Wunsch /*
2804e176059SJoerg Wunsch * NB: Don't free `line' because getttynam()
2814e176059SJoerg Wunsch * may still be referencing it
2824e176059SJoerg Wunsch */
28358f0484fSRodney W. Grimes if (tf) {
2845fae0297SJoerg Wunsch rval = (fclose(tf) != EOF);
28558f0484fSRodney W. Grimes tf = NULL;
28658f0484fSRodney W. Grimes return (rval);
28758f0484fSRodney W. Grimes }
28858f0484fSRodney W. Grimes return (1);
28958f0484fSRodney W. Grimes }
290b06ebb32SDavid Nugent
291b06ebb32SDavid Nugent static int
isttystat(const char * tty,int flag)2922c201a9aSEd Schouten isttystat(const char *tty, int flag)
293b06ebb32SDavid Nugent {
294b231cb39SDavid E. O'Brien struct ttyent *t;
295b06ebb32SDavid Nugent
296b06ebb32SDavid Nugent return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag);
297b06ebb32SDavid Nugent }
298b06ebb32SDavid Nugent
299b06ebb32SDavid Nugent
300b06ebb32SDavid Nugent int
isdialuptty(const char * tty)3012c201a9aSEd Schouten isdialuptty(const char *tty)
302b06ebb32SDavid Nugent {
303b06ebb32SDavid Nugent
304b06ebb32SDavid Nugent return isttystat(tty, TTY_DIALUP);
305b06ebb32SDavid Nugent }
306b06ebb32SDavid Nugent
3072c201a9aSEd Schouten int
isnettty(const char * tty)3082c201a9aSEd Schouten isnettty(const char *tty)
309b06ebb32SDavid Nugent {
310b06ebb32SDavid Nugent
311b06ebb32SDavid Nugent return isttystat(tty, TTY_NETWORK);
312b06ebb32SDavid Nugent }
313