1 | /* |
2 | * Copyright (c) 1989, 1993 |
3 | * The Regents of the University of California. All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * 4. Neither the name of the University nor the names of its contributors |
14 | * may be used to endorse or promote products derived from this software |
15 | * without specific prior written permission. |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. |
28 | */ |
29 | |
30 | #if defined(LIBC_SCCS) && !defined(lint) |
31 | static char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93" ; |
32 | #endif /* LIBC_SCCS and not lint */ |
33 | |
34 | #include <ttyent.h> |
35 | #include <stdio.h> |
36 | #include <stdio_ext.h> |
37 | #include <ctype.h> |
38 | #include <string.h> |
39 | |
40 | #define flockfile(s) _IO_flockfile (s) |
41 | #define funlockfile(s) _IO_funlockfile (s) |
42 | |
43 | static char zapchar; |
44 | static FILE *tf; |
45 | |
46 | struct ttyent * |
47 | __getttynam (const char *tty) |
48 | { |
49 | struct ttyent *t; |
50 | |
51 | __setttyent(); |
52 | while ((t = __getttyent())) |
53 | if (!strcmp(tty, t->ty_name)) |
54 | break; |
55 | __endttyent(); |
56 | return (t); |
57 | } |
58 | weak_alias (__getttynam, getttynam) |
59 | |
60 | static char *skip (char *) __THROW internal_function; |
61 | static char *value (char *) __THROW internal_function; |
62 | |
63 | struct ttyent * |
64 | __getttyent (void) |
65 | { |
66 | static struct ttyent tty; |
67 | int c; |
68 | char *p; |
69 | #define MAXLINELENGTH 100 |
70 | static char line[MAXLINELENGTH]; |
71 | |
72 | if (!tf && !__setttyent()) |
73 | return (NULL); |
74 | flockfile (tf); |
75 | for (;;) { |
76 | if (!__fgets_unlocked(p = line, sizeof(line), tf)) { |
77 | funlockfile (tf); |
78 | return (NULL); |
79 | } |
80 | /* skip lines that are too big */ |
81 | if (!strchr (p, '\n')) { |
82 | while ((c = getc_unlocked(tf)) != '\n' && c != EOF) |
83 | ; |
84 | continue; |
85 | } |
86 | while (isspace(*p)) |
87 | ++p; |
88 | if (*p && *p != '#') |
89 | break; |
90 | } |
91 | |
92 | zapchar = 0; |
93 | tty.ty_name = p; |
94 | p = skip(p); |
95 | if (!*(tty.ty_getty = p)) |
96 | tty.ty_getty = tty.ty_type = NULL; |
97 | else { |
98 | p = skip(p); |
99 | if (!*(tty.ty_type = p)) |
100 | tty.ty_type = NULL; |
101 | else |
102 | p = skip(p); |
103 | } |
104 | tty.ty_status = 0; |
105 | tty.ty_window = NULL; |
106 | |
107 | #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace(p[sizeof(e) - 1]) |
108 | #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' |
109 | for (; *p; p = skip(p)) { |
110 | if (scmp(_TTYS_OFF)) |
111 | tty.ty_status &= ~TTY_ON; |
112 | else if (scmp(_TTYS_ON)) |
113 | tty.ty_status |= TTY_ON; |
114 | else if (scmp(_TTYS_SECURE)) |
115 | tty.ty_status |= TTY_SECURE; |
116 | else if (vcmp(_TTYS_WINDOW)) |
117 | tty.ty_window = value(p); |
118 | else |
119 | break; |
120 | } |
121 | /* We can release the lock only here since `zapchar' is global. */ |
122 | funlockfile(tf); |
123 | |
124 | if (zapchar == '#' || *p == '#') |
125 | while ((c = *++p) == ' ' || c == '\t') |
126 | ; |
127 | tty.ty_comment = p; |
128 | if (*p == 0) |
129 | tty.ty_comment = 0; |
130 | if ((p = strchr (p, '\n'))) |
131 | *p = '\0'; |
132 | return (&tty); |
133 | } |
134 | libc_hidden_def (__getttyent) |
135 | weak_alias (__getttyent, getttyent) |
136 | |
137 | #define QUOTED 1 |
138 | |
139 | /* |
140 | * Skip over the current field, removing quotes, and return a pointer to |
141 | * the next field. |
142 | */ |
143 | static char * |
144 | internal_function |
145 | skip (char *p) |
146 | { |
147 | char *t; |
148 | int c, q; |
149 | |
150 | for (q = 0, t = p; (c = *p) != '\0'; p++) { |
151 | if (c == '"') { |
152 | q ^= QUOTED; /* obscure, but nice */ |
153 | continue; |
154 | } |
155 | if (q == QUOTED && *p == '\\' && *(p+1) == '"') |
156 | p++; |
157 | *t++ = *p; |
158 | if (q == QUOTED) |
159 | continue; |
160 | if (c == '#') { |
161 | zapchar = c; |
162 | *p = 0; |
163 | break; |
164 | } |
165 | if (c == '\t' || c == ' ' || c == '\n') { |
166 | zapchar = c; |
167 | *p++ = 0; |
168 | while ((c = *p) == '\t' || c == ' ' || c == '\n') |
169 | p++; |
170 | break; |
171 | } |
172 | } |
173 | *--t = '\0'; |
174 | return (p); |
175 | } |
176 | |
177 | static char * |
178 | internal_function |
179 | value (char *p) |
180 | { |
181 | |
182 | return ((p = strchr (p, '=')) ? ++p : NULL); |
183 | } |
184 | |
185 | int |
186 | __setttyent (void) |
187 | { |
188 | |
189 | if (tf) { |
190 | (void)rewind(tf); |
191 | return (1); |
192 | } else if ((tf = fopen(_PATH_TTYS, "rce" ))) { |
193 | /* We do the locking ourselves. */ |
194 | __fsetlocking (tf, FSETLOCKING_BYCALLER); |
195 | return (1); |
196 | } |
197 | return (0); |
198 | } |
199 | libc_hidden_def (__setttyent) |
200 | weak_alias (__setttyent, setttyent) |
201 | |
202 | int |
203 | __endttyent (void) |
204 | { |
205 | int rval; |
206 | |
207 | if (tf) { |
208 | rval = !(fclose(tf) == EOF); |
209 | tf = NULL; |
210 | return (rval); |
211 | } |
212 | return (1); |
213 | } |
214 | libc_hidden_def (__endttyent) |
215 | weak_alias (__endttyent, endttyent) |
216 | |