xref: /netbsd-src/external/bsd/libbind/dist/irs/lcl_pr.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
1*5bbd2a12Schristos /*	$NetBSD: lcl_pr.c,v 1.1.1.2 2012/09/09 16:07:54 christos Exp $	*/
2b5677b36Schristos 
3b5677b36Schristos /*
4b5677b36Schristos  * Copyright (c) 1989, 1993, 1995
5b5677b36Schristos  *	The Regents of the University of California.  All rights reserved.
6b5677b36Schristos  *
7b5677b36Schristos  * Redistribution and use in source and binary forms, with or without
8b5677b36Schristos  * modification, are permitted provided that the following conditions
9b5677b36Schristos  * are met:
10b5677b36Schristos  * 1. Redistributions of source code must retain the above copyright
11b5677b36Schristos  *    notice, this list of conditions and the following disclaimer.
12b5677b36Schristos  * 2. Redistributions in binary form must reproduce the above copyright
13b5677b36Schristos  *    notice, this list of conditions and the following disclaimer in the
14b5677b36Schristos  *    documentation and/or other materials provided with the distribution.
15b5677b36Schristos  * 3. All advertising materials mentioning features or use of this software
16b5677b36Schristos  *    must display the following acknowledgement:
17b5677b36Schristos  *	This product includes software developed by the University of
18b5677b36Schristos  *	California, Berkeley and its contributors.
19b5677b36Schristos  * 4. Neither the name of the University nor the names of its contributors
20b5677b36Schristos  *    may be used to endorse or promote products derived from this software
21b5677b36Schristos  *    without specific prior written permission.
22b5677b36Schristos  *
23b5677b36Schristos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24b5677b36Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25b5677b36Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26b5677b36Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27b5677b36Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28b5677b36Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29b5677b36Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30b5677b36Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31b5677b36Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32b5677b36Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33b5677b36Schristos  * SUCH DAMAGE.
34b5677b36Schristos  */
35b5677b36Schristos 
36b5677b36Schristos /*
37b5677b36Schristos  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
38b5677b36Schristos  * Portions Copyright (c) 1996,1999 by Internet Software Consortium.
39b5677b36Schristos  *
40b5677b36Schristos  * Permission to use, copy, modify, and distribute this software for any
41b5677b36Schristos  * purpose with or without fee is hereby granted, provided that the above
42b5677b36Schristos  * copyright notice and this permission notice appear in all copies.
43b5677b36Schristos  *
44b5677b36Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
45b5677b36Schristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
46b5677b36Schristos  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
47b5677b36Schristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
48b5677b36Schristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
49b5677b36Schristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
50b5677b36Schristos  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51b5677b36Schristos  */
52b5677b36Schristos 
53b5677b36Schristos #if defined(LIBC_SCCS) && !defined(lint)
54b5677b36Schristos static const char rcsid[] = "Id: lcl_pr.c,v 1.4 2006/03/09 23:57:56 marka Exp ";
55b5677b36Schristos #endif /* LIBC_SCCS and not lint */
56b5677b36Schristos 
57b5677b36Schristos /* extern */
58b5677b36Schristos 
59b5677b36Schristos #include "port_before.h"
60b5677b36Schristos 
61b5677b36Schristos #include <sys/types.h>
62b5677b36Schristos #include <netinet/in.h>
63b5677b36Schristos #include <arpa/nameser.h>
64b5677b36Schristos #include <resolv.h>
65b5677b36Schristos 
66b5677b36Schristos #include <errno.h>
67b5677b36Schristos #include <fcntl.h>
68b5677b36Schristos #include <string.h>
69b5677b36Schristos #include <stdio.h>
70b5677b36Schristos #include <stdlib.h>
71b5677b36Schristos 
72b5677b36Schristos #include <irs.h>
73b5677b36Schristos #include <isc/memcluster.h>
74b5677b36Schristos 
75b5677b36Schristos #include "port_after.h"
76b5677b36Schristos 
77b5677b36Schristos #include "irs_p.h"
78b5677b36Schristos #include "lcl_p.h"
79b5677b36Schristos 
80b5677b36Schristos #ifndef _PATH_PROTOCOLS
81b5677b36Schristos #define _PATH_PROTOCOLS "/etc/protocols"
82b5677b36Schristos #endif
83b5677b36Schristos #define MAXALIASES      35
84b5677b36Schristos 
85b5677b36Schristos /* Types */
86b5677b36Schristos 
87b5677b36Schristos struct pvt {
88b5677b36Schristos 	FILE *		fp;
89b5677b36Schristos 	char		line[BUFSIZ+1];
90b5677b36Schristos 	char *		dbuf;
91b5677b36Schristos 	struct protoent	proto;
92b5677b36Schristos 	char *		proto_aliases[MAXALIASES];
93b5677b36Schristos };
94b5677b36Schristos 
95b5677b36Schristos /* Forward */
96b5677b36Schristos 
97b5677b36Schristos static void			pr_close(struct irs_pr *);
98b5677b36Schristos static struct protoent *	pr_next(struct irs_pr *);
99b5677b36Schristos static struct protoent *	pr_byname(struct irs_pr *, const char *);
100b5677b36Schristos static struct protoent *	pr_bynumber(struct irs_pr *, int);
101b5677b36Schristos static void			pr_rewind(struct irs_pr *);
102b5677b36Schristos static void			pr_minimize(struct irs_pr *);
103b5677b36Schristos 
104b5677b36Schristos /* Portability. */
105b5677b36Schristos 
106b5677b36Schristos #ifndef SEEK_SET
107b5677b36Schristos # define SEEK_SET 0
108b5677b36Schristos #endif
109b5677b36Schristos 
110b5677b36Schristos /* Public */
111b5677b36Schristos 
112b5677b36Schristos struct irs_pr *
irs_lcl_pr(struct irs_acc * this)113b5677b36Schristos irs_lcl_pr(struct irs_acc *this) {
114b5677b36Schristos 	struct irs_pr *pr;
115b5677b36Schristos 	struct pvt *pvt;
116b5677b36Schristos 
117b5677b36Schristos 	if (!(pr = memget(sizeof *pr))) {
118b5677b36Schristos 		errno = ENOMEM;
119b5677b36Schristos 		return (NULL);
120b5677b36Schristos 	}
121b5677b36Schristos 	if (!(pvt = memget(sizeof *pvt))) {
122b5677b36Schristos 		memput(pr, sizeof *this);
123b5677b36Schristos 		errno = ENOMEM;
124b5677b36Schristos 		return (NULL);
125b5677b36Schristos 	}
126b5677b36Schristos 	memset(pvt, 0, sizeof *pvt);
127b5677b36Schristos 	pr->private = pvt;
128b5677b36Schristos 	pr->close = pr_close;
129b5677b36Schristos 	pr->byname = pr_byname;
130b5677b36Schristos 	pr->bynumber = pr_bynumber;
131b5677b36Schristos 	pr->next = pr_next;
132b5677b36Schristos 	pr->rewind = pr_rewind;
133b5677b36Schristos 	pr->minimize = pr_minimize;
134b5677b36Schristos 	pr->res_get = NULL;
135b5677b36Schristos 	pr->res_set = NULL;
136b5677b36Schristos 	return (pr);
137b5677b36Schristos }
138b5677b36Schristos 
139b5677b36Schristos /* Methods */
140b5677b36Schristos 
141b5677b36Schristos static void
pr_close(struct irs_pr * this)142b5677b36Schristos pr_close(struct irs_pr *this) {
143b5677b36Schristos 	struct pvt *pvt = (struct pvt *)this->private;
144b5677b36Schristos 
145b5677b36Schristos 	if (pvt->fp)
146b5677b36Schristos 		(void) fclose(pvt->fp);
147b5677b36Schristos 	if (pvt->dbuf)
148b5677b36Schristos 		free(pvt->dbuf);
149b5677b36Schristos 	memput(pvt, sizeof *pvt);
150b5677b36Schristos 	memput(this, sizeof *this);
151b5677b36Schristos }
152b5677b36Schristos 
153b5677b36Schristos static struct protoent *
pr_byname(struct irs_pr * this,const char * name)154b5677b36Schristos pr_byname(struct irs_pr *this, const char *name) {
155b5677b36Schristos 
156b5677b36Schristos 	struct protoent *p;
157b5677b36Schristos 	char **cp;
158b5677b36Schristos 
159b5677b36Schristos 	pr_rewind(this);
160b5677b36Schristos 	while ((p = pr_next(this))) {
161b5677b36Schristos 		if (!strcmp(p->p_name, name))
162b5677b36Schristos 			goto found;
163b5677b36Schristos 		for (cp = p->p_aliases; *cp; cp++)
164b5677b36Schristos 			if (!strcmp(*cp, name))
165b5677b36Schristos 				goto found;
166b5677b36Schristos 	}
167b5677b36Schristos  found:
168b5677b36Schristos 	return (p);
169b5677b36Schristos }
170b5677b36Schristos 
171b5677b36Schristos static struct protoent *
pr_bynumber(struct irs_pr * this,int proto)172b5677b36Schristos pr_bynumber(struct irs_pr *this, int proto) {
173b5677b36Schristos 	struct protoent *p;
174b5677b36Schristos 
175b5677b36Schristos 	pr_rewind(this);
176b5677b36Schristos 	while ((p = pr_next(this)))
177b5677b36Schristos 		if (p->p_proto == proto)
178b5677b36Schristos 			break;
179b5677b36Schristos 	return (p);
180b5677b36Schristos }
181b5677b36Schristos 
182b5677b36Schristos static void
pr_rewind(struct irs_pr * this)183b5677b36Schristos pr_rewind(struct irs_pr *this) {
184b5677b36Schristos 	struct pvt *pvt = (struct pvt *)this->private;
185b5677b36Schristos 
186b5677b36Schristos 	if (pvt->fp) {
187b5677b36Schristos 		if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
188b5677b36Schristos 			return;
189b5677b36Schristos 		(void)fclose(pvt->fp);
190b5677b36Schristos 	}
191b5677b36Schristos 	if (!(pvt->fp = fopen(_PATH_PROTOCOLS, "r" )))
192b5677b36Schristos 		return;
193b5677b36Schristos 	if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
194b5677b36Schristos 		(void)fclose(pvt->fp);
195b5677b36Schristos 		pvt->fp = NULL;
196b5677b36Schristos 	}
197b5677b36Schristos }
198b5677b36Schristos 
199b5677b36Schristos static struct protoent *
pr_next(struct irs_pr * this)200b5677b36Schristos pr_next(struct irs_pr *this) {
201b5677b36Schristos 	struct pvt *pvt = (struct pvt *)this->private;
202b5677b36Schristos 	char *p, *cp, **q;
203b5677b36Schristos 	char *bufp, *ndbuf, *dbuf = NULL;
204b5677b36Schristos 	int c, bufsiz, offset;
205b5677b36Schristos 
206b5677b36Schristos 	if (!pvt->fp)
207b5677b36Schristos 		pr_rewind(this);
208b5677b36Schristos 	if (!pvt->fp)
209b5677b36Schristos 		return (NULL);
210b5677b36Schristos 	if (pvt->dbuf) {
211b5677b36Schristos 		free(pvt->dbuf);
212b5677b36Schristos 		pvt->dbuf = NULL;
213b5677b36Schristos 	}
214b5677b36Schristos 	bufp = pvt->line;
215b5677b36Schristos 	bufsiz = BUFSIZ;
216b5677b36Schristos 	offset = 0;
217b5677b36Schristos  again:
218b5677b36Schristos 	if ((p = fgets(bufp + offset, bufsiz - offset, pvt->fp)) == NULL) {
219b5677b36Schristos 		if (dbuf)
220b5677b36Schristos 			free(dbuf);
221b5677b36Schristos 		return (NULL);
222b5677b36Schristos 	}
223b5677b36Schristos 	if (!strchr(p, '\n') && !feof(pvt->fp)) {
224b5677b36Schristos #define GROWBUF 1024
225b5677b36Schristos 		/* allocate space for longer line */
226b5677b36Schristos 		if (dbuf == NULL) {
227b5677b36Schristos 			if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
228b5677b36Schristos 				strcpy(ndbuf, bufp);
229b5677b36Schristos 		} else
230b5677b36Schristos 			ndbuf = realloc(dbuf, bufsiz + GROWBUF);
231b5677b36Schristos 		if (ndbuf) {
232b5677b36Schristos 			dbuf = ndbuf;
233b5677b36Schristos 			bufp = dbuf;
234b5677b36Schristos 			bufsiz += GROWBUF;
235b5677b36Schristos 			offset = strlen(dbuf);
236b5677b36Schristos 		} else {
237b5677b36Schristos 			/* allocation failed; skip this long line */
238b5677b36Schristos 			while ((c = getc(pvt->fp)) != EOF)
239b5677b36Schristos 				if (c == '\n')
240b5677b36Schristos 					break;
241b5677b36Schristos 			if (c != EOF)
242b5677b36Schristos 				ungetc(c, pvt->fp);
243b5677b36Schristos 		}
244b5677b36Schristos 		goto again;
245b5677b36Schristos 	}
246b5677b36Schristos 
247b5677b36Schristos 	p -= offset;
248b5677b36Schristos 	offset = 0;
249b5677b36Schristos 
250b5677b36Schristos 	if (*p == '#')
251b5677b36Schristos 		goto again;
252b5677b36Schristos 	cp = strpbrk(p, "#\n");
253b5677b36Schristos 	if (cp != NULL)
254b5677b36Schristos 		*cp = '\0';
255b5677b36Schristos 	pvt->proto.p_name = p;
256b5677b36Schristos 	cp = strpbrk(p, " \t");
257b5677b36Schristos 	if (cp == NULL)
258b5677b36Schristos 		goto again;
259b5677b36Schristos 	*cp++ = '\0';
260b5677b36Schristos 	while (*cp == ' ' || *cp == '\t')
261b5677b36Schristos 		cp++;
262b5677b36Schristos 	p = strpbrk(cp, " \t");
263b5677b36Schristos 	if (p != NULL)
264b5677b36Schristos 		*p++ = '\0';
265b5677b36Schristos 	pvt->proto.p_proto = atoi(cp);
266b5677b36Schristos 	q = pvt->proto.p_aliases = pvt->proto_aliases;
267b5677b36Schristos 	if (p != NULL) {
268b5677b36Schristos 		cp = p;
269b5677b36Schristos 		while (cp && *cp) {
270b5677b36Schristos 			if (*cp == ' ' || *cp == '\t') {
271b5677b36Schristos 				cp++;
272b5677b36Schristos 				continue;
273b5677b36Schristos 			}
274b5677b36Schristos 			if (q < &pvt->proto_aliases[MAXALIASES - 1])
275b5677b36Schristos 				*q++ = cp;
276b5677b36Schristos 			cp = strpbrk(cp, " \t");
277b5677b36Schristos 			if (cp != NULL)
278b5677b36Schristos 				*cp++ = '\0';
279b5677b36Schristos 		}
280b5677b36Schristos 	}
281b5677b36Schristos 	*q = NULL;
282b5677b36Schristos 	pvt->dbuf = dbuf;
283b5677b36Schristos 	return (&pvt->proto);
284b5677b36Schristos }
285b5677b36Schristos 
286b5677b36Schristos static void
pr_minimize(struct irs_pr * this)287b5677b36Schristos pr_minimize(struct irs_pr *this) {
288b5677b36Schristos 	struct pvt *pvt = (struct pvt *)this->private;
289b5677b36Schristos 
290b5677b36Schristos 	if (pvt->fp != NULL) {
291b5677b36Schristos 		(void)fclose(pvt->fp);
292b5677b36Schristos 		pvt->fp = NULL;
293b5677b36Schristos 	}
294b5677b36Schristos }
295b5677b36Schristos 
296b5677b36Schristos /*! \file */
297