1 /*-
2  * Copyright (c) 1993 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Bill Jolitz.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #if defined(LIBC_SCCS) && !defined(lint)
12 static char sccsid[] = "@(#)getttyent.c	5.2 (Berkeley) 05/29/93";
13 #endif /* LIBC_SCCS and not lint */
14 
15 #include <stdio.h>
16 #include <strings.h>
17 #include <ttyent.h>
18 
19 static char TTYFILE[] = "/etc/ttys";
20 static char zapchar;
21 static FILE *tf = NULL;
22 #define LINE 256
23 static char line[LINE];
24 static struct ttyent tty;
25 #define NOPTS 32
26 static char *options[NOPTS];
27 
28 setttyent()
29 {
30 	if (tf == NULL)
31 		tf = fopen(TTYFILE, "r");
32 	else
33 		rewind(tf);
34 }
35 
36 endttyent()
37 {
38 	if (tf != NULL) {
39 		(void) fclose(tf);
40 		tf = NULL;
41 	}
42 }
43 
44 #define QUOTED	1
45 
46 /*
47  * Skip over the current field, removing quotes,
48  * and return a pointer to the next field.
49  */
50 static char *
51 skip(p)
52 	register char *p;
53 {
54 	register char *t = p;
55 	register int c;
56 	register int q = 0;
57 
58 	for (; (c = *p) != '\0'; p++) {
59 		if (c == '"') {
60 			q ^= QUOTED;	/* obscure, but nice */
61 			continue;
62 		}
63 		if (q == QUOTED && *p == '\\' && *(p+1) == '"')
64 			p++;
65 		*t++ = *p;
66 		if (q == QUOTED)
67 			continue;
68 		if (c == '#') {
69 			zapchar = c;
70 			*p = 0;
71 			break;
72 		}
73 		if (c == '\t' || c == ' ' || c == '\n') {
74 			zapchar = c;
75 			*p++ = 0;
76 			while ((c = *p) == '\t' || c == ' ' || c == '\n')
77 				p++;
78 			break;
79 		}
80 	}
81 	*--t = '\0';
82 	return (p);
83 }
84 
85 static char *
86 value(p)
87 	register char *p;
88 {
89 	if ((p = index(p,'=')) == 0)
90 		return(NULL);
91 	p++;			/* get past the = sign */
92 	return(p);
93 }
94 
95 struct ttyent *
96 getttyent()
97 {
98 	register char *p;
99 	register int c;
100 	register char **op;
101 
102 	if (tf == NULL) {
103 		if ((tf = fopen(TTYFILE, "r")) == NULL)
104 			return (NULL);
105 	}
106 	do {
107 		p = fgets(line, LINE, tf);
108 		if (p == NULL)
109 			return (NULL);
110 		while ((c = *p) == '\t' || c == ' ' || c == '\n')
111 			p++;
112 	} while (c == '\0' || c == '#');
113 	zapchar = 0;
114 	tty.ty_name = p;
115 	p = skip(p);
116 	tty.ty_getty = p;
117 	p = skip(p);
118 	tty.ty_type = p;
119 	p = skip(p);
120 	tty.ty_status = 0;
121 	tty.ty_window = NULL;
122 	tty.ty_flags = options ;
123 	op = options ;
124 	for (; *p; p = skip(p)) {
125 		*op++ = p ; /* bounds check ? */
126 #define space(x) ((c = p[x]) == ' ' || c == '\t' || c == '\n')
127 		if (strncmp(p, "on", 2) == 0 && space(2))
128 			tty.ty_status |= TTY_ON;
129 		else if (strncmp(p, "off", 3) == 0 && space(3))
130 			tty.ty_status &= ~TTY_ON;
131 		else if (strncmp(p, "secure", 6) == 0 && space(6))
132 			tty.ty_status |= TTY_SECURE;
133 		else if (strncmp(p, "window=", 7) == 0)
134 			tty.ty_window = value(p);
135 		else if (zapchar == '#' || *p == '#')
136 			break;
137 	}
138 	*op = 0 ;	/* end sentinel */
139 	if (zapchar == '#' || *p == '#')
140 		while ((c = *++p) == ' ' || c == '\t')
141 			;
142 	tty.ty_comment = p;
143 	if (*p == 0)
144 		tty.ty_comment = 0;
145 	if (p = index(p, '\n'))
146 		*p = '\0';
147 	return(&tty);
148 }
149