2 * Copyright (c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
36 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
38 * Permission to use, copy, modify, and distribute this software for any
39 * purpose with or without fee is hereby granted, provided that the above
40 * copyright notice and this permission notice appear in all copies.
42 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
43 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
44 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
45 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
47 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
48 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51 #if defined(LIBC_SCCS) && !defined(lint)
52 static const char rcsid[] = "$Id: lcl_nw.c,v 1.1.206.2 2004/03/17 00:29:50 marka Exp $";
53 /* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
54 /* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
55 #endif /* LIBC_SCCS and not lint */
59 #include "port_before.h"
61 #include <sys/types.h>
62 #include <sys/socket.h>
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
66 #include <arpa/nameser.h>
76 #include <isc/memcluster.h>
78 #include "port_after.h"
91 char * aliases[MAXALIASES];
92 char addr[MAXADDRSIZE];
93 struct __res_state * res;
94 void (*free_res)(void *);
99 static void nw_close(struct irs_nw *);
100 static struct nwent * nw_byname(struct irs_nw *, const char *, int);
101 static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
102 static struct nwent * nw_next(struct irs_nw *);
103 static void nw_rewind(struct irs_nw *);
104 static void nw_minimize(struct irs_nw *);
105 static struct __res_state * nw_res_get(struct irs_nw *this);
106 static void nw_res_set(struct irs_nw *this,
107 struct __res_state *res,
108 void (*free_res)(void *));
110 static int init(struct irs_nw *this);
121 irs_lcl_nw(struct irs_acc *this) {
127 if (!(pvt = memget(sizeof *pvt))) {
131 memset(pvt, 0, sizeof *pvt);
132 if (!(nw = memget(sizeof *nw))) {
133 memput(pvt, sizeof *pvt);
137 memset(nw, 0x5e, sizeof *nw);
139 nw->close = nw_close;
140 nw->byname = nw_byname;
141 nw->byaddr = nw_byaddr;
143 nw->rewind = nw_rewind;
144 nw->minimize = nw_minimize;
145 nw->res_get = nw_res_get;
146 nw->res_set = nw_res_set;
153 nw_close(struct irs_nw *this) {
154 struct pvt *pvt = (struct pvt *)this->private;
157 if (pvt->res && pvt->free_res)
158 (*pvt->free_res)(pvt->res);
160 (void)fclose(pvt->fp);
161 memput(pvt, sizeof *pvt);
162 memput(this, sizeof *this);
165 static struct nwent *
166 nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
169 if (init(this) == -1)
173 while ((p = nw_next(this)) != NULL)
174 if (p->n_addrtype == type && p->n_length == length)
175 if (bitncmp(p->n_addr, net, length) == 0)
180 static struct nwent *
181 nw_byname(struct irs_nw *this, const char *name, int type) {
185 if (init(this) == -1)
189 while ((p = nw_next(this)) != NULL) {
190 if (ns_samename(p->n_name, name) == 1 &&
191 p->n_addrtype == type)
193 for (ap = p->n_aliases; *ap; ap++)
194 if ((ns_samename(*ap, name) == 1) &&
195 (p->n_addrtype == type))
203 nw_rewind(struct irs_nw *this) {
204 struct pvt *pvt = (struct pvt *)this->private;
207 if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
209 (void)fclose(pvt->fp);
211 if (!(pvt->fp = fopen(_PATH_NETWORKS, "r")))
213 if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
214 (void)fclose(pvt->fp);
219 static struct nwent *
220 nw_next(struct irs_nw *this) {
221 struct pvt *pvt = (struct pvt *)this->private;
222 struct nwent *ret = NULL;
224 char *bufp, *ndbuf, *dbuf = NULL;
225 int c, bufsiz, offset = 0;
227 if (init(this) == -1)
232 if (pvt->fp == NULL) {
233 RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
237 bufsiz = sizeof(pvt->line);
240 p = fgets(bufp + offset, bufsiz - offset, pvt->fp);
243 if (!strchr(p, '\n') && !feof(pvt->fp)) {
245 /* allocate space for longer line */
247 if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
250 ndbuf = realloc(dbuf, bufsiz + GROWBUF);
255 offset = strlen(dbuf);
257 /* allocation failed; skip this long line */
258 while ((c = getc(pvt->fp)) != EOF)
273 cp = strpbrk(p, "#\n");
277 cp = strpbrk(p, " \t");
281 while (*cp == ' ' || *cp == '\t')
283 p = strpbrk(cp, " \t");
286 pvt->net.n_length = inet_net_pton(AF_INET, cp, pvt->addr,
288 if (pvt->net.n_length < 0)
290 pvt->net.n_addrtype = AF_INET;
291 pvt->net.n_addr = pvt->addr;
292 q = pvt->net.n_aliases = pvt->aliases;
296 if (*cp == ' ' || *cp == '\t') {
300 if (q < &pvt->aliases[MAXALIASES - 1])
302 cp = strpbrk(cp, " \t");
318 nw_minimize(struct irs_nw *this) {
319 struct pvt *pvt = (struct pvt *)this->private;
322 res_nclose(pvt->res);
323 if (pvt->fp != NULL) {
324 (void)fclose(pvt->fp);
329 static struct __res_state *
330 nw_res_get(struct irs_nw *this) {
331 struct pvt *pvt = (struct pvt *)this->private;
334 struct __res_state *res;
335 res = (struct __res_state *)malloc(sizeof *res);
340 memset(res, 0, sizeof *res);
341 nw_res_set(this, res, free);
348 nw_res_set(struct irs_nw *this, struct __res_state *res,
349 void (*free_res)(void *)) {
350 struct pvt *pvt = (struct pvt *)this->private;
352 if (pvt->res && pvt->free_res) {
353 res_nclose(pvt->res);
354 (*pvt->free_res)(pvt->res);
358 pvt->free_res = free_res;
362 init(struct irs_nw *this) {
363 struct pvt *pvt = (struct pvt *)this->private;
365 if (!pvt->res && !nw_res_get(this))
367 if (((pvt->res->options & RES_INIT) == 0U) &&
368 res_ninit(pvt->res) == -1)