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.4 2005/04/27 04:56:31 sra 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)