diff options
Diffstat (limited to 'contrib/bind/lib/irs/nis_nw.c')
-rw-r--r-- | contrib/bind/lib/irs/nis_nw.c | 111 |
1 files changed, 92 insertions, 19 deletions
diff --git a/contrib/bind/lib/irs/nis_nw.c b/contrib/bind/lib/irs/nis_nw.c index b9e9e79..72ec391 100644 --- a/contrib/bind/lib/irs/nis_nw.c +++ b/contrib/bind/lib/irs/nis_nw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_nw.c,v 1.10 1997/12/04 04:58:00 halley Exp $"; +static const char rcsid[] = "$Id: nis_nw.c,v 1.15 1999/01/18 07:46:58 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -28,20 +28,24 @@ static int __bind_irs_nis_unneeded; #else #include <sys/types.h> +#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <sys/socket.h> +#include <arpa/nameser.h> + #include <rpc/rpc.h> #include <rpc/xdr.h> #include <rpcsvc/yp_prot.h> #include <rpcsvc/ypclnt.h> #include <errno.h> +#include <resolv.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <isc/memcluster.h> #include <irs.h> #include "port_after.h" @@ -67,6 +71,9 @@ struct pvt { char * aliases[MAXALIASES + 1]; u_char addr[MAXADDRSIZE]; + + struct __res_state * res; + void (*free_res)(void *); }; enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 }; @@ -82,9 +89,14 @@ static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int); static struct nwent * nw_next(struct irs_nw *); static void nw_rewind(struct irs_nw *); static void nw_minimize(struct irs_nw *); +static struct __res_state * nw_res_get(struct irs_nw *this); +static void nw_res_set(struct irs_nw *this, + struct __res_state *res, + void (*free_res)(void *)); static struct nwent * makenwent(struct irs_nw *this); static void nisfree(struct pvt *, enum do_what); +static int init(struct irs_nw *this); /* Public */ @@ -93,17 +105,17 @@ irs_nis_nw(struct irs_acc *this) { struct irs_nw *nw; struct pvt *pvt; - if (!(nw = (struct irs_nw *)malloc(sizeof *nw))) { + if (!(pvt = memget(sizeof *pvt))) { errno = ENOMEM; return (NULL); } - memset(nw, 0x5e, sizeof *nw); - if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) { - free(nw); + memset(pvt, 0, sizeof *pvt); + if (!(nw = memget(sizeof *nw))) { + memput(pvt, sizeof *pvt); errno = ENOMEM; return (NULL); } - memset(pvt, 0, sizeof *pvt); + memset(nw, 0x5e, sizeof *nw); pvt->needrewind = 1; pvt->nis_domain = ((struct nis_p *)this->private)->domain; nw->private = pvt; @@ -113,6 +125,8 @@ irs_nis_nw(struct irs_acc *this) { nw->next = nw_next; nw->rewind = nw_rewind; nw->minimize = nw_minimize; + nw->res_get = nw_res_get; + nw->res_set = nw_res_set; return (nw); } @@ -122,10 +136,13 @@ static void nw_close(struct irs_nw *this) { struct pvt *pvt = (struct pvt *)this->private; + nw_minimize(this); + if (pvt->res && pvt->free_res) + (*pvt->free_res)(pvt->res); if (pvt->nwbuf) free(pvt->nwbuf); - free(pvt); - free(this); + memput(pvt, sizeof *pvt); + memput(this, sizeof *this); } static struct nwent * @@ -134,15 +151,18 @@ nw_byaddr(struct irs_nw *this, void *net, int length, int af) { char tmp[sizeof "255.255.255.255/32"], *t; int r; + if (init(this) == -1) + return (NULL); + if (af != AF_INET) { - h_errno = NETDB_INTERNAL; + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); errno = EAFNOSUPPORT; return (NULL); } nisfree(pvt, do_val); /* Try it with /CIDR first. */ if (inet_net_ntop(AF_INET, net, length, tmp, sizeof tmp) == NULL) { - h_errno = NETDB_INTERNAL; + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); return (NULL); } r = yp_match(pvt->nis_domain, networks_byaddr, tmp, strlen(tmp), @@ -156,7 +176,7 @@ nw_byaddr(struct irs_nw *this, void *net, int length, int af) { &pvt->curval_data, &pvt->curval_len); } if (r != 0) { - h_errno = HOST_NOT_FOUND; + RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); return (NULL); } } @@ -168,8 +188,11 @@ nw_byname(struct irs_nw *this, const char *name, int af) { struct pvt *pvt = (struct pvt *)this->private; int r; + if (init(this) == -1) + return (NULL); + if (af != AF_INET) { - h_errno = NETDB_INTERNAL; + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); errno = EAFNOSUPPORT; return (NULL); } @@ -177,7 +200,7 @@ nw_byname(struct irs_nw *this, const char *name, int af) { r = yp_match(pvt->nis_domain, networks_byname, (char *)name, strlen(name), &pvt->curval_data, &pvt->curval_len); if (r != 0) { - h_errno = HOST_NOT_FOUND; + RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); return (NULL); } return (makenwent(this)); @@ -196,6 +219,9 @@ nw_next(struct irs_nw *this) { struct nwent *rval; int r; + if (init(this) == -1) + return (NULL); + do { if (pvt->needrewind) { nisfree(pvt, do_all); @@ -217,7 +243,7 @@ nw_next(struct irs_nw *this) { pvt->curkey_len = newkey_len; } if (r != 0) { - h_errno = HOST_NOT_FOUND; + RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); return (NULL); } rval = makenwent(this); @@ -227,15 +253,50 @@ nw_next(struct irs_nw *this) { static void nw_minimize(struct irs_nw *this) { - /* NOOP */ + struct pvt *pvt = (struct pvt *)this->private; + + if (pvt->res) + res_nclose(pvt->res); +} + +static struct __res_state * +nw_res_get(struct irs_nw *this) { + struct pvt *pvt = (struct pvt *)this->private; + + if (!pvt->res) { + struct __res_state *res; + res = (struct __res_state *)malloc(sizeof *res); + if (!res) { + errno = ENOMEM; + return (NULL); + } + memset(res, 0, sizeof *res); + nw_res_set(this, res, free); + } + + return (pvt->res); +} + +static void +nw_res_set(struct irs_nw *this, struct __res_state *res, + void (*free_res)(void *)) { + struct pvt *pvt = (struct pvt *)this->private; + + if (pvt->res && pvt->free_res) { + res_nclose(pvt->res); + (*pvt->free_res)(pvt->res); + } + + pvt->res = res; + pvt->free_res = free_res; } /* Private */ static struct nwent * makenwent(struct irs_nw *this) { - static const char spaces[] = " \t"; struct pvt *pvt = (struct pvt *)this->private; + static const char spaces[] = " \t"; char *t, *cp, **ap; if (pvt->nwbuf) @@ -243,7 +304,7 @@ makenwent(struct irs_nw *this) { pvt->nwbuf = pvt->curval_data; pvt->curval_data = NULL; - if ((cp = strchr(pvt->nwbuf, '#')) != NULL) + if ((cp = strpbrk(pvt->nwbuf, "#\n")) != NULL) *cp = '\0'; cp = pvt->nwbuf; @@ -303,4 +364,16 @@ nisfree(struct pvt *pvt, enum do_what do_what) { } } +static int +init(struct irs_nw *this) { + struct pvt *pvt = (struct pvt *)this->private; + + if (!pvt->res && !nw_res_get(this)) + return (-1); + if (((pvt->res->options & RES_INIT) == 0) && + res_ninit(pvt->res) == -1) + return (-1); + return (0); +} + #endif /*WANT_IRS_NIS*/ |