getttyent.c revision 148401
1191783Srmacklem/*
2191783Srmacklem * Copyright (c) 1989, 1993
3191783Srmacklem *	The Regents of the University of California.  All rights reserved.
4191783Srmacklem *
5191783Srmacklem * Redistribution and use in source and binary forms, with or without
6191783Srmacklem * modification, are permitted provided that the following conditions
7191783Srmacklem * are met:
8191783Srmacklem * 1. Redistributions of source code must retain the above copyright
9191783Srmacklem *    notice, this list of conditions and the following disclaimer.
10191783Srmacklem * 2. Redistributions in binary form must reproduce the above copyright
11191783Srmacklem *    notice, this list of conditions and the following disclaimer in the
12191783Srmacklem *    documentation and/or other materials provided with the distribution.
13191783Srmacklem * 3. All advertising materials mentioning features or use of this software
14191783Srmacklem *    must display the following acknowledgement:
15191783Srmacklem *	This product includes software developed by the University of
16191783Srmacklem *	California, Berkeley and its contributors.
17191783Srmacklem * 4. Neither the name of the University nor the names of its contributors
18191783Srmacklem *    may be used to endorse or promote products derived from this software
19191783Srmacklem *    without specific prior written permission.
20191783Srmacklem *
21191783Srmacklem * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22191783Srmacklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23191783Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24191783Srmacklem * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25191783Srmacklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26191783Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27191783Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29191783Srmacklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30191783Srmacklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31191783Srmacklem * SUCH DAMAGE.
32191783Srmacklem */
33191783Srmacklem
34191783Srmacklem#if defined(LIBC_SCCS) && !defined(lint)
35191783Srmacklemstatic char sccsid[] = "@(#)getttyent.c	8.1 (Berkeley) 6/4/93";
36191783Srmacklem#endif /* LIBC_SCCS and not lint */
37191783Srmacklem#include <sys/cdefs.h>
38191783Srmacklem__FBSDID("$FreeBSD: head/lib/libc/gen/getttyent.c 148401 2005-07-25 17:57:15Z mdodd $");
39191783Srmacklem
40191783Srmacklem#include <ttyent.h>
41191783Srmacklem#include <stdio.h>
42191783Srmacklem#include <stdlib.h>
43191783Srmacklem#include <ctype.h>
44191783Srmacklem#include <string.h>
45191783Srmacklem
46191783Srmacklemstatic char zapchar;
47191783Srmacklemstatic FILE *tf;
48191783Srmacklemstatic size_t lbsize;
49191783Srmacklemstatic char *line;
50191783Srmacklem
51191783Srmacklem#define	MALLOCCHUNK	100
52191783Srmacklem
53191783Srmacklemstatic char *skip(char *);
54191783Srmacklemstatic char *value(char *);
55191783Srmacklem
56191783Srmacklemstruct ttyent *
57191783Srmacklemgetttynam(tty)
58191783Srmacklem	const char *tty;
59191783Srmacklem{
60191783Srmacklem	struct ttyent *t;
61191783Srmacklem
62191783Srmacklem	if (strncmp(tty, "/dev/", 5) == 0)
63191783Srmacklem		tty += 5;
64191783Srmacklem	setttyent();
65191783Srmacklem	while ( (t = getttyent()) )
66191783Srmacklem		if (!strcmp(tty, t->ty_name))
67191783Srmacklem			break;
68191783Srmacklem	endttyent();
69191783Srmacklem	return (t);
70191783Srmacklem}
71191783Srmacklem
72191783Srmacklemstruct ttyent *
73191783Srmacklemgetttyent()
74191783Srmacklem{
75191783Srmacklem	static struct ttyent tty;
76191783Srmacklem	char *p;
77191783Srmacklem	int c;
78191783Srmacklem	size_t i;
79191783Srmacklem
80191783Srmacklem	if (!tf && !setttyent())
81191783Srmacklem		return (NULL);
82191783Srmacklem	for (;;) {
83191783Srmacklem		if (!fgets(p = line, lbsize, tf))
84191783Srmacklem			return (NULL);
85191783Srmacklem		/* extend buffer if line was too big, and retry */
86191783Srmacklem		while (!index(p, '\n')) {
87192115Srmacklem			i = strlen(p);
88191783Srmacklem			lbsize += MALLOCCHUNK;
89191783Srmacklem			if ((p = realloc(line, lbsize)) == NULL) {
90191783Srmacklem				(void)endttyent();
91191783Srmacklem				return (NULL);
92191783Srmacklem			}
93191783Srmacklem			line = p;
94191783Srmacklem			if (!fgets(&line[i], lbsize - i, tf))
95191783Srmacklem				return (NULL);
96191783Srmacklem		}
97191783Srmacklem		while (isspace((unsigned char)*p))
98191783Srmacklem			++p;
99191783Srmacklem		if (*p && *p != '#')
100191783Srmacklem			break;
101191783Srmacklem	}
102191783Srmacklem
103191783Srmacklem#define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1])
104191783Srmacklem#define	vcmp(e)	!strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
105191783Srmacklem
106191783Srmacklem	zapchar = 0;
107191783Srmacklem	tty.ty_name = p;
108191783Srmacklem	tty.ty_status = 0;
109191783Srmacklem	tty.ty_window = NULL;
110191783Srmacklem	tty.ty_group  = _TTYS_NOGROUP;
111191783Srmacklem
112191783Srmacklem	p = skip(p);
113191783Srmacklem	if (!*(tty.ty_getty = p))
114191783Srmacklem		tty.ty_getty = tty.ty_type = NULL;
115191783Srmacklem	else {
116191783Srmacklem		p = skip(p);
117191783Srmacklem		if (!*(tty.ty_type = p))
118191783Srmacklem			tty.ty_type = NULL;
119191783Srmacklem		else {
120191783Srmacklem			/* compatibility kludge: handle network/dialup specially */
121191783Srmacklem			if (scmp(_TTYS_DIALUP))
122191783Srmacklem				tty.ty_status |= TTY_DIALUP;
123191783Srmacklem			else if (scmp(_TTYS_NETWORK))
124191783Srmacklem				tty.ty_status |= TTY_NETWORK;
125191783Srmacklem			p = skip(p);
126220530Srmacklem		}
127191783Srmacklem	}
128192115Srmacklem
129191783Srmacklem	for (; *p; p = skip(p)) {
130191783Srmacklem		if (scmp(_TTYS_OFF))
131191783Srmacklem			tty.ty_status &= ~TTY_ON;
132191783Srmacklem		else if (scmp(_TTYS_ON))
133191783Srmacklem			tty.ty_status |= TTY_ON;
134191783Srmacklem		else if (scmp(_TTYS_SECURE))
135191783Srmacklem			tty.ty_status |= TTY_SECURE;
136191783Srmacklem		else if (scmp(_TTYS_INSECURE))
137191783Srmacklem			tty.ty_status &= ~TTY_SECURE;
138191783Srmacklem		else if (scmp(_TTYS_DIALUP))
139191783Srmacklem			tty.ty_status |= TTY_DIALUP;
140191783Srmacklem		else if (scmp(_TTYS_NETWORK))
141191783Srmacklem			tty.ty_status |= TTY_NETWORK;
142191783Srmacklem		else if (vcmp(_TTYS_WINDOW))
143191783Srmacklem			tty.ty_window = value(p);
144191783Srmacklem		else if (vcmp(_TTYS_GROUP))
145191783Srmacklem			tty.ty_group = value(p);
146191783Srmacklem		else
147191783Srmacklem			break;
148191783Srmacklem	}
149191783Srmacklem
150191783Srmacklem	if (zapchar == '#' || *p == '#')
151191783Srmacklem		while ((c = *++p) == ' ' || c == '\t')
152191783Srmacklem			;
153191783Srmacklem	tty.ty_comment = p;
154191783Srmacklem	if (*p == 0)
155191783Srmacklem		tty.ty_comment = 0;
156191783Srmacklem	if ( (p = index(p, '\n')) )
157191783Srmacklem		*p = '\0';
158191783Srmacklem	return (&tty);
159191783Srmacklem}
160191783Srmacklem
161191783Srmacklem#define	QUOTED	1
162191783Srmacklem
163191783Srmacklem/*
164191783Srmacklem * Skip over the current field, removing quotes, and return a pointer to
165191783Srmacklem * the next field.
166191783Srmacklem */
167191783Srmacklemstatic char *
168191783Srmacklemskip(p)
169191783Srmacklem	char *p;
170191783Srmacklem{
171191783Srmacklem	char *t;
172191783Srmacklem	int c, q;
173191783Srmacklem
174191783Srmacklem	for (q = 0, t = p; (c = *p) != '\0'; p++) {
175191783Srmacklem		if (c == '"') {
176191783Srmacklem			q ^= QUOTED;	/* obscure, but nice */
177191783Srmacklem			continue;
178191783Srmacklem		}
179191783Srmacklem		if (q == QUOTED && *p == '\\' && *(p+1) == '"')
180191783Srmacklem			p++;
181191783Srmacklem		*t++ = *p;
182191783Srmacklem		if (q == QUOTED)
183191783Srmacklem			continue;
184191783Srmacklem		if (c == '#') {
185191783Srmacklem			zapchar = c;
186191783Srmacklem			*p = 0;
187191783Srmacklem			break;
188191783Srmacklem		}
189191783Srmacklem		if (c == '\t' || c == ' ' || c == '\n') {
190191783Srmacklem			zapchar = c;
191191783Srmacklem			*p++ = 0;
192191783Srmacklem			while ((c = *p) == '\t' || c == ' ' || c == '\n')
193191783Srmacklem				p++;
194191783Srmacklem			break;
195191783Srmacklem		}
196191783Srmacklem	}
197191783Srmacklem	*--t = '\0';
198191783Srmacklem	return (p);
199191783Srmacklem}
200191783Srmacklem
201191783Srmacklemstatic char *
202191783Srmacklemvalue(p)
203191783Srmacklem	char *p;
204191783Srmacklem{
205191783Srmacklem
206191783Srmacklem	return ((p = index(p, '=')) ? ++p : NULL);
207191783Srmacklem}
208191783Srmacklem
209191783Srmacklemint
210191783Srmacklemsetttyent()
211191783Srmacklem{
212192115Srmacklem
213191783Srmacklem	if (line == NULL) {
214191783Srmacklem		if ((line = malloc(MALLOCCHUNK)) == NULL)
215191783Srmacklem			return (0);
216192115Srmacklem		lbsize = MALLOCCHUNK;
217191783Srmacklem	}
218191783Srmacklem	if (tf) {
219191783Srmacklem		rewind(tf);
220191783Srmacklem		return (1);
221191783Srmacklem	} else if ( (tf = fopen(_PATH_TTYS, "r")) )
222191783Srmacklem		return (1);
223191783Srmacklem	return (0);
224191783Srmacklem}
225191783Srmacklem
226191783Srmacklemint
227192115Srmacklemendttyent()
228191783Srmacklem{
229191783Srmacklem	int rval;
230191783Srmacklem
231191783Srmacklem	/*
232191783Srmacklem         * NB: Don't free `line' because getttynam()
233191783Srmacklem	 * may still be referencing it
234191783Srmacklem	 */
235251641Sken	if (tf) {
236191783Srmacklem		rval = (fclose(tf) != EOF);
237191783Srmacklem		tf = NULL;
238191783Srmacklem		return (rval);
239191783Srmacklem	}
240191783Srmacklem	return (1);
241191783Srmacklem}
242191783Srmacklem
243191783Srmacklemstatic int
244191783Srmacklemisttystat(tty, flag)
245191783Srmacklem	const char *tty;
246191783Srmacklem	int flag;
247191783Srmacklem{
248191783Srmacklem	struct ttyent *t;
249191783Srmacklem
250222389Srmacklem	return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag);
251191783Srmacklem}
252191783Srmacklem
253222389Srmacklem
254211951Srmacklemint
255205941Srmacklemisdialuptty(tty)
256191783Srmacklem	const char *tty;
257191783Srmacklem{
258192115Srmacklem
259192115Srmacklem	return isttystat(tty, TTY_DIALUP);
260191783Srmacklem}
261192115Srmacklem
262191783Srmacklemint isnettty(tty)
263191783Srmacklem	const char *tty;
264191783Srmacklem{
265191783Srmacklem
266191783Srmacklem	return isttystat(tty, TTY_NETWORK);
267191783Srmacklem}
268191783Srmacklem