1 /*
2  * Copyright (c) 1989 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  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  */
20 
21 #if defined(LIBC_SCCS) && !defined(lint)
22 static char sccsid[] = "@(#)getttyent.c	5.1 (Berkeley) 05/16/89";
23 #endif /* LIBC_SCCS and not lint */
24 
25 #include <stdio.h>
26 #include <strings.h>
27 #include <ttyent.h>
28 
29 static char TTYFILE[] = "/etc/ttys";
30 static char zapchar;
31 static FILE *tf = NULL;
32 #define LINE 256
33 static char line[LINE];
34 static struct ttyent tty;
35 #define NOPTS 32
36 static char *options[NOPTS];
37 
38 setttyent()
39 {
40 	if (tf == NULL)
41 		tf = fopen(TTYFILE, "r");
42 	else
43 		rewind(tf);
44 }
45 
46 endttyent()
47 {
48 	if (tf != NULL) {
49 		(void) fclose(tf);
50 		tf = NULL;
51 	}
52 }
53 
54 #define QUOTED	1
55 
56 /*
57  * Skip over the current field, removing quotes,
58  * and return a pointer to the next field.
59  */
60 static char *
61 skip(p)
62 	register char *p;
63 {
64 	register char *t = p;
65 	register int c;
66 	register int q = 0;
67 
68 	for (; (c = *p) != '\0'; p++) {
69 		if (c == '"') {
70 			q ^= QUOTED;	/* obscure, but nice */
71 			continue;
72 		}
73 		if (q == QUOTED && *p == '\\' && *(p+1) == '"')
74 			p++;
75 		*t++ = *p;
76 		if (q == QUOTED)
77 			continue;
78 		if (c == '#') {
79 			zapchar = c;
80 			*p = 0;
81 			break;
82 		}
83 		if (c == '\t' || c == ' ' || c == '\n') {
84 			zapchar = c;
85 			*p++ = 0;
86 			while ((c = *p) == '\t' || c == ' ' || c == '\n')
87 				p++;
88 			break;
89 		}
90 	}
91 	*--t = '\0';
92 	return (p);
93 }
94 
95 static char *
96 value(p)
97 	register char *p;
98 {
99 	if ((p = index(p,'=')) == 0)
100 		return(NULL);
101 	p++;			/* get past the = sign */
102 	return(p);
103 }
104 
105 struct ttyent *
106 getttyent()
107 {
108 	register char *p;
109 	register int c;
110 	register char **op;
111 
112 	if (tf == NULL) {
113 		if ((tf = fopen(TTYFILE, "r")) == NULL)
114 			return (NULL);
115 	}
116 	do {
117 		p = fgets(line, LINE, tf);
118 		if (p == NULL)
119 			return (NULL);
120 		while ((c = *p) == '\t' || c == ' ' || c == '\n')
121 			p++;
122 	} while (c == '\0' || c == '#');
123 	zapchar = 0;
124 	tty.ty_name = p;
125 	p = skip(p);
126 	tty.ty_getty = p;
127 	p = skip(p);
128 	tty.ty_type = p;
129 	p = skip(p);
130 	tty.ty_status = 0;
131 	tty.ty_window = NULL;
132 	tty.ty_flags = options ;
133 	op = options ;
134 	for (; *p; p = skip(p)) {
135 		*op++ = p ; /* bounds check ? */
136 #define space(x) ((c = p[x]) == ' ' || c == '\t' || c == '\n')
137 		if (strncmp(p, "on", 2) == 0 && space(2))
138 			tty.ty_status |= TTY_ON;
139 		else if (strncmp(p, "off", 3) == 0 && space(3))
140 			tty.ty_status &= ~TTY_ON;
141 		else if (strncmp(p, "secure", 6) == 0 && space(6))
142 			tty.ty_status |= TTY_SECURE;
143 		else if (strncmp(p, "window=", 7) == 0)
144 			tty.ty_window = value(p);
145 		else if (zapchar == '#' || *p == '#')
146 			break;
147 	}
148 	*op = 0 ;	/* end sentinel */
149 	if (zapchar == '#' || *p == '#')
150 		while ((c = *++p) == ' ' || c == '\t')
151 			;
152 	tty.ty_comment = p;
153 	if (*p == 0)
154 		tty.ty_comment = 0;
155 	if (p = index(p, '\n'))
156 		*p = '\0';
157 	return(&tty);
158 }
159