1*6caac9d0Smartin /* $NetBSD: getttyent.c,v 1.26 2013/06/30 10:07:43 martin Exp $ */
2b585e843Scgd
361f28255Scgd /*
4b585e843Scgd * Copyright (c) 1989, 1993
5b585e843Scgd * The Regents of the University of California. All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
15eb7c1594Sagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
32052e43e4Schristos #include <sys/cdefs.h>
3361f28255Scgd #if defined(LIBC_SCCS) && !defined(lint)
34b585e843Scgd #if 0
35b585e843Scgd static char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93";
36b585e843Scgd #else
37*6caac9d0Smartin __RCSID("$NetBSD: getttyent.c,v 1.26 2013/06/30 10:07:43 martin Exp $");
38b585e843Scgd #endif
3961f28255Scgd #endif /* LIBC_SCCS and not lint */
4061f28255Scgd
4143fa6fe3Sjtc #include "namespace.h"
42b48252f3Slukem
43b48252f3Slukem #include <assert.h>
4461f28255Scgd #include <ctype.h>
45b48252f3Slukem #include <stdio.h>
4661f28255Scgd #include <string.h>
47b48252f3Slukem #include <ttyent.h>
48622e897fSchristos #include <errno.h>
49622e897fSchristos #include <err.h>
50622e897fSchristos #include <stdlib.h>
5161f28255Scgd
52138bf8b9Smatt #include <sys/sysctl.h>
53138bf8b9Smatt #include <sys/utsname.h>
54138bf8b9Smatt
5543fa6fe3Sjtc #ifdef __weak_alias
5660549036Smycroft __weak_alias(endttyent,_endttyent)
5760549036Smycroft __weak_alias(getttyent,_getttyent)
5860549036Smycroft __weak_alias(getttynam,_getttynam)
5960549036Smycroft __weak_alias(setttyent,_setttyent)
602118fde3Ssalo __weak_alias(setttyentpath,_setttyentpath)
6143fa6fe3Sjtc #endif
6243fa6fe3Sjtc
6361f28255Scgd static FILE *tf;
64622e897fSchristos static size_t lineno = 0;
65ba984735Schristos static char *skip(char *, char *);
66ba984735Schristos static char *value(char *);
6761f28255Scgd
6861f28255Scgd struct ttyent *
getttynam(const char * tty)69ba984735Schristos getttynam(const char *tty)
7061f28255Scgd {
714146d586Sperry struct ttyent *t;
7261f28255Scgd
73b48252f3Slukem _DIAGASSERT(tty != NULL);
74b48252f3Slukem
7561f28255Scgd setttyent();
76052e43e4Schristos while ((t = getttyent()) != NULL)
7761f28255Scgd if (!strcmp(tty, t->ty_name))
7861f28255Scgd break;
7961f28255Scgd endttyent();
8061f28255Scgd return (t);
8161f28255Scgd }
8261f28255Scgd
8361f28255Scgd struct ttyent *
getttyent(void)84ba984735Schristos getttyent(void)
8561f28255Scgd {
8661f28255Scgd static struct ttyent tty;
874146d586Sperry int c;
884146d586Sperry char *p;
89622e897fSchristos size_t len;
90622e897fSchristos static char *line = NULL;
91ba984735Schristos char zapchar;
9261f28255Scgd
93622e897fSchristos if (line)
94622e897fSchristos free(line);
95ba984735Schristos
96ba984735Schristos if (!tf && !setttyent())
97ba984735Schristos return NULL;
98ba984735Schristos
9961f28255Scgd for (;;) {
100622e897fSchristos errno = 0;
101622e897fSchristos line = fparseln(tf, &len, &lineno, NULL, FPARSELN_UNESCALL);
102622e897fSchristos if (line == NULL) {
103622e897fSchristos if (errno != 0)
104ba984735Schristos warn(__func__);
105622e897fSchristos return NULL;
10661f28255Scgd }
107622e897fSchristos for (p = line; *p && isspace((unsigned char)*p); p++)
108622e897fSchristos continue;
10961f28255Scgd if (*p && *p != '#')
11061f28255Scgd break;
111622e897fSchristos free(line);
11261f28255Scgd }
11361f28255Scgd
11461f28255Scgd tty.ty_name = p;
115ba984735Schristos p = skip(p, &zapchar);
116ba984735Schristos if (*(tty.ty_getty = p) == '\0')
11761f28255Scgd tty.ty_getty = tty.ty_type = NULL;
11861f28255Scgd else {
119ba984735Schristos p = skip(p, &zapchar);
120ba984735Schristos if (*(tty.ty_type = p) == '\0')
12161f28255Scgd tty.ty_type = NULL;
12261f28255Scgd else
123ba984735Schristos p = skip(p, &zapchar);
12461f28255Scgd }
12561f28255Scgd tty.ty_status = 0;
12661f28255Scgd tty.ty_window = NULL;
127d1ca0533Schristos tty.ty_class = NULL;
12861f28255Scgd
129622e897fSchristos #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && (isspace((unsigned char) p[sizeof(e) - 1]) || p[sizeof(e) - 1] == '\0')
13061f28255Scgd #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
131ba984735Schristos for (; *p; p = skip(p, &zapchar)) {
13261f28255Scgd if (scmp(_TTYS_OFF))
13361f28255Scgd tty.ty_status &= ~TTY_ON;
13461f28255Scgd else if (scmp(_TTYS_ON))
13561f28255Scgd tty.ty_status |= TTY_ON;
13661f28255Scgd else if (scmp(_TTYS_SECURE))
13761f28255Scgd tty.ty_status |= TTY_SECURE;
138a1fcdedbScgd else if (scmp(_TTYS_LOCAL))
139a1fcdedbScgd tty.ty_status |= TTY_LOCAL;
140a1fcdedbScgd else if (scmp(_TTYS_RTSCTS))
141a1fcdedbScgd tty.ty_status |= TTY_RTSCTS;
14294cf4332Sscottr else if (scmp(_TTYS_DTRCTS))
14394cf4332Sscottr tty.ty_status |= TTY_DTRCTS;
144a1fcdedbScgd else if (scmp(_TTYS_SOFTCAR))
145a1fcdedbScgd tty.ty_status |= TTY_SOFTCAR;
146a1fcdedbScgd else if (scmp(_TTYS_MDMBUF))
147a1fcdedbScgd tty.ty_status |= TTY_MDMBUF;
14861f28255Scgd else if (vcmp(_TTYS_WINDOW))
14961f28255Scgd tty.ty_window = value(p);
150531aeb7cStsarna else if (vcmp(_TTYS_CLASS))
151531aeb7cStsarna tty.ty_class = value(p);
15261f28255Scgd else
153ba984735Schristos warnx("%s: %s, %lu: unknown option `%s'",
154ba984735Schristos __func__, _PATH_TTYS, (unsigned long)lineno, p);
15561f28255Scgd }
15661f28255Scgd
15761f28255Scgd if (zapchar == '#' || *p == '#')
15861f28255Scgd while ((c = *++p) == ' ' || c == '\t')
159ba984735Schristos continue;
16061f28255Scgd tty.ty_comment = p;
161ba984735Schristos if (*p == '\0')
162ba984735Schristos tty.ty_comment = NULL;
163052e43e4Schristos if ((p = strchr(p, '\n')) != NULL)
16461f28255Scgd *p = '\0';
165ba984735Schristos return &tty;
16661f28255Scgd }
16761f28255Scgd
16861f28255Scgd #define QUOTED 1
16961f28255Scgd
17061f28255Scgd /*
17161f28255Scgd * Skip over the current field, removing quotes, and return a pointer to
17261f28255Scgd * the next field.
17361f28255Scgd */
17461f28255Scgd static char *
skip(char * p,char * zapchar)175ba984735Schristos skip(char *p, char *zapchar)
17661f28255Scgd {
1774146d586Sperry char *t;
1784146d586Sperry int c, q;
17961f28255Scgd
180b48252f3Slukem _DIAGASSERT(p != NULL);
181ba984735Schristos *zapchar = '\0';
182b48252f3Slukem
18361f28255Scgd for (q = 0, t = p; (c = *p) != '\0'; p++) {
18461f28255Scgd if (c == '"') {
18561f28255Scgd q ^= QUOTED; /* obscure, but nice */
18661f28255Scgd continue;
18761f28255Scgd }
18861f28255Scgd if (q == QUOTED && *p == '\\' && *(p+1) == '"')
18961f28255Scgd p++;
19061f28255Scgd *t++ = *p;
19161f28255Scgd if (q == QUOTED)
19261f28255Scgd continue;
19361f28255Scgd if (c == '#') {
194ba984735Schristos *zapchar = c;
195ba984735Schristos *p = '\0';
196ba984735Schristos *--t = '\0';
197ba984735Schristos return p;
19861f28255Scgd }
19961f28255Scgd if (c == '\t' || c == ' ' || c == '\n') {
200ba984735Schristos *zapchar = c;
201ba984735Schristos *p++ = '\0';
20261f28255Scgd while ((c = *p) == '\t' || c == ' ' || c == '\n')
20361f28255Scgd p++;
20461f28255Scgd *--t = '\0';
205ba984735Schristos return p;
206ba984735Schristos }
207ba984735Schristos }
208ba984735Schristos if (t != p)
209ba984735Schristos *t = '\0';
210ba984735Schristos return p;
21161f28255Scgd }
21261f28255Scgd
21361f28255Scgd static char *
value(char * p)214ba984735Schristos value(char *p)
21561f28255Scgd {
21661f28255Scgd
217b48252f3Slukem _DIAGASSERT(p != NULL);
218b48252f3Slukem
219ba984735Schristos return (p = strchr(p, '=')) != NULL ? ++p : NULL;
22061f28255Scgd }
22161f28255Scgd
22261f28255Scgd int
setttyentpath(const char * path)2232118fde3Ssalo setttyentpath(const char *path)
22461f28255Scgd {
225622e897fSchristos lineno = 0;
22661f28255Scgd if (tf) {
227915b76ddSjtc rewind(tf);
228ba984735Schristos return 1;
229138bf8b9Smatt }
230138bf8b9Smatt
231138bf8b9Smatt /*
232138bf8b9Smatt * Try <path>.$MACHINE (e.g. etc/ttys.amd64)
233138bf8b9Smatt */
234*6caac9d0Smartin {
235138bf8b9Smatt char machine[_SYS_NMLN];
236138bf8b9Smatt const int mib[] = { [0] = CTL_HW, [1] = HW_MACHINE, };
237138bf8b9Smatt size_t len = sizeof(machine);
238138bf8b9Smatt
239*6caac9d0Smartin if (sysctl(mib, (u_int)__arraycount(mib), machine, &len,
240*6caac9d0Smartin NULL, 0) != -1) {
241138bf8b9Smatt char npath[PATH_MAX];
242*6caac9d0Smartin (void)snprintf(npath, sizeof(npath), "%s.%s", path,
243*6caac9d0Smartin machine);
244138bf8b9Smatt if ((tf = fopen(npath, "re")) != NULL)
245138bf8b9Smatt return 1;
246138bf8b9Smatt }
247*6caac9d0Smartin }
248138bf8b9Smatt
249138bf8b9Smatt if ((tf = fopen(path, "re")) != NULL)
250ba984735Schristos return 1;
251ba984735Schristos return 0;
25261f28255Scgd }
25361f28255Scgd
25461f28255Scgd int
setttyent(void)2552118fde3Ssalo setttyent(void)
2562118fde3Ssalo {
2572118fde3Ssalo return setttyentpath(_PATH_TTYS);
2582118fde3Ssalo }
2592118fde3Ssalo
2602118fde3Ssalo int
endttyent(void)261ba984735Schristos endttyent(void)
26261f28255Scgd {
26361f28255Scgd int rval;
26461f28255Scgd
26561f28255Scgd if (tf) {
26661f28255Scgd rval = !(fclose(tf) == EOF);
26761f28255Scgd tf = NULL;
268ba984735Schristos return rval;
26961f28255Scgd }
270ba984735Schristos return 1;
27161f28255Scgd }
272