getttyent.c revision 90045
180219Swpaul/*
280219Swpaul * Copyright (c) 1989, 1993
380219Swpaul *	The Regents of the University of California.  All rights reserved.
480219Swpaul *
580219Swpaul * Redistribution and use in source and binary forms, with or without
680219Swpaul * modification, are permitted provided that the following conditions
780219Swpaul * are met:
880219Swpaul * 1. Redistributions of source code must retain the above copyright
980219Swpaul *    notice, this list of conditions and the following disclaimer.
1080219Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1180219Swpaul *    notice, this list of conditions and the following disclaimer in the
1280219Swpaul *    documentation and/or other materials provided with the distribution.
1380219Swpaul * 3. All advertising materials mentioning features or use of this software
1480219Swpaul *    must display the following acknowledgement:
1580219Swpaul *	This product includes software developed by the University of
1680219Swpaul *	California, Berkeley and its contributors.
1780219Swpaul * 4. Neither the name of the University nor the names of its contributors
1880219Swpaul *    may be used to endorse or promote products derived from this software
1980219Swpaul *    without specific prior written permission.
2080219Swpaul *
2180219Swpaul * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2280219Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2380219Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2480219Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2580219Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2680219Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2780219Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2880219Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2980219Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3080219Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3180219Swpaul * SUCH DAMAGE.
3280219Swpaul */
3380219Swpaul
3480219Swpaul#if defined(LIBC_SCCS) && !defined(lint)
3580219Swpaulstatic char sccsid[] = "@(#)getttyent.c	8.1 (Berkeley) 6/4/93";
3680219Swpaul#endif /* LIBC_SCCS and not lint */
3780219Swpaul#include <sys/cdefs.h>
3880219Swpaul__FBSDID("$FreeBSD: head/lib/libc/gen/getttyent.c 90045 2002-02-01 01:32:19Z obrien $");
3980219Swpaul
4080219Swpaul#include <ttyent.h>
4180219Swpaul#include <stdio.h>
4280219Swpaul#include <stdlib.h>
4380219Swpaul#include <ctype.h>
4480219Swpaul#include <string.h>
4580219Swpaul
4680219Swpaulstatic char zapchar;
4780219Swpaulstatic FILE *tf;
4880219Swpaulstatic size_t lbsize;
4980219Swpaulstatic char *line;
5080219Swpaul
5180219Swpaul#define	MALLOCCHUNK	100
5280219Swpaul
5380219Swpaulstatic char *skip(char *);
5480219Swpaulstatic char *value(char *);
5583115Sbrooks
5680219Swpaulstruct ttyent *
5780219Swpaulgetttynam(tty)
5880219Swpaul	const char *tty;
5980219Swpaul{
6080219Swpaul	struct ttyent *t;
6180219Swpaul
6280219Swpaul	if (strncmp(tty, "/dev/", 5) == 0)
6380219Swpaul		tty += 5;
6480219Swpaul	setttyent();
6580219Swpaul	while ( (t = getttyent()) )
6680219Swpaul		if (!strcmp(tty, t->ty_name))
6780219Swpaul			break;
6880219Swpaul	endttyent();
6980219Swpaul	return (t);
7080219Swpaul}
7180219Swpaul
7280219Swpaulstruct ttyent *
7380219Swpaulgetttyent()
7480219Swpaul{
7580219Swpaul	static struct ttyent tty;
7680219Swpaul	char *p;
7780219Swpaul	int c;
7880219Swpaul	size_t i;
7980219Swpaul
8080219Swpaul	if (!tf && !setttyent())
8180219Swpaul		return (NULL);
8280219Swpaul	for (;;) {
8380219Swpaul		if (!fgets(p = line, lbsize, tf))
8480229Swpaul			return (NULL);
8580219Swpaul		/* extend buffer if line was too big, and retry */
8680219Swpaul		while (!index(p, '\n')) {
8780219Swpaul			i = strlen(p);
8880219Swpaul			lbsize += MALLOCCHUNK;
8980219Swpaul			if ((p = realloc(line, lbsize)) == NULL) {
9080219Swpaul				(void)endttyent();
9180219Swpaul				return (NULL);
9280219Swpaul			}
9380219Swpaul			line = p;
9480219Swpaul			if (!fgets(&line[i], lbsize - i, tf))
9580219Swpaul				return (NULL);
9680219Swpaul		}
9780219Swpaul		while (isspace((unsigned char)*p))
9880219Swpaul			++p;
9980219Swpaul		if (*p && *p != '#')
10080219Swpaul			break;
10180219Swpaul	}
10280219Swpaul
10380219Swpaul#define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1])
10480219Swpaul#define	vcmp(e)	!strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
10580219Swpaul
10680219Swpaul	zapchar = 0;
10780219Swpaul	tty.ty_name = p;
10880219Swpaul	p = skip(p);
10980219Swpaul	if (!*(tty.ty_getty = p))
11080219Swpaul		tty.ty_getty = tty.ty_type = NULL;
11180219Swpaul	else {
11280219Swpaul		p = skip(p);
11380219Swpaul		if (!*(tty.ty_type = p))
11480219Swpaul			tty.ty_type = NULL;
11580219Swpaul		else {
11680219Swpaul			/* compatibility kludge: handle network/dialup specially */
11780219Swpaul			if (scmp(_TTYS_DIALUP))
11880219Swpaul				tty.ty_status |= TTY_DIALUP;
11980219Swpaul			else if (scmp(_TTYS_NETWORK))
12080219Swpaul				tty.ty_status |= TTY_NETWORK;
12180219Swpaul			p = skip(p);
12280219Swpaul		}
12380219Swpaul	}
12480219Swpaul	tty.ty_status = 0;
12580219Swpaul	tty.ty_window = NULL;
12680219Swpaul	tty.ty_group  = _TTYS_NOGROUP;
12780219Swpaul
12880219Swpaul	for (; *p; p = skip(p)) {
12980219Swpaul		if (scmp(_TTYS_OFF))
13080219Swpaul			tty.ty_status &= ~TTY_ON;
13180219Swpaul		else if (scmp(_TTYS_ON))
13280219Swpaul			tty.ty_status |= TTY_ON;
13380219Swpaul		else if (scmp(_TTYS_SECURE))
13480219Swpaul			tty.ty_status |= TTY_SECURE;
13580219Swpaul		else if (scmp(_TTYS_INSECURE))
13680219Swpaul			tty.ty_status &= ~TTY_SECURE;
13780219Swpaul		else if (scmp(_TTYS_DIALUP))
13880219Swpaul			tty.ty_status |= TTY_DIALUP;
13980219Swpaul		else if (scmp(_TTYS_NETWORK))
14080219Swpaul			tty.ty_status |= TTY_NETWORK;
14180219Swpaul		else if (vcmp(_TTYS_WINDOW))
14280219Swpaul			tty.ty_window = value(p);
14380219Swpaul		else if (vcmp(_TTYS_GROUP))
14480219Swpaul			tty.ty_group = value(p);
14580219Swpaul		else
14680219Swpaul			break;
14780219Swpaul	}
14880219Swpaul
14980219Swpaul	if (zapchar == '#' || *p == '#')
15080219Swpaul		while ((c = *++p) == ' ' || c == '\t')
15180219Swpaul			;
15280219Swpaul	tty.ty_comment = p;
15380219Swpaul	if (*p == 0)
15480219Swpaul		tty.ty_comment = 0;
15580219Swpaul	if ( (p = index(p, '\n')) )
15680219Swpaul		*p = '\0';
15780219Swpaul	return (&tty);
15880219Swpaul}
15980219Swpaul
16080219Swpaul#define	QUOTED	1
16180219Swpaul
16280219Swpaul/*
16380219Swpaul * Skip over the current field, removing quotes, and return a pointer to
16480219Swpaul * the next field.
16580219Swpaul */
16680219Swpaulstatic char *
16780219Swpaulskip(p)
16880219Swpaul	char *p;
16980219Swpaul{
17080219Swpaul	char *t;
17180219Swpaul	int c, q;
17280219Swpaul
17380219Swpaul	for (q = 0, t = p; (c = *p) != '\0'; p++) {
17480219Swpaul		if (c == '"') {
17580219Swpaul			q ^= QUOTED;	/* obscure, but nice */
17680219Swpaul			continue;
17780219Swpaul		}
17880219Swpaul		if (q == QUOTED && *p == '\\' && *(p+1) == '"')
17980219Swpaul			p++;
18080219Swpaul		*t++ = *p;
18180219Swpaul		if (q == QUOTED)
18280219Swpaul			continue;
18380219Swpaul		if (c == '#') {
18480219Swpaul			zapchar = c;
18580219Swpaul			*p = 0;
18680219Swpaul			break;
18780219Swpaul		}
18880219Swpaul		if (c == '\t' || c == ' ' || c == '\n') {
18980219Swpaul			zapchar = c;
19080219Swpaul			*p++ = 0;
19180219Swpaul			while ((c = *p) == '\t' || c == ' ' || c == '\n')
19280219Swpaul				p++;
19380219Swpaul			break;
19480219Swpaul		}
19580219Swpaul	}
19680219Swpaul	*--t = '\0';
19780219Swpaul	return (p);
19880219Swpaul}
19980219Swpaul
20080219Swpaulstatic char *
20180219Swpaulvalue(p)
20280219Swpaul	char *p;
20380219Swpaul{
20480219Swpaul
20580219Swpaul	return ((p = index(p, '=')) ? ++p : NULL);
20680219Swpaul}
20780219Swpaul
20880219Swpaulint
20980219Swpaulsetttyent()
21080219Swpaul{
21180219Swpaul
21280219Swpaul	if (line == NULL) {
21380219Swpaul		if ((line = malloc(MALLOCCHUNK)) == NULL)
21480219Swpaul			return (0);
21580219Swpaul		lbsize = MALLOCCHUNK;
21680219Swpaul	}
21780219Swpaul	if (tf) {
21880219Swpaul		rewind(tf);
21980219Swpaul		return (1);
22080219Swpaul	} else if ( (tf = fopen(_PATH_TTYS, "r")) )
22180219Swpaul		return (1);
22280219Swpaul	return (0);
22380219Swpaul}
22480219Swpaul
22580219Swpaulint
22680219Swpaulendttyent()
22780219Swpaul{
22880219Swpaul	int rval;
22980219Swpaul
23080219Swpaul	/*
23180219Swpaul         * NB: Don't free `line' because getttynam()
23280219Swpaul	 * may still be referencing it
23380219Swpaul	 */
23480219Swpaul	if (tf) {
23580219Swpaul		rval = (fclose(tf) != EOF);
23680219Swpaul		tf = NULL;
23780219Swpaul		return (rval);
23880219Swpaul	}
23980219Swpaul	return (1);
24080219Swpaul}
24180219Swpaul
24280219Swpaulstatic int
24380219Swpaulisttystat(tty, flag)
24480219Swpaul	const char *tty;
24580219Swpaul	int flag;
24680219Swpaul{
24780219Swpaul	struct ttyent *t;
24880219Swpaul
24980219Swpaul	return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag);
25080219Swpaul}
25180219Swpaul
25280219Swpaul
25380219Swpaulint
25480219Swpaulisdialuptty(tty)
25580219Swpaul	const char *tty;
25680455Swpaul{
25780219Swpaul
25880219Swpaul	return isttystat(tty, TTY_DIALUP);
25980219Swpaul}
26080219Swpaul
26180219Swpaulint isnettty(tty)
26280455Swpaul	const char *tty;
26380219Swpaul{
26480219Swpaul
26580219Swpaul	return isttystat(tty, TTY_NETWORK);
26680219Swpaul}
26780219Swpaul