Annotation of src/lib/libc/gen/getttyent.c, Revision 1.23
1.23 ! salo 1: /* $NetBSD: getttyent.c,v 1.22 2005/05/14 15:43:47 christos Exp $ */
1.8 cgd 2:
1.1 cgd 3: /*
1.8 cgd 4: * Copyright (c) 1989, 1993
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
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.
1.20 agc 15: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
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.
30: */
31:
1.10 christos 32: #include <sys/cdefs.h>
1.1 cgd 33: #if defined(LIBC_SCCS) && !defined(lint)
1.8 cgd 34: #if 0
35: static char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93";
36: #else
1.23 ! salo 37: __RCSID("$NetBSD: getttyent.c,v 1.22 2005/05/14 15:43:47 christos Exp $");
1.8 cgd 38: #endif
1.1 cgd 39: #endif /* LIBC_SCCS and not lint */
40:
1.11 jtc 41: #include "namespace.h"
1.15 lukem 42:
43: #include <assert.h>
44: #include <ctype.h>
1.1 cgd 45: #include <stdio.h>
46: #include <string.h>
1.15 lukem 47: #include <ttyent.h>
1.19 christos 48: #include <errno.h>
49: #include <err.h>
50: #include <stdlib.h>
1.11 jtc 51:
52: #ifdef __weak_alias
1.17 mycroft 53: __weak_alias(endttyent,_endttyent)
54: __weak_alias(getttyent,_getttyent)
55: __weak_alias(getttynam,_getttynam)
56: __weak_alias(setttyent,_setttyent)
1.23 ! salo 57: __weak_alias(setttyentpath,_setttyentpath)
1.11 jtc 58: #endif
1.1 cgd 59:
60: static FILE *tf;
1.19 christos 61: static size_t lineno = 0;
1.21 christos 62: static char *skip(char *, char *);
63: static char *value(char *);
1.1 cgd 64:
65: struct ttyent *
1.21 christos 66: getttynam(const char *tty)
1.1 cgd 67: {
1.13 perry 68: struct ttyent *t;
1.1 cgd 69:
1.15 lukem 70: _DIAGASSERT(tty != NULL);
71:
1.1 cgd 72: setttyent();
1.10 christos 73: while ((t = getttyent()) != NULL)
1.1 cgd 74: if (!strcmp(tty, t->ty_name))
75: break;
76: endttyent();
77: return (t);
78: }
79:
80: struct ttyent *
1.21 christos 81: getttyent(void)
1.1 cgd 82: {
83: static struct ttyent tty;
1.13 perry 84: int c;
85: char *p;
1.19 christos 86: size_t len;
87: static char *line = NULL;
1.21 christos 88: char zapchar;
1.1 cgd 89:
1.19 christos 90: if (line)
91: free(line);
1.21 christos 92:
93: if (!tf && !setttyent())
94: return NULL;
95:
1.1 cgd 96: for (;;) {
1.19 christos 97: errno = 0;
98: line = fparseln(tf, &len, &lineno, NULL, FPARSELN_UNESCALL);
99: if (line == NULL) {
100: if (errno != 0)
1.21 christos 101: warn(__func__);
1.19 christos 102: return NULL;
103: }
1.21 christos 104: for (p = line; *p && isspace((unsigned char)*p); p++)
1.1 cgd 105: continue;
106: if (*p && *p != '#')
107: break;
1.19 christos 108: free(line);
1.1 cgd 109: }
110:
111: tty.ty_name = p;
1.21 christos 112: p = skip(p, &zapchar);
113: if (*(tty.ty_getty = p) == '\0')
1.1 cgd 114: tty.ty_getty = tty.ty_type = NULL;
115: else {
1.21 christos 116: p = skip(p, &zapchar);
117: if (*(tty.ty_type = p) == '\0')
1.1 cgd 118: tty.ty_type = NULL;
119: else
1.21 christos 120: p = skip(p, &zapchar);
1.1 cgd 121: }
122: tty.ty_status = 0;
123: tty.ty_window = NULL;
1.22 christos 124: tty.ty_class = NULL;
1.1 cgd 125:
1.19 christos 126: #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && (isspace((unsigned char) p[sizeof(e) - 1]) || p[sizeof(e) - 1] == '\0')
1.1 cgd 127: #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
1.21 christos 128: for (; *p; p = skip(p, &zapchar)) {
1.1 cgd 129: if (scmp(_TTYS_OFF))
130: tty.ty_status &= ~TTY_ON;
131: else if (scmp(_TTYS_ON))
132: tty.ty_status |= TTY_ON;
133: else if (scmp(_TTYS_SECURE))
134: tty.ty_status |= TTY_SECURE;
1.7 cgd 135: else if (scmp(_TTYS_LOCAL))
1.5 cgd 136: tty.ty_status |= TTY_LOCAL;
1.7 cgd 137: else if (scmp(_TTYS_RTSCTS))
1.5 cgd 138: tty.ty_status |= TTY_RTSCTS;
1.12 scottr 139: else if (scmp(_TTYS_DTRCTS))
140: tty.ty_status |= TTY_DTRCTS;
1.7 cgd 141: else if (scmp(_TTYS_SOFTCAR))
1.5 cgd 142: tty.ty_status |= TTY_SOFTCAR;
1.7 cgd 143: else if (scmp(_TTYS_MDMBUF))
1.6 cgd 144: tty.ty_status |= TTY_MDMBUF;
1.7 cgd 145: else if (vcmp(_TTYS_WINDOW))
146: tty.ty_window = value(p);
1.14 tsarna 147: else if (vcmp(_TTYS_CLASS))
148: tty.ty_class = value(p);
1.1 cgd 149: else
1.21 christos 150: warnx("%s: %s, %lu: unknown option `%s'",
151: __func__, _PATH_TTYS, (unsigned long)lineno, p);
1.1 cgd 152: }
153:
154: if (zapchar == '#' || *p == '#')
155: while ((c = *++p) == ' ' || c == '\t')
1.21 christos 156: continue;
1.1 cgd 157: tty.ty_comment = p;
1.21 christos 158: if (*p == '\0')
159: tty.ty_comment = NULL;
1.10 christos 160: if ((p = strchr(p, '\n')) != NULL)
1.1 cgd 161: *p = '\0';
1.21 christos 162: return &tty;
1.1 cgd 163: }
164:
165: #define QUOTED 1
166:
167: /*
168: * Skip over the current field, removing quotes, and return a pointer to
169: * the next field.
170: */
171: static char *
1.21 christos 172: skip(char *p, char *zapchar)
1.1 cgd 173: {
1.13 perry 174: char *t;
175: int c, q;
1.1 cgd 176:
1.15 lukem 177: _DIAGASSERT(p != NULL);
1.21 christos 178: *zapchar = '\0';
1.15 lukem 179:
1.1 cgd 180: for (q = 0, t = p; (c = *p) != '\0'; p++) {
181: if (c == '"') {
182: q ^= QUOTED; /* obscure, but nice */
183: continue;
184: }
185: if (q == QUOTED && *p == '\\' && *(p+1) == '"')
186: p++;
187: *t++ = *p;
188: if (q == QUOTED)
189: continue;
190: if (c == '#') {
1.21 christos 191: *zapchar = c;
192: *p = '\0';
193: *--t = '\0';
194: return p;
1.1 cgd 195: }
196: if (c == '\t' || c == ' ' || c == '\n') {
1.21 christos 197: *zapchar = c;
198: *p++ = '\0';
1.1 cgd 199: while ((c = *p) == '\t' || c == ' ' || c == '\n')
200: p++;
1.21 christos 201: *--t = '\0';
202: return p;
1.1 cgd 203: }
204: }
1.21 christos 205: if (t != p)
206: *t = '\0';
207: return p;
1.1 cgd 208: }
209:
210: static char *
1.21 christos 211: value(char *p)
1.1 cgd 212: {
1.15 lukem 213:
214: _DIAGASSERT(p != NULL);
1.1 cgd 215:
1.21 christos 216: return (p = strchr(p, '=')) != NULL ? ++p : NULL;
1.1 cgd 217: }
218:
219: int
1.23 ! salo 220: setttyentpath(const char *path)
1.1 cgd 221: {
1.19 christos 222: lineno = 0;
1.1 cgd 223: if (tf) {
1.9 jtc 224: rewind(tf);
1.21 christos 225: return 1;
1.23 ! salo 226: } else if ((tf = fopen(path, "r")) != NULL)
1.21 christos 227: return 1;
228: return 0;
1.1 cgd 229: }
230:
231: int
1.23 ! salo 232: setttyent(void)
! 233: {
! 234: return setttyentpath(_PATH_TTYS);
! 235: }
! 236:
! 237: int
1.21 christos 238: endttyent(void)
1.1 cgd 239: {
240: int rval;
241:
242: if (tf) {
243: rval = !(fclose(tf) == EOF);
244: tf = NULL;
1.21 christos 245: return rval;
1.1 cgd 246: }
1.21 christos 247: return 1;
1.1 cgd 248: }
CVSweb <webmaster@jp.NetBSD.org>