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