tools/llvm: Do not build with symbols
[minix3.git] / lib / libc / gen / getttyent.c
blob6585ebefa3c43960da74bee99d31ab4f358b9d50
1 /* $NetBSD: getttyent.c,v 1.26 2013/06/30 10:07:43 martin Exp $ */
3 /*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
34 #if 0
35 static char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93";
36 #else
37 __RCSID("$NetBSD: getttyent.c,v 1.26 2013/06/30 10:07:43 martin Exp $");
38 #endif
39 #endif /* LIBC_SCCS and not lint */
41 #include "namespace.h"
43 #include <assert.h>
44 #include <ctype.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <ttyent.h>
48 #include <errno.h>
49 #include <err.h>
50 #include <stdlib.h>
52 #include <sys/sysctl.h>
53 #include <sys/utsname.h>
55 #ifdef __weak_alias
56 __weak_alias(endttyent,_endttyent)
57 __weak_alias(getttyent,_getttyent)
58 __weak_alias(getttynam,_getttynam)
59 __weak_alias(setttyent,_setttyent)
60 __weak_alias(setttyentpath,_setttyentpath)
61 #endif
63 static FILE *tf;
64 static size_t lineno = 0;
65 static char *skip(char *, char *);
66 static char *value(char *);
68 struct ttyent *
69 getttynam(const char *tty)
71 struct ttyent *t;
73 _DIAGASSERT(tty != NULL);
75 setttyent();
76 while ((t = getttyent()) != NULL)
77 if (!strcmp(tty, t->ty_name))
78 break;
79 endttyent();
80 return (t);
83 struct ttyent *
84 getttyent(void)
86 static struct ttyent tty;
87 int c;
88 char *p;
89 size_t len;
90 static char *line = NULL;
91 char zapchar;
93 if (line)
94 free(line);
96 if (!tf && !setttyent())
97 return NULL;
99 for (;;) {
100 errno = 0;
101 line = fparseln(tf, &len, &lineno, NULL, FPARSELN_UNESCALL);
102 if (line == NULL) {
103 if (errno != 0)
104 warn(__func__);
105 return NULL;
107 for (p = line; *p && isspace((unsigned char)*p); p++)
108 continue;
109 if (*p && *p != '#')
110 break;
111 free(line);
114 tty.ty_name = p;
115 p = skip(p, &zapchar);
116 if (*(tty.ty_getty = p) == '\0')
117 tty.ty_getty = tty.ty_type = NULL;
118 else {
119 p = skip(p, &zapchar);
120 if (*(tty.ty_type = p) == '\0')
121 tty.ty_type = NULL;
122 else
123 p = skip(p, &zapchar);
125 tty.ty_status = 0;
126 tty.ty_window = NULL;
127 tty.ty_class = NULL;
129 #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && (isspace((unsigned char) p[sizeof(e) - 1]) || p[sizeof(e) - 1] == '\0')
130 #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
131 for (; *p; p = skip(p, &zapchar)) {
132 if (scmp(_TTYS_OFF))
133 tty.ty_status &= ~TTY_ON;
134 else if (scmp(_TTYS_ON))
135 tty.ty_status |= TTY_ON;
136 else if (scmp(_TTYS_SECURE))
137 tty.ty_status |= TTY_SECURE;
138 else if (scmp(_TTYS_LOCAL))
139 tty.ty_status |= TTY_LOCAL;
140 else if (scmp(_TTYS_RTSCTS))
141 tty.ty_status |= TTY_RTSCTS;
142 else if (scmp(_TTYS_DTRCTS))
143 tty.ty_status |= TTY_DTRCTS;
144 else if (scmp(_TTYS_SOFTCAR))
145 tty.ty_status |= TTY_SOFTCAR;
146 else if (scmp(_TTYS_MDMBUF))
147 tty.ty_status |= TTY_MDMBUF;
148 else if (vcmp(_TTYS_WINDOW))
149 tty.ty_window = value(p);
150 else if (vcmp(_TTYS_CLASS))
151 tty.ty_class = value(p);
152 else
153 warnx("%s: %s, %lu: unknown option `%s'",
154 __func__, _PATH_TTYS, (unsigned long)lineno, p);
157 if (zapchar == '#' || *p == '#')
158 while ((c = *++p) == ' ' || c == '\t')
159 continue;
160 tty.ty_comment = p;
161 if (*p == '\0')
162 tty.ty_comment = NULL;
163 if ((p = strchr(p, '\n')) != NULL)
164 *p = '\0';
165 return &tty;
168 #define QUOTED 1
171 * Skip over the current field, removing quotes, and return a pointer to
172 * the next field.
174 static char *
175 skip(char *p, char *zapchar)
177 char *t;
178 int c, q;
180 _DIAGASSERT(p != NULL);
181 *zapchar = '\0';
183 for (q = 0, t = p; (c = *p) != '\0'; p++) {
184 if (c == '"') {
185 q ^= QUOTED; /* obscure, but nice */
186 continue;
188 if (q == QUOTED && *p == '\\' && *(p+1) == '"')
189 p++;
190 *t++ = *p;
191 if (q == QUOTED)
192 continue;
193 if (c == '#') {
194 *zapchar = c;
195 *p = '\0';
196 *--t = '\0';
197 return p;
199 if (c == '\t' || c == ' ' || c == '\n') {
200 *zapchar = c;
201 *p++ = '\0';
202 while ((c = *p) == '\t' || c == ' ' || c == '\n')
203 p++;
204 *--t = '\0';
205 return p;
208 if (t != p)
209 *t = '\0';
210 return p;
213 static char *
214 value(char *p)
217 _DIAGASSERT(p != NULL);
219 return (p = strchr(p, '=')) != NULL ? ++p : NULL;
223 setttyentpath(const char *path)
225 lineno = 0;
226 if (tf) {
227 rewind(tf);
228 return 1;
232 * Try <path>.$MACHINE (e.g. etc/ttys.amd64)
235 char machine[_SYS_NMLN];
236 const int mib[] = { [0] = CTL_HW, [1] = HW_MACHINE, };
237 size_t len = sizeof(machine);
239 if (sysctl(mib, (u_int)__arraycount(mib), machine, &len,
240 NULL, 0) != -1) {
241 char npath[PATH_MAX];
242 (void)snprintf(npath, sizeof(npath), "%s.%s", path,
243 machine);
244 if ((tf = fopen(npath, "re")) != NULL)
245 return 1;
249 if ((tf = fopen(path, "re")) != NULL)
250 return 1;
251 return 0;
255 setttyent(void)
257 return setttyentpath(_PATH_TTYS);
261 endttyent(void)
263 int rval;
265 if (tf) {
266 rval = !(fclose(tf) == EOF);
267 tf = NULL;
268 return rval;
270 return 1;