xref: /freebsd/lib/libc/gen/getttyent.c (revision bcc7f0f4080736ae4b6927e22d63fcbf40095061)
158f0484fSRodney W. Grimes /*
258f0484fSRodney W. Grimes  * Copyright (c) 1989, 1993
358f0484fSRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
458f0484fSRodney W. Grimes  *
558f0484fSRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
658f0484fSRodney W. Grimes  * modification, are permitted provided that the following conditions
758f0484fSRodney W. Grimes  * are met:
858f0484fSRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
958f0484fSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
1058f0484fSRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
1158f0484fSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
1258f0484fSRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
1358f0484fSRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
1458f0484fSRodney W. Grimes  *    may be used to endorse or promote products derived from this software
1558f0484fSRodney W. Grimes  *    without specific prior written permission.
1658f0484fSRodney W. Grimes  *
1758f0484fSRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1858f0484fSRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1958f0484fSRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2058f0484fSRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2158f0484fSRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2258f0484fSRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2358f0484fSRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2458f0484fSRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2558f0484fSRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2658f0484fSRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2758f0484fSRodney W. Grimes  * SUCH DAMAGE.
2858f0484fSRodney W. Grimes  */
2958f0484fSRodney W. Grimes 
3058f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint)
3158f0484fSRodney W. Grimes static char sccsid[] = "@(#)getttyent.c	8.1 (Berkeley) 6/4/93";
3258f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */
33b231cb39SDavid E. O'Brien #include <sys/cdefs.h>
34b231cb39SDavid E. O'Brien __FBSDID("$FreeBSD$");
3558f0484fSRodney W. Grimes 
3658f0484fSRodney W. Grimes #include <ttyent.h>
3758f0484fSRodney W. Grimes #include <stdio.h>
385fae0297SJoerg Wunsch #include <stdlib.h>
3958f0484fSRodney W. Grimes #include <ctype.h>
4058f0484fSRodney W. Grimes #include <string.h>
4158f0484fSRodney W. Grimes 
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 *
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 
6758f0484fSRodney W. Grimes struct ttyent *
682c201a9aSEd Schouten getttyent(void)
6958f0484fSRodney W. Grimes {
7058f0484fSRodney W. Grimes 	static struct ttyent tty;
71b231cb39SDavid E. O'Brien 	char *p;
72b231cb39SDavid E. O'Brien 	int c;
735fae0297SJoerg Wunsch 	size_t i;
7458f0484fSRodney W. Grimes 
7558f0484fSRodney W. Grimes 	if (!tf && !setttyent())
7658f0484fSRodney W. Grimes 		return (NULL);
7758f0484fSRodney W. Grimes 	for (;;) {
78bcc7f0f4SEd Schouten 		if (!fgets(p = line, lbsize, tf))
7958f0484fSRodney W. Grimes 			return (NULL);
805fae0297SJoerg Wunsch 		/* extend buffer if line was too big, and retry */
8100a32d0cSDavid Schultz 		while (!index(p, '\n') && !feof(tf)) {
825fae0297SJoerg Wunsch 			i = strlen(p);
835fae0297SJoerg Wunsch 			lbsize += MALLOCCHUNK;
84a098bfd7SJoerg Wunsch 			if ((p = realloc(line, lbsize)) == NULL) {
855fae0297SJoerg Wunsch 				(void)endttyent();
865fae0297SJoerg Wunsch 				return (NULL);
875fae0297SJoerg Wunsch 			}
88a098bfd7SJoerg Wunsch 			line = p;
895fae0297SJoerg Wunsch 			if (!fgets(&line[i], lbsize - i, tf))
905fae0297SJoerg Wunsch 				return (NULL);
9158f0484fSRodney W. Grimes 		}
9249435560SAndrey A. Chernov 		while (isspace((unsigned char)*p))
9358f0484fSRodney W. Grimes 			++p;
9458f0484fSRodney W. Grimes 		if (*p && *p != '#')
9558f0484fSRodney W. Grimes 			break;
9658f0484fSRodney W. Grimes 	}
9758f0484fSRodney W. Grimes 
9849435560SAndrey A. Chernov #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1])
99b06ebb32SDavid Nugent #define	vcmp(e)	!strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
100b06ebb32SDavid Nugent 
10158f0484fSRodney W. Grimes 	zapchar = 0;
10258f0484fSRodney W. Grimes 	tty.ty_name = p;
10350007d44SMatthew N. Dodd 	tty.ty_status = 0;
10450007d44SMatthew N. Dodd 	tty.ty_window = NULL;
10550007d44SMatthew N. Dodd 	tty.ty_group  = _TTYS_NOGROUP;
10650007d44SMatthew N. Dodd 
10758f0484fSRodney W. Grimes 	p = skip(p);
10858f0484fSRodney W. Grimes 	if (!*(tty.ty_getty = p))
10958f0484fSRodney W. Grimes 		tty.ty_getty = tty.ty_type = NULL;
11058f0484fSRodney W. Grimes 	else {
11158f0484fSRodney W. Grimes 		p = skip(p);
11258f0484fSRodney W. Grimes 		if (!*(tty.ty_type = p))
11358f0484fSRodney W. Grimes 			tty.ty_type = NULL;
114b06ebb32SDavid Nugent 		else {
115b06ebb32SDavid Nugent 			/* compatibility kludge: handle network/dialup specially */
116b06ebb32SDavid Nugent 			if (scmp(_TTYS_DIALUP))
117b06ebb32SDavid Nugent 				tty.ty_status |= TTY_DIALUP;
118b06ebb32SDavid Nugent 			else if (scmp(_TTYS_NETWORK))
119b06ebb32SDavid Nugent 				tty.ty_status |= TTY_NETWORK;
12058f0484fSRodney W. Grimes 			p = skip(p);
12158f0484fSRodney W. Grimes 		}
122b06ebb32SDavid Nugent 	}
12358f0484fSRodney W. Grimes 
12458f0484fSRodney W. Grimes 	for (; *p; p = skip(p)) {
12558f0484fSRodney W. Grimes 		if (scmp(_TTYS_OFF))
12658f0484fSRodney W. Grimes 			tty.ty_status &= ~TTY_ON;
12758f0484fSRodney W. Grimes 		else if (scmp(_TTYS_ON))
12858f0484fSRodney W. Grimes 			tty.ty_status |= TTY_ON;
12958f0484fSRodney W. Grimes 		else if (scmp(_TTYS_SECURE))
13058f0484fSRodney W. Grimes 			tty.ty_status |= TTY_SECURE;
131a60c8a80SDavid Nugent 		else if (scmp(_TTYS_INSECURE))
132a60c8a80SDavid Nugent 			tty.ty_status &= ~TTY_SECURE;
133b06ebb32SDavid Nugent 		else if (scmp(_TTYS_DIALUP))
134b06ebb32SDavid Nugent 			tty.ty_status |= TTY_DIALUP;
135b06ebb32SDavid Nugent 		else if (scmp(_TTYS_NETWORK))
136b06ebb32SDavid Nugent 			tty.ty_status |= TTY_NETWORK;
13758f0484fSRodney W. Grimes 		else if (vcmp(_TTYS_WINDOW))
13858f0484fSRodney W. Grimes 			tty.ty_window = value(p);
1394ae89ecdSDavid Nugent 		else if (vcmp(_TTYS_GROUP))
1404ae89ecdSDavid Nugent 			tty.ty_group = value(p);
14158f0484fSRodney W. Grimes 		else
14258f0484fSRodney W. Grimes 			break;
14358f0484fSRodney W. Grimes 	}
14458f0484fSRodney W. Grimes 
14558f0484fSRodney W. Grimes 	if (zapchar == '#' || *p == '#')
14658f0484fSRodney W. Grimes 		while ((c = *++p) == ' ' || c == '\t')
14758f0484fSRodney W. Grimes 			;
14858f0484fSRodney W. Grimes 	tty.ty_comment = p;
14958f0484fSRodney W. Grimes 	if (*p == 0)
15058f0484fSRodney W. Grimes 		tty.ty_comment = 0;
15151295a4dSJordan K. Hubbard 	if ( (p = index(p, '\n')) )
15258f0484fSRodney W. Grimes 		*p = '\0';
15358f0484fSRodney W. Grimes 	return (&tty);
15458f0484fSRodney W. Grimes }
15558f0484fSRodney W. Grimes 
15658f0484fSRodney W. Grimes #define	QUOTED	1
15758f0484fSRodney W. Grimes 
15858f0484fSRodney W. Grimes /*
15958f0484fSRodney W. Grimes  * Skip over the current field, removing quotes, and return a pointer to
16058f0484fSRodney W. Grimes  * the next field.
16158f0484fSRodney W. Grimes  */
16258f0484fSRodney W. Grimes static char *
1632c201a9aSEd Schouten skip(char *p)
16458f0484fSRodney W. Grimes {
165b231cb39SDavid E. O'Brien 	char *t;
166b231cb39SDavid E. O'Brien 	int c, q;
16758f0484fSRodney W. Grimes 
16858f0484fSRodney W. Grimes 	for (q = 0, t = p; (c = *p) != '\0'; p++) {
16958f0484fSRodney W. Grimes 		if (c == '"') {
17058f0484fSRodney W. Grimes 			q ^= QUOTED;	/* obscure, but nice */
17158f0484fSRodney W. Grimes 			continue;
17258f0484fSRodney W. Grimes 		}
17358f0484fSRodney W. Grimes 		if (q == QUOTED && *p == '\\' && *(p+1) == '"')
17458f0484fSRodney W. Grimes 			p++;
17558f0484fSRodney W. Grimes 		*t++ = *p;
17658f0484fSRodney W. Grimes 		if (q == QUOTED)
17758f0484fSRodney W. Grimes 			continue;
17858f0484fSRodney W. Grimes 		if (c == '#') {
17958f0484fSRodney W. Grimes 			zapchar = c;
18058f0484fSRodney W. Grimes 			*p = 0;
18158f0484fSRodney W. Grimes 			break;
18258f0484fSRodney W. Grimes 		}
18358f0484fSRodney W. Grimes 		if (c == '\t' || c == ' ' || c == '\n') {
18458f0484fSRodney W. Grimes 			zapchar = c;
18558f0484fSRodney W. Grimes 			*p++ = 0;
18658f0484fSRodney W. Grimes 			while ((c = *p) == '\t' || c == ' ' || c == '\n')
18758f0484fSRodney W. Grimes 				p++;
18858f0484fSRodney W. Grimes 			break;
18958f0484fSRodney W. Grimes 		}
19058f0484fSRodney W. Grimes 	}
19158f0484fSRodney W. Grimes 	*--t = '\0';
19258f0484fSRodney W. Grimes 	return (p);
19358f0484fSRodney W. Grimes }
19458f0484fSRodney W. Grimes 
19558f0484fSRodney W. Grimes static char *
1962c201a9aSEd Schouten value(char *p)
19758f0484fSRodney W. Grimes {
19858f0484fSRodney W. Grimes 
19958f0484fSRodney W. Grimes 	return ((p = index(p, '=')) ? ++p : NULL);
20058f0484fSRodney W. Grimes }
20158f0484fSRodney W. Grimes 
20258f0484fSRodney W. Grimes int
2032c201a9aSEd Schouten setttyent(void)
20458f0484fSRodney W. Grimes {
20558f0484fSRodney W. Grimes 
2065fae0297SJoerg Wunsch 	if (line == NULL) {
2075fae0297SJoerg Wunsch 		if ((line = malloc(MALLOCCHUNK)) == NULL)
2085fae0297SJoerg Wunsch 			return (0);
2095fae0297SJoerg Wunsch 		lbsize = MALLOCCHUNK;
2105fae0297SJoerg Wunsch 	}
21158f0484fSRodney W. Grimes 	if (tf) {
212e78bad23SJeffrey Hsu 		rewind(tf);
21358f0484fSRodney W. Grimes 		return (1);
21451295a4dSJordan K. Hubbard 	} else if ( (tf = fopen(_PATH_TTYS, "r")) )
21558f0484fSRodney W. Grimes 		return (1);
21658f0484fSRodney W. Grimes 	return (0);
21758f0484fSRodney W. Grimes }
21858f0484fSRodney W. Grimes 
21958f0484fSRodney W. Grimes int
2202c201a9aSEd Schouten endttyent(void)
22158f0484fSRodney W. Grimes {
22258f0484fSRodney W. Grimes 	int rval;
22358f0484fSRodney W. Grimes 
2244e176059SJoerg Wunsch 	/*
2254e176059SJoerg Wunsch          * NB: Don't free `line' because getttynam()
2264e176059SJoerg Wunsch 	 * may still be referencing it
2274e176059SJoerg Wunsch 	 */
22858f0484fSRodney W. Grimes 	if (tf) {
2295fae0297SJoerg Wunsch 		rval = (fclose(tf) != EOF);
23058f0484fSRodney W. Grimes 		tf = NULL;
23158f0484fSRodney W. Grimes 		return (rval);
23258f0484fSRodney W. Grimes 	}
23358f0484fSRodney W. Grimes 	return (1);
23458f0484fSRodney W. Grimes }
235b06ebb32SDavid Nugent 
236b06ebb32SDavid Nugent static int
2372c201a9aSEd Schouten isttystat(const char *tty, int flag)
238b06ebb32SDavid Nugent {
239b231cb39SDavid E. O'Brien 	struct ttyent *t;
240b06ebb32SDavid Nugent 
241b06ebb32SDavid Nugent 	return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag);
242b06ebb32SDavid Nugent }
243b06ebb32SDavid Nugent 
244b06ebb32SDavid Nugent 
245b06ebb32SDavid Nugent int
2462c201a9aSEd Schouten isdialuptty(const char *tty)
247b06ebb32SDavid Nugent {
248b06ebb32SDavid Nugent 
249b06ebb32SDavid Nugent 	return isttystat(tty, TTY_DIALUP);
250b06ebb32SDavid Nugent }
251b06ebb32SDavid Nugent 
2522c201a9aSEd Schouten int
2532c201a9aSEd Schouten isnettty(const char *tty)
254b06ebb32SDavid Nugent {
255b06ebb32SDavid Nugent 
256b06ebb32SDavid Nugent 	return isttystat(tty, TTY_NETWORK);
257b06ebb32SDavid Nugent }
258