1/*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved.  The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#pragma ident	"%Z%%M%	%I%	%E% SMI"
8
9
10#include <stdio.h>
11#include <strings.h>
12#include <ttyent.h>
13
14static char *TTYFILE = "/etc/ttytab";
15#define LINE 256
16static struct _ttyentjunk {
17	char	zapchar;
18	FILE	*tf;
19	char	line[LINE];
20	struct	ttyent tty;
21} *__ttyentjunk, *_ttyentjunk(void);
22
23static struct _ttyentjunk *
24_ttyentjunk(void)
25{
26
27	if (__ttyentjunk == 0)
28		__ttyentjunk = (struct _ttyentjunk *)calloc(1, sizeof (struct _ttyentjunk));
29	return (__ttyentjunk);
30}
31
32void
33setttyent(void)
34{
35	struct _ttyentjunk *t = _ttyentjunk();
36
37	if (t == 0)
38		return;
39	if (t->tf == NULL)
40		t->tf = fopen(TTYFILE, "r");
41	else
42		rewind(t->tf);
43}
44
45void
46endttyent(void)
47{
48	struct _ttyentjunk *t = _ttyentjunk();
49
50	if (t == 0)
51		return;
52	if (t->tf != NULL) {
53		(void) fclose(t->tf);
54		t->tf = NULL;
55	}
56}
57
58#define QUOTED	1
59
60/*
61 * Skip over the current field, removing quotes,
62 * and return a pointer to the next field.
63 */
64static char *
65skip(char *p)
66{
67	struct _ttyentjunk *t = _ttyentjunk();
68	char *cp = p;
69	int c;
70	int q = 0;
71
72	if (t == 0)
73		return (0);
74	for (; (c = *p) != '\0'; p++) {
75		if (c == '"') {
76			q ^= QUOTED;	/* obscure, but nice */
77			continue;
78		}
79		if (q == QUOTED && *p == '\\' && *(p+1) == '"')
80			p++;
81		*cp++ = *p;
82		if (q == QUOTED)
83			continue;
84		if (c == '#') {
85			t->zapchar = c;
86			*p = 0;
87			break;
88		}
89		if (c == '\t' || c == ' ' || c == '\n') {
90			t->zapchar = c;
91			*p++ = 0;
92			while ((c = *p) == '\t' || c == ' ' || c == '\n')
93				p++;
94			break;
95		}
96	}
97	*--cp = '\0';
98	return (p);
99}
100
101static char *
102value(char *p)
103{
104	if ((p = index(p,'=')) == 0)
105		return (NULL);
106	p++;			/* get past the = sign */
107	return (p);
108}
109
110struct ttyent *
111getttyent(void)
112{
113	struct _ttyentjunk *t = _ttyentjunk();
114	char *p;
115	int c;
116
117	if (t == 0)
118		return (NULL);
119	if (t->tf == NULL) {
120		if ((t->tf = fopen(TTYFILE, "r")) == NULL)
121			return (NULL);
122	}
123	do {
124		p = fgets(t->line, LINE, t->tf);
125		if (p == NULL)
126			return (NULL);
127		while ((c = *p) == '\t' || c == ' ' || c == '\n')
128			p++;
129	} while (c == '\0' || c == '#');
130	t->zapchar = 0;
131	t->tty.ty_name = p;
132	p = skip(p);
133	t->tty.ty_getty = p;
134	p = skip(p);
135	t->tty.ty_type = p;
136	p = skip(p);
137	t->tty.ty_status = 0;
138	t->tty.ty_window = NULL;
139	for (; *p; p = skip(p)) {
140#define space(x) ((c = p[x]) == ' ' || c == '\t' || c == '\n')
141		if (strncmp(p, "on", 2) == 0 && space(2))
142			t->tty.ty_status |= TTY_ON;
143		else if (strncmp(p, "off", 3) == 0 && space(3))
144			t->tty.ty_status &= ~TTY_ON;
145		else if (strncmp(p, "secure", 6) == 0 && space(6))
146			t->tty.ty_status |= TTY_SECURE;
147		else if (strncmp(p, "local", 5) == 0 && space(5))
148			t->tty.ty_status |= TTY_LOCAL;
149		else if (strncmp(p, "window=", 7) == 0)
150			t->tty.ty_window = value(p);
151		else
152			break;
153	}
154	if (t->zapchar == '#' || *p == '#')
155		while ((c = *++p) == ' ' || c == '\t')
156			;
157	t->tty.ty_comment = p;
158	if (*p == 0)
159		t->tty.ty_comment = 0;
160	if (p = index(p, '\n'))
161		*p = '\0';
162	return (&t->tty);
163}
164