summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/irs
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-11-30 02:43:11 +0000
committerpeter <peter@FreeBSD.org>1999-11-30 02:43:11 +0000
commit4ef23ce6957fc75fc005885496d605fed48213e1 (patch)
tree7828b08c74ef918938b1b853c98f0cb41edac52c /contrib/bind/lib/irs
parent67e0f3ce71726dc4058c2f80a813341a59244dbd (diff)
downloadFreeBSD-src-4ef23ce6957fc75fc005885496d605fed48213e1.zip
FreeBSD-src-4ef23ce6957fc75fc005885496d605fed48213e1.tar.gz
Import bind v8.2.2.p5, minus the crypto for the time being. The bind
package does have BXA export approval, but the licensing strings on the dnssafe code are a bit unpleasant. The crypto is easy to restore and bind will run without it - just without full dnssec support. Obtained from: The Internet Software Consortium (www.isc.org)
Diffstat (limited to 'contrib/bind/lib/irs')
-rw-r--r--contrib/bind/lib/irs/Makefile66
-rw-r--r--contrib/bind/lib/irs/Makefile.BSD5
-rw-r--r--contrib/bind/lib/irs/README4
-rw-r--r--contrib/bind/lib/irs/dns.c63
-rw-r--r--contrib/bind/lib/irs/dns_gr.c46
-rw-r--r--contrib/bind/lib/irs/dns_ho.c167
-rw-r--r--contrib/bind/lib/irs/dns_nw.c153
-rw-r--r--contrib/bind/lib/irs/dns_p.h13
-rw-r--r--contrib/bind/lib/irs/dns_pr.c42
-rw-r--r--contrib/bind/lib/irs/dns_pw.c46
-rw-r--r--contrib/bind/lib/irs/dns_sv.c49
-rw-r--r--contrib/bind/lib/irs/gai_strerror.c45
-rw-r--r--contrib/bind/lib/irs/gen.c107
-rw-r--r--contrib/bind/lib/irs/gen_gr.c73
-rw-r--r--contrib/bind/lib/irs/gen_ho.c150
-rw-r--r--contrib/bind/lib/irs/gen_ng.c20
-rw-r--r--contrib/bind/lib/irs/gen_nw.c110
-rw-r--r--contrib/bind/lib/irs/gen_p.h9
-rw-r--r--contrib/bind/lib/irs/gen_pr.c66
-rw-r--r--contrib/bind/lib/irs/gen_pw.c66
-rw-r--r--contrib/bind/lib/irs/gen_sv.c66
-rw-r--r--contrib/bind/lib/irs/getaddrinfo.c505
-rw-r--r--contrib/bind/lib/irs/getgrent.c180
-rw-r--r--contrib/bind/lib/irs/getgrent_r.c219
-rw-r--r--contrib/bind/lib/irs/gethostent.c765
-rw-r--r--contrib/bind/lib/irs/gethostent_r.c228
-rw-r--r--contrib/bind/lib/irs/getnameinfo.c230
-rw-r--r--contrib/bind/lib/irs/getnetent.c250
-rw-r--r--contrib/bind/lib/irs/getnetent_r.c191
-rw-r--r--contrib/bind/lib/irs/getnetgrent.c110
-rw-r--r--contrib/bind/lib/irs/getnetgrent_r.c134
-rw-r--r--contrib/bind/lib/irs/getprotoent.c139
-rw-r--r--contrib/bind/lib/irs/getprotoent_r.c185
-rw-r--r--contrib/bind/lib/irs/getpwent.c160
-rw-r--r--contrib/bind/lib/irs/getpwent_r.c253
-rw-r--r--contrib/bind/lib/irs/getservent.c150
-rw-r--r--contrib/bind/lib/irs/getservent_r.c206
-rw-r--r--contrib/bind/lib/irs/hesiod.c95
-rw-r--r--contrib/bind/lib/irs/hesiod_p.h9
-rw-r--r--contrib/bind/lib/irs/irp.c583
-rw-r--r--contrib/bind/lib/irs/irp_gr.c405
-rw-r--r--contrib/bind/lib/irs/irp_ho.c418
-rw-r--r--contrib/bind/lib/irs/irp_ng.c266
-rw-r--r--contrib/bind/lib/irs/irp_nw.c375
-rw-r--r--contrib/bind/lib/irs/irp_p.h61
-rw-r--r--contrib/bind/lib/irs/irp_pr.c353
-rw-r--r--contrib/bind/lib/irs/irp_pw.c356
-rw-r--r--contrib/bind/lib/irs/irp_sv.c369
-rw-r--r--contrib/bind/lib/irs/irpmarshall.c2332
-rw-r--r--contrib/bind/lib/irs/irs_data.c171
-rw-r--r--contrib/bind/lib/irs/irs_data.h19
-rw-r--r--contrib/bind/lib/irs/irs_p.h17
-rw-r--r--contrib/bind/lib/irs/lcl.c64
-rw-r--r--contrib/bind/lib/irs/lcl_gr.c37
-rw-r--r--contrib/bind/lib/irs/lcl_ho.c158
-rw-r--r--contrib/bind/lib/irs/lcl_ng.c19
-rw-r--r--contrib/bind/lib/irs/lcl_nw.c148
-rw-r--r--contrib/bind/lib/irs/lcl_p.h7
-rw-r--r--contrib/bind/lib/irs/lcl_pr.c70
-rw-r--r--contrib/bind/lib/irs/lcl_pw.c38
-rw-r--r--contrib/bind/lib/irs/lcl_sv.c344
-rw-r--r--contrib/bind/lib/irs/nis.c61
-rw-r--r--contrib/bind/lib/irs/nis_gr.c25
-rw-r--r--contrib/bind/lib/irs/nis_ho.c112
-rw-r--r--contrib/bind/lib/irs/nis_ng.c30
-rw-r--r--contrib/bind/lib/irs/nis_nw.c111
-rw-r--r--contrib/bind/lib/irs/nis_p.h8
-rw-r--r--contrib/bind/lib/irs/nis_pr.c21
-rw-r--r--contrib/bind/lib/irs/nis_pw.c43
-rw-r--r--contrib/bind/lib/irs/nis_sv.c22
-rw-r--r--contrib/bind/lib/irs/nul_ng.c11
-rw-r--r--contrib/bind/lib/irs/pathnames.h10
-rw-r--r--contrib/bind/lib/irs/util.c6
73 files changed, 11471 insertions, 974 deletions
diff --git a/contrib/bind/lib/irs/Makefile b/contrib/bind/lib/irs/Makefile
index 55130d0..3421b8b 100644
--- a/contrib/bind/lib/irs/Makefile
+++ b/contrib/bind/lib/irs/Makefile
@@ -1,4 +1,4 @@
-# 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
@@ -13,7 +13,7 @@
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
-# $Id: Makefile,v 8.6 1997/05/21 19:23:18 halley Exp $
+# $Id: Makefile,v 8.16 1999/02/22 02:47:58 vixie Exp $
# these are only appropriate for BSD 4.4 or derivatives, and are used in
# development. normal builds will be done in the top level directory and
@@ -26,29 +26,48 @@ A=a
CC= cc
LD= ld
SHELL= /bin/sh
-CDEBUG= -g
+CDEBUG= -g
TOP= ../..
INCL = ${TOP}/include
PORTINCL = ${TOP}/port/${SYSTYPE}/include
LIBBIND = ${TOP}/lib/libbind.${A}
+LIBBINDR = ../${TOP}/lib/libbind_r.${A}
CFLAGS= ${CDEBUG} -I${PORTINCL} -I${INCL}
+# -D__BIND_NOSTATIC -Wimplicit
LD_LIBFLAGS= -x -r
-AR= ar cruv
+AR= ar cru
RANLIB= ranlib
INSTALL= install
+INSTALL_EXEC=
+INSTALL_LIB=-o bin -g bin
+THREADED= threaded
-SRCS= dns.c dns_gr.c dns_ho.c dns_nw.c dns_pr.c dns_pw.c dns_sv.c gen.c \
- gen_gr.c gen_ho.c gen_ng.c gen_nw.c gen_pr.c gen_pw.c gen_sv.c \
- getgrent.c gethostent.c getnetent.c getnetgrent.c getprotoent.c \
- getpwent.c getservent.c hesiod.c irs_data.c lcl.c lcl_gr.c lcl_ho.c \
- lcl_ng.c lcl_nw.c lcl_pr.c lcl_pw.c lcl_sv.c nis.c nis_gr.c nis_ho.c \
- nis_ng.c nis_nw.c nis_pr.c nis_pw.c nis_sv.c nul_ng.c util.c
+SRCS= dns.c dns_gr.c dns_ho.c dns_nw.c dns_pr.c dns_pw.c \
+ dns_sv.c gai_strerror.c gen.c gen_gr.c gen_ho.c \
+ gen_ng.c gen_nw.c gen_pr.c gen_pw.c gen_sv.c \
+ getaddrinfo.c getgrent.c getgrent_r.c gethostent.c \
+ gethostent_r.c getnameinfo.c getnetent.c getnetent_r.c \
+ getnetgrent.c getnetgrent_r.c getprotoent.c \
+ getprotoent_r.c getpwent.c getpwent_r.c getservent.c \
+ getservent_r.c hesiod.c irs_data.c \
+ irp.c irp_gr.c irp_ho.c irp_ng.c irp_nw.c \
+ irp_pr.c irp_pw.c irp_sv.c irpmarshall.c \
+ lcl.c lcl_gr.c \
+ lcl_ho.c lcl_ng.c lcl_nw.c lcl_pr.c lcl_pw.c \
+ lcl_sv.c nis.c nis_gr.c nis_ho.c nis_ng.c nis_nw.c \
+ nis_pr.c nis_pw.c nis_sv.c nul_ng.c util.c
OBJS= dns.${O} dns_gr.${O} dns_ho.${O} dns_nw.${O} dns_pr.${O} dns_pw.${O} \
- dns_sv.${O} gen.${O} gen_gr.${O} gen_ho.${O} gen_ng.${O} gen_nw.${O} \
- gen_pr.${O} gen_pw.${O} gen_sv.${O} getgrent.${O} gethostent.${O} \
- getnetent.${O} getnetgrent.${O} getprotoent.${O} getpwent.${O} \
- getservent.${O} hesiod.${O} irs_data.${O} lcl.${O} lcl_gr.${O} \
+ dns_sv.${O} gai_strerror.${O} gen.${O} gen_gr.${O} gen_ho.${O} \
+ gen_ng.${O} gen_nw.${O} gen_pr.${O} gen_pw.${O} gen_sv.${O} \
+ getaddrinfo.${O} getgrent.${O} getgrent_r.${O} gethostent.${O} \
+ gethostent_r.${O} getnameinfo.${O} getnetent.${O} getnetent_r.${O} \
+ getnetgrent.${O} getnetgrent_r.${O} getprotoent.${O} \
+ getprotoent_r.${O} getpwent.${O} getpwent_r.${O} getservent.${O} \
+ getservent_r.${O} hesiod.${O} irs_data.${O} \
+ irp.${O} irp_gr.${O} irp_ho.${O} irp_ng.${O} irp_nw.${O} \
+ irp_pr.${O} irp_pw.${O} irp_sv.${O} irpmarshall.${O} \
+ lcl.${O} lcl_gr.${O} \
lcl_ho.${O} lcl_ng.${O} lcl_nw.${O} lcl_pr.${O} lcl_pw.${O} \
lcl_sv.${O} nis.${O} nis_gr.${O} nis_ho.${O} nis_ng.${O} nis_nw.${O} \
nis_pr.${O} nis_pw.${O} nis_sv.${O} nul_ng.${O} util.${O}
@@ -56,18 +75,29 @@ OBJS= dns.${O} dns_gr.${O} dns_ho.${O} dns_nw.${O} dns_pr.${O} dns_pw.${O} \
all: ${LIBBIND}
${LIBBIND}: ${OBJS}
+ -( cd ${THREADED} ; \
+ ${AR} ${LIBBINDR} ${ARPREF} ${OBJS} ${ARSUFF} ; \
+ ${RANLIB} ${LIBBINDR} )
${AR} ${LIBBIND} ${ARPREF} ${OBJS} ${ARSUFF}
${RANLIB} ${LIBBIND}
.c.${O}:
- ${CC} ${CPPFLAGS} ${CFLAGS} -c $*.c
- -${LDS} ${LD} ${LD_LIBFLAGS} $*.${O} && ${LDS} mv a.out $*.${O}
+ if test ! -d ${THREADED} ; then mkdir ${THREADED} ; fi
+ -(${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \
+ -o ${THREADED}/$*.${O} ; \
+ ${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} && \
+ ${LDS} mv a.out ${THREADED}/$*.${O})
+ ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c
+ -${LDS} ${LD} ${LD_LIBFLAGS} $*.${O} -o a.out && \
+ ${LDS} mv a.out $*.${O}
distclean: clean
clean: FRC
rm -f .depend a.out core ${LIB} tags
rm -f *.${O} *.BAK *.CKP *~
+ rm -f ${THREADED}/*.${O}
+ -rmdir ${THREADED}
depend: FRC
mkdep -I${INCL} -I${PORTINCL} ${CPPFLAGS} ${SRCS}
@@ -75,6 +105,10 @@ depend: FRC
links: FRC
@set -e; ln -s SRC/*.[ch] .
+testirpd: testirpd.o ${LIBBIND}
+ ${CC} ${CDEBUG} ${LDFLAGS} -o testirpd testirpd.o ${LIBBIND} ${SYSLIBS}
+
+
install:
FRC:
diff --git a/contrib/bind/lib/irs/Makefile.BSD b/contrib/bind/lib/irs/Makefile.BSD
index 197e739..d30c417 100644
--- a/contrib/bind/lib/irs/Makefile.BSD
+++ b/contrib/bind/lib/irs/Makefile.BSD
@@ -1,4 +1,4 @@
-# BSDI $Id: Makefile.BSD,v 1.4 1996/10/25 07:22:55 vixie Exp $
+# BSDI $Id: Makefile.BSD,v 1.5 1999/01/18 07:46:47 vixie Exp $
#
# @(#)Makefile 5.12 (Berkeley) 7/15/92
@@ -15,7 +15,8 @@ SRCS= lcl.c lcl_gr.c lcl_pw.c lcl_sv.c lcl_pr.c lcl_ho.c lcl_nw.c lcl_ng.c \
gen.c gen_gr.c gen_pw.c gen_sv.c gen_pr.c gen_ho.c gen_nw.c gen_ng.c \
getgrent.c getpwent.c getservent.c getprotoent.c gethostent.c \
getnetent.c getnetgrent.c \
- nul_ng.c irs_data.c \
+ nul_ng.c irs_data.c irp.c irp_gr.c irp_ho.c irp_ng.c irp_nw.c \
+ irp_pr.c irp_pw.c irp_sv.c irpd.c irpmarshall.c \
hesiod.c util.c bitncmp.c
NOMAN=
diff --git a/contrib/bind/lib/irs/README b/contrib/bind/lib/irs/README
index d6b8792..cb81a9a 100644
--- a/contrib/bind/lib/irs/README
+++ b/contrib/bind/lib/irs/README
@@ -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
@@ -18,7 +18,7 @@
This is the Information Retrieval Service (IRS).
Designed by Paul Vixie (ISC) and Ted T'so (MIT), 1995.
Written by Paul Vixie, Ted T'so and Sam Stoller, 1996.
-$Id: README,v 1.4 1996/10/25 07:22:56 vixie Exp $
+$Id: README,v 1.5 1999/01/08 19:23:52 vixie Exp $
Introduction:
diff --git a/contrib/bind/lib/irs/dns.c b/contrib/bind/lib/irs/dns.c
index e7aa125..7ba7eec 100644
--- a/contrib/bind/lib/irs/dns.c
+++ b/contrib/bind/lib/irs/dns.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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: dns.c,v 1.11 1998/03/21 00:59:45 halley Exp $";
+static const char rcsid[] = "$Id: dns.c,v 1.14 1999/01/18 07:46:47 vixie Exp $";
#endif
/*
@@ -29,6 +29,14 @@ static const char rcsid[] = "$Id: dns.c,v 1.11 1998/03/21 00:59:45 halley Exp $"
#include <string.h>
#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <resolv.h>
+
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -40,6 +48,9 @@ static const char rcsid[] = "$Id: dns.c,v 1.11 1998/03/21 00:59:45 halley Exp $"
/* forward */
static void dns_close(struct irs_acc *);
+static struct __res_state * dns_res_get(struct irs_acc *);
+static void dns_res_set(struct irs_acc *, struct __res_state *,
+ void (*)(void *));
/* public */
@@ -48,17 +59,19 @@ irs_dns_acc(const char *options) {
struct irs_acc *acc;
struct dns_p *dns;
- if (!(acc = malloc(sizeof *acc))) {
+ if (!(acc = memget(sizeof *acc))) {
errno = ENOMEM;
return (NULL);
}
memset(acc, 0x5e, sizeof *acc);
- if (!(dns = malloc(sizeof *dns))) {
+ if (!(dns = memget(sizeof *dns))) {
errno = ENOMEM;
- free(acc);
+ memput(acc, sizeof *acc);
return (NULL);
}
memset(dns, 0x5e, sizeof *dns);
+ dns->res = NULL;
+ dns->free_res = NULL;
if (hesiod_init(&dns->hes_ctx) < 0) {
/*
* We allow the dns accessor class to initialize
@@ -83,20 +96,56 @@ irs_dns_acc(const char *options) {
acc->ho_map = irs_dns_ho;
acc->nw_map = irs_dns_nw;
acc->ng_map = irs_nul_ng;
+ acc->res_get = dns_res_get;
+ acc->res_set = dns_res_set;
acc->close = dns_close;
return (acc);
}
/* methods */
+static struct __res_state *
+dns_res_get(struct irs_acc *this) {
+ struct dns_p *dns = (struct dns_p *)this->private;
+
+ if (dns->res == NULL) {
+ struct __res_state *res;
+ res = (struct __res_state *)malloc(sizeof *res);
+ if (res == NULL)
+ return (NULL);
+ memset(dns->res, 0, sizeof *dns->res);
+ dns_res_set(this, res, free);
+ }
+
+ if ((dns->res->options | RES_INIT) == 0 &&
+ res_ninit(dns->res) < 0)
+ return (NULL);
+
+ return (dns->res);
+}
+
+static void
+dns_res_set(struct irs_acc *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct dns_p *dns = (struct dns_p *)this->private;
+
+ if (dns->res && dns->free_res) {
+ res_nclose(dns->res);
+ (*dns->free_res)(dns->res);
+ }
+ dns->res = res;
+ dns->free_res = free_res;
+}
static void
dns_close(struct irs_acc *this) {
struct dns_p *dns;
dns = (struct dns_p *)this->private;
+ if (dns->res && dns->free_res)
+ (*dns->free_res)(dns->res);
if (dns->hes_ctx)
hesiod_end(dns->hes_ctx);
- free(dns);
- free(this);
+ memput(dns, sizeof *dns);
+ memput(this, sizeof *this);
}
diff --git a/contrib/bind/lib/irs/dns_gr.c b/contrib/bind/lib/irs/dns_gr.c
index 9c91719..64cbe9b 100644
--- a/contrib/bind/lib/irs/dns_gr.c
+++ b/contrib/bind/lib/irs/dns_gr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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: dns_gr.c,v 1.15 1998/03/21 00:59:46 halley Exp $";
+static const char rcsid[] = "$Id: dns_gr.c,v 1.19 1999/01/18 07:46:48 vixie Exp $";
#endif
/*
@@ -39,6 +39,13 @@ static int __bind_irs_gr_unneeded;
#include <errno.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
+
#include <irs.h>
#include "port_after.h"
@@ -53,7 +60,7 @@ struct pvt {
/*
* This is our private accessor data. It has a shared hesiod context.
*/
- struct dns_p *dns;
+ struct dns_p * dns;
/*
* Need space to store the entries read from the group file.
* The members list also needs space per member, and the
@@ -77,6 +84,10 @@ static void gr_close(struct irs_gr *);
static int gr_list(struct irs_gr *, const char *,
gid_t, gid_t *, int *);
static void gr_minimize(struct irs_gr *);
+static struct __res_state * gr_res_get(struct irs_gr *);
+static void gr_res_set(struct irs_gr *,
+ struct __res_state *,
+ void (*)(void *));
static struct group * get_hes_group(struct irs_gr *this,
const char *name,
@@ -94,14 +105,14 @@ irs_dns_gr(struct irs_acc *this) {
errno = ENODEV;
return (NULL);
}
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
pvt->dns = dns;
- if (!(gr = (struct irs_gr *)malloc(sizeof *gr))) {
- free(pvt);
+ if (!(gr = memget(sizeof *gr))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -114,6 +125,8 @@ irs_dns_gr(struct irs_acc *this) {
gr->close = gr_close;
gr->list = gr_list;
gr->minimize = gr_minimize;
+ gr->res_get = gr_res_get;
+ gr->res_set = gr_res_set;
return (gr);
}
@@ -127,8 +140,8 @@ gr_close(struct irs_gr *this) {
free(pvt->group.gr_mem);
if (pvt->membuf)
free(pvt->membuf);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct group *
@@ -247,4 +260,21 @@ get_hes_group(struct irs_gr *this, const char *name, const char *type) {
return (NULL);
}
+static struct __res_state *
+gr_res_get(struct irs_gr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ return (__hesiod_res_get(dns->hes_ctx));
+}
+
+static void
+gr_res_set(struct irs_gr *this, struct __res_state * res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ __hesiod_res_set(dns->hes_ctx, res, free_res);
+}
+
#endif /* WANT_IRS_GR */
diff --git a/contrib/bind/lib/irs/dns_ho.c b/contrib/bind/lib/irs/dns_ho.c
index 3a8c402..e319f96 100644
--- a/contrib/bind/lib/irs/dns_ho.c
+++ b/contrib/bind/lib/irs/dns_ho.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996,1997 by Internet Software Consortium.
+ * Portions 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
@@ -52,7 +52,7 @@
/* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$Id: dns_ho.c,v 1.18 1998/01/26 23:08:22 halley Exp $";
+static const char rcsid[] = "$Id: dns_ho.c,v 1.26 1999/10/15 19:49:09 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -75,6 +75,7 @@ static char rcsid[] = "$Id: dns_ho.c,v 1.18 1998/01/26 23:08:22 halley Exp $";
#include <stdio.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -88,8 +89,6 @@ static char rcsid[] = "$Id: dns_ho.c,v 1.18 1998/01/26 23:08:22 halley Exp $";
# define SPRINTF(x) sprintf x
#endif
-extern int h_errno;
-
/* Definitions. */
#define MAXALIASES 35
@@ -113,6 +112,8 @@ struct pvt {
char * host_aliases[MAXALIASES];
char hostbuf[8*1024];
u_char host_addr[16]; /* IPv4 or IPv6 */
+ struct __res_state *res;
+ void (*free_res)(void *);
};
typedef union {
@@ -122,6 +123,8 @@ typedef union {
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
+/* Note: the IPv6 loopback address is in the "tunnel" space */
+static const u_char v6local[] = { 0,0, 0,1 }; /* last 4 bytes of IPv6 addr */
/* Forwards. */
@@ -134,14 +137,19 @@ static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
static struct hostent * ho_next(struct irs_ho *this);
static void ho_rewind(struct irs_ho *this);
static void ho_minimize(struct irs_ho *this);
+static struct __res_state * ho_res_get(struct irs_ho *this);
+static void ho_res_set(struct irs_ho *this,
+ struct __res_state *res,
+ void (*free_res)(void *));
static void map_v4v6_hostent(struct hostent *hp, char **bp,
int *len);
-static void addrsort(char **, int);
+static void addrsort(res_state, char **, int);
static struct hostent * gethostans(struct irs_ho *this,
const u_char *ansbuf, int anslen,
const char *qname, int qtype,
int af, int size);
+static int init(struct irs_ho *this);
/* Exports. */
@@ -150,13 +158,14 @@ irs_dns_ho(struct irs_acc *this) {
struct irs_ho *ho;
struct pvt *pvt;
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
- if (!(ho = (struct irs_ho *)malloc(sizeof *ho))) {
- free(pvt);
+
+ if (!(ho = memget(sizeof *ho))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -169,6 +178,8 @@ irs_dns_ho(struct irs_acc *this) {
ho->next = ho_next;
ho->rewind = ho_rewind;
ho->minimize = ho_minimize;
+ ho->res_get = ho_res_get;
+ ho->res_set = ho_res_set;
return (ho);
}
@@ -178,18 +189,23 @@ static void
ho_close(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ ho_minimize(this);
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
if (pvt)
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct hostent *
ho_byname(struct irs_ho *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
struct hostent *hp;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (init(this) == -1)
return (NULL);
- if (_res.options & RES_USE_INET6) {
+
+ if (pvt->res->options & RES_USE_INET6) {
hp = ho_byname2(this, name, AF_INET6);
if (hp)
return (hp);
@@ -200,11 +216,12 @@ ho_byname(struct irs_ho *this, const char *name) {
static struct hostent *
ho_byname2(struct irs_ho *this, const char *name, int af) {
struct pvt *pvt = (struct pvt *)this->private;
- int n, size, type, len;
+ int n, size, type;
u_char buf[MAXPACKET];
+ char tmp[NS_MAXDNAME];
const char *cp;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (init(this) == -1)
return (NULL);
switch (af) {
@@ -217,20 +234,22 @@ ho_byname2(struct irs_ho *this, const char *name, int af) {
type = T_AAAA;
break;
default:
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = EAFNOSUPPORT;
return (NULL);
}
/*
* if there aren't any dots, it could be a user-level alias.
- * this is also done in res_query() since we are not the only
+ * this is also done in res_nquery() since we are not the only
* function that looks up host names.
*/
- if (!strchr(name, '.') && (cp = hostalias(name)))
+ if (!strchr(name, '.') && (cp = res_hostalias(pvt->res, name,
+ tmp, sizeof tmp)))
name = cp;
- if ((n = res_search(name, C_IN, type, buf, sizeof buf)) < 0)
+ if ((n = res_nsearch(pvt->res, name, C_IN, type,
+ buf, sizeof buf)) < 0)
return (NULL);
return (gethostans(this, buf, n, name, type, af, size));
}
@@ -244,11 +263,13 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
struct hostent *hp;
int n, size;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (init(this) == -1)
return (NULL);
+
if (af == AF_INET6 && len == IN6ADDRSZ &&
(!memcmp(uaddr, mapped, sizeof mapped) ||
- !memcmp(uaddr, tunnelled, sizeof tunnelled))) {
+ (!memcmp(uaddr, tunnelled, sizeof tunnelled) &&
+ memcmp(&uaddr[sizeof tunnelled], v6local, sizeof(v6local))))) {
/* Unmap. */
addr = (char *)addr + sizeof mapped;
uaddr += sizeof mapped;
@@ -264,12 +285,12 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
break;
default:
errno = EAFNOSUPPORT;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
if (size > len) {
errno = EINVAL;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
switch (af) {
@@ -292,21 +313,21 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
default:
abort();
}
- n = res_query(qbuf, C_IN, T_PTR, buf, sizeof buf);
+ n = res_nquery(pvt->res, qbuf, C_IN, T_PTR, buf, sizeof buf);
if (n < 0)
return (NULL);
hp = gethostans(this, buf, n, qbuf, T_PTR, af, size);
if (!hp)
- return (NULL); /* h_errno was set by gethostans() */
+ return (NULL); /* H_ERRNO was set by gethostans() */
memcpy(pvt->host_addr, addr, len);
pvt->h_addr_ptrs[0] = (char *)pvt->host_addr;
pvt->h_addr_ptrs[1] = NULL;
- if (af == AF_INET && (_res.options & RES_USE_INET6)) {
+ if (af == AF_INET && (pvt->res->options & RES_USE_INET6)) {
map_v4v6_address((char*)pvt->host_addr, (char*)pvt->host_addr);
pvt->host.h_addrtype = AF_INET6;
pvt->host.h_length = IN6ADDRSZ;
}
- h_errno = NETDB_SUCCESS;
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
return (hp);
}
@@ -322,7 +343,42 @@ ho_rewind(struct irs_ho *this) {
static void
ho_minimize(struct irs_ho *this) {
- /* NOOP */
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (pvt->res)
+ res_nclose(pvt->res);
+}
+
+static struct __res_state *
+ho_res_get(struct irs_ho *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);
+ ho_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+ho_res_set(struct irs_ho *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. */
@@ -364,7 +420,7 @@ gethostans(struct irs_ho *this,
* Find first satisfactory answer.
*/
if (ansbuf + HFIXEDSZ > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
hp = (HEADER *)ansbuf;
@@ -374,27 +430,27 @@ gethostans(struct irs_ho *this,
buflen = sizeof pvt->hostbuf;
cp = ansbuf + HFIXEDSZ;
if (qdcount != 1) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
n = dn_expand(ansbuf, eom, cp, bp, buflen);
- if ((n < 0) || !(*name_ok)(bp)) {
- h_errno = NO_RECOVERY;
+ if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) {
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
cp += n + QFIXEDSZ;
if (cp > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
if (qtype == T_A || qtype == T_AAAA) {
- /* res_send() has already verified that the query name is the
+ /* res_nsend() has already verified that the query name is the
* same as the one we sent; this just gets the expanded name
* (i.e., with the succeeding search-domain tacked on).
*/
n = strlen(bp) + 1; /* for the \0 */
if (n > MAXHOSTNAMELEN) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
pvt->host.h_name = bp;
@@ -413,7 +469,7 @@ gethostans(struct irs_ho *this,
had_error = 0;
while (ancount-- > 0 && cp < eom && !had_error) {
n = dn_expand(ansbuf, eom, cp, bp, buflen);
- if ((n < 0) || !(*name_ok)(bp)) {
+ if (n < 0 || !maybe_ok(pvt->res, bp, name_ok)) {
had_error++;
continue;
}
@@ -434,7 +490,7 @@ gethostans(struct irs_ho *this,
if (ap >= &pvt->host_aliases[MAXALIASES-1])
continue;
n = dn_expand(ansbuf, eom, cp, tbuf, sizeof tbuf);
- if ((n < 0) || !(*name_ok)(tbuf)) {
+ if (n < 0 || !maybe_ok(pvt->res, tbuf, name_ok)) {
had_error++;
continue;
}
@@ -458,7 +514,7 @@ gethostans(struct irs_ho *this,
}
if (qtype == T_PTR && type == T_CNAME) {
n = dn_expand(ansbuf, eom, cp, tbuf, sizeof tbuf);
- if (n < 0 || !res_dnok(tbuf)) {
+ if (n < 0 || !maybe_dnok(pvt->res, tbuf)) {
had_error++;
continue;
}
@@ -481,12 +537,13 @@ gethostans(struct irs_ho *this,
}
switch (type) {
case T_PTR:
- if (strcasecmp(tname, bp) != 0) {
+ if (ns_samename(tname, bp) != 1) {
cp += n;
continue;
}
n = dn_expand(ansbuf, eom, cp, bp, buflen);
- if (n < 0 || !res_hnok(bp) || n >= MAXHOSTNAMELEN) {
+ if (n < 0 || !maybe_hnok(pvt->res, bp) ||
+ n >= MAXHOSTNAMELEN) {
had_error++;
break;
}
@@ -505,7 +562,7 @@ gethostans(struct irs_ho *this,
break;
case T_A:
case T_AAAA:
- if (strcasecmp(pvt->host.h_name, bp) != 0) {
+ if (ns_samename(pvt->host.h_name, bp) != 1) {
cp += n;
continue;
}
@@ -551,8 +608,8 @@ gethostans(struct irs_ho *this,
*ap = NULL;
*hap = NULL;
- if (_res.nsort && haveanswer > 1 && qtype == T_A)
- addrsort(pvt->h_addr_ptrs, haveanswer);
+ if (pvt->res->nsort && haveanswer > 1 && qtype == T_A)
+ addrsort(pvt->res, pvt->h_addr_ptrs, haveanswer);
if (!pvt->host.h_name) {
n = strlen(qname) + 1; /* for the \0 */
if (n > buflen || n >= MAXHOSTNAMELEN)
@@ -562,13 +619,13 @@ gethostans(struct irs_ho *this,
bp += n;
buflen -= n;
}
- if (_res.options & RES_USE_INET6)
+ if (pvt->res->options & RES_USE_INET6)
map_v4v6_hostent(&pvt->host, &bp, &buflen);
- h_errno = NETDB_SUCCESS;
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
return (&pvt->host);
}
no_recovery:
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
@@ -598,16 +655,16 @@ map_v4v6_hostent(struct hostent *hp, char **bpp, int *lenp) {
}
static void
-addrsort(char **ap, int num) {
+addrsort(res_state statp, char **ap, int num) {
int i, j, needsort = 0, aval[MAXADDRS];
char **p;
p = ap;
for (i = 0; i < num; i++, p++) {
- for (j = 0 ; (unsigned)j < _res.nsort; j++)
- if (_res.sort_list[j].addr.s_addr ==
+ for (j = 0 ; (unsigned)j < statp->nsort; j++)
+ if (statp->sort_list[j].addr.s_addr ==
(((struct in_addr *)(*p))->s_addr &
- _res.sort_list[j].mask))
+ statp->sort_list[j].mask))
break;
aval[i] = j;
if (needsort == 0 && i > 0 && j < aval[i-1])
@@ -635,3 +692,15 @@ addrsort(char **ap, int num) {
needsort++;
}
}
+
+static int
+init(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res && !ho_res_get(this))
+ return (-1);
+ if (((pvt->res->options & RES_INIT) == 0) &&
+ res_ninit(pvt->res) == -1)
+ return (-1);
+ return (0);
+}
diff --git a/contrib/bind/lib/irs/dns_nw.c b/contrib/bind/lib/irs/dns_nw.c
index 30767e7..66ef664 100644
--- a/contrib/bind/lib/irs/dns_nw.c
+++ b/contrib/bind/lib/irs/dns_nw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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: dns_nw.c,v 1.13 1998/02/13 01:10:40 halley Exp $";
+static const char rcsid[] = "$Id: dns_nw.c,v 1.19 1999/10/15 19:49:10 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -38,6 +38,7 @@ static const char rcsid[] = "$Id: dns_nw.c,v 1.13 1998/02/13 01:10:40 halley Exp
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -51,8 +52,6 @@ static const char rcsid[] = "$Id: dns_nw.c,v 1.13 1998/02/13 01:10:40 halley Exp
# define SPRINTF(x) sprintf x
#endif
-extern int h_errno;
-
/* Definitions. */
#define MAXALIASES 35
@@ -67,6 +66,8 @@ struct pvt {
struct nwent net;
char * ali[MAXALIASES];
char buf[BUFSIZ+1];
+ struct __res_state * res;
+ void (*free_res)(void *);
};
typedef union {
@@ -84,6 +85,10 @@ 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 * get1101byaddr(struct irs_nw *, u_char *, int);
static struct nwent * get1101byname(struct irs_nw *, const char *);
@@ -92,9 +97,10 @@ static struct nwent * get1101answer(struct irs_nw *,
enum by_what by_what,
int af, const char *name,
const u_char *addr, int addrlen);
-static struct nwent * get1101mask(struct nwent *);
+static struct nwent * get1101mask(struct irs_nw *this, struct nwent *);
static int make1101inaddr(const u_char *, int, char *, int);
static void normalize_name(char *name);
+static int init(struct irs_nw *this);
/* Exports. */
@@ -103,13 +109,13 @@ irs_dns_nw(struct irs_acc *this) {
struct irs_nw *nw;
struct pvt *pvt;
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
- if (!(nw = (struct irs_nw *)malloc(sizeof *nw))) {
- free(pvt);
+ if (!(nw = memget(sizeof *nw))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -121,6 +127,8 @@ irs_dns_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);
}
@@ -130,32 +138,47 @@ static void
nw_close(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ nw_minimize(this);
+
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct nwent *
nw_byname(struct irs_nw *this, const char *name, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (init(this) == -1)
+ return (NULL);
+
switch (af) {
case AF_INET:
return (get1101byname(this, name));
default:
(void)NULL;
}
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = EAFNOSUPPORT;
return (NULL);
}
static struct nwent *
nw_byaddr(struct irs_nw *this, void *net, int len, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (init(this) == -1)
+ return (NULL);
+
switch (af) {
case AF_INET:
return (get1101byaddr(this, net, len));
default:
(void)NULL;
}
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = EAFNOSUPPORT;
return (NULL);
}
@@ -172,43 +195,80 @@ nw_rewind(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 *
get1101byname(struct irs_nw *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
u_char ansbuf[MAXPACKET];
int anslen;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
- return (NULL);
- anslen = res_search(name, C_IN, T_PTR, ansbuf, sizeof ansbuf);
+ anslen = res_nsearch(pvt->res, name, C_IN, T_PTR,
+ ansbuf, sizeof ansbuf);
if (anslen < 0)
return (NULL);
- return (get1101mask(get1101answer(this, ansbuf, anslen, by_name,
- AF_INET, name, NULL, 0)));
+ return (get1101mask(this, get1101answer(this, ansbuf, anslen, by_name,
+ AF_INET, name, NULL, 0)));
}
static struct nwent *
get1101byaddr(struct irs_nw *this, u_char *net, int len) {
- u_char ansbuf[MAXPACKET];
+ struct pvt *pvt = (struct pvt *)this->private;
char qbuf[sizeof "255.255.255.255.in-addr.arpa"];
+ u_char ansbuf[MAXPACKET];
int anslen;
if (len < 1 || len > 32) {
errno = EINVAL;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
if (make1101inaddr(net, len, qbuf, sizeof qbuf) < 0)
return (NULL);
- anslen = res_query(qbuf, C_IN, T_PTR, ansbuf, sizeof ansbuf);
+ anslen = res_nquery(pvt->res, qbuf, C_IN, T_PTR,
+ ansbuf, sizeof ansbuf);
if (anslen < 0)
return (NULL);
- return (get1101mask(get1101answer(this, ansbuf, anslen, by_addr,
- AF_INET, NULL, net, len)));
+ return (get1101mask(this, get1101answer(this, ansbuf, anslen, by_addr,
+ AF_INET, NULL, net, len)));
}
static struct nwent *
@@ -225,7 +285,7 @@ get1101answer(struct irs_nw *this,
/* Initialize, and parse header. */
eom = ansbuf + anslen;
if (ansbuf + HFIXEDSZ > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
hp = (HEADER *)ansbuf;
@@ -235,16 +295,16 @@ get1101answer(struct irs_nw *this,
int n = dn_skipname(cp, eom);
cp += n + QFIXEDSZ;
if (n < 0 || cp > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
}
ancount = ntohs(hp->ancount);
if (!ancount) {
if (hp->aa)
- h_errno = HOST_NOT_FOUND;
+ RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
else
- h_errno = TRY_AGAIN;
+ RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
return (NULL);
}
@@ -264,7 +324,7 @@ get1101answer(struct irs_nw *this,
int n = strlen(name) + 1;
if (n > buflen) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
pvt->net.n_name = strcpy(bp, name);
@@ -277,7 +337,7 @@ get1101answer(struct irs_nw *this,
int n = addrlen / 8 + ((addrlen % 8) != 0);
if (INADDRSZ > buflen) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
memset(bp, 0, INADDRSZ);
@@ -298,9 +358,9 @@ get1101answer(struct irs_nw *this,
int n = dn_expand(ansbuf, eom, cp, bp, buflen);
cp += n; /* Owner */
- if (n < 0 || !res_dnok(bp) ||
+ if (n < 0 || !maybe_dnok(pvt->res, bp) ||
cp + 3 * INT16SZ + INT32SZ > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
GETSHORT(type, cp); /* Type */
@@ -311,8 +371,8 @@ get1101answer(struct irs_nw *this,
int nn;
nn = dn_expand(ansbuf, eom, cp, bp, buflen);
- if (nn < 0 || !res_hnok(bp) || nn != n) {
- h_errno = NO_RECOVERY;
+ if (nn < 0 || !maybe_hnok(pvt->res, bp) || nn != n) {
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
normalize_name(bp);
@@ -320,7 +380,7 @@ get1101answer(struct irs_nw *this,
case by_addr: {
if (pvt->net.n_name == NULL)
pvt->net.n_name = bp;
- else if (strcasecmp(pvt->net.n_name, bp) == 0)
+ else if (ns_samename(pvt->net.n_name, bp) == 1)
break;
else
*ap++ = bp;
@@ -338,7 +398,7 @@ get1101answer(struct irs_nw *this,
&b1, &b2, &b3, &b4) != 4)
break;
if (buflen < INADDRSZ) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
pvt->net.n_addr = bp;
@@ -355,7 +415,7 @@ get1101answer(struct irs_nw *this,
cp += n; /* RDATA */
}
if (!haveanswer) {
- h_errno = TRY_AGAIN;
+ RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
return (NULL);
}
*ap = NULL;
@@ -364,7 +424,8 @@ get1101answer(struct irs_nw *this,
}
static struct nwent *
-get1101mask(struct nwent *nwent) {
+get1101mask(struct irs_nw *this, struct nwent *nwent) {
+ struct pvt *pvt = (struct pvt *)this->private;
char qbuf[sizeof "255.255.255.255.in-addr.arpa"], owner[MAXDNAME];
int anslen, type, class, ancount, qdcount;
u_char ansbuf[MAXPACKET], *cp, *eom;
@@ -379,7 +440,7 @@ get1101mask(struct nwent *nwent) {
}
/* Query for the A RR that would hold this network's mask. */
- anslen = res_query(qbuf, C_IN, T_A, ansbuf, sizeof ansbuf);
+ anslen = res_nquery(pvt->res, qbuf, C_IN, T_A, ansbuf, sizeof ansbuf);
if (anslen < HFIXEDSZ)
return (nwent);
@@ -400,7 +461,7 @@ get1101mask(struct nwent *nwent) {
while (--ancount >= 0 && cp < eom) {
int n = dn_expand(ansbuf, eom, cp, owner, sizeof owner);
- if (n < 0 || !res_dnok(owner))
+ if (n < 0 || !maybe_dnok(pvt->res, owner))
break;
cp += n; /* Owner */
if (cp + 3 * INT16SZ + INT32SZ > eom)
@@ -412,7 +473,7 @@ get1101mask(struct nwent *nwent) {
if (cp + n > eom)
break;
if (n == INADDRSZ && class == C_IN && type == T_A &&
- !strcasecmp(qbuf, owner)) {
+ ns_samename(qbuf, owner) == 1) {
/* This A RR indicates the actual netmask. */
int nn, mm;
@@ -485,3 +546,15 @@ normalize_name(char *name) {
while (t > name && t[-1] == '.')
*--t = '\0';
}
+
+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);
+}
diff --git a/contrib/bind/lib/irs/dns_p.h b/contrib/bind/lib/irs/dns_p.h
index 5a4ef84..6b5fe11 100644
--- a/contrib/bind/lib/irs/dns_p.h
+++ b/contrib/bind/lib/irs/dns_p.h
@@ -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,17 +16,24 @@
*/
/*
- * $Id: dns_p.h,v 1.7 1996/10/25 07:22:59 vixie Exp $
+ * $Id: dns_p.h,v 1.11 1999/06/03 20:50:36 vixie Exp $
*/
#ifndef _DNS_P_H_INCLUDED
#define _DNS_P_H_INCLUDED
+#define maybe_ok(res, nm, ok) (((res)->options & RES_NOCHECKNAME) != 0 || \
+ (ok)(nm) != 0)
+#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
+#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
+
/*
* Object state.
*/
struct dns_p {
- void *hes_ctx;
+ void *hes_ctx;
+ struct __res_state *res;
+ void (*free_res) __P((void *));
};
/*
diff --git a/contrib/bind/lib/irs/dns_pr.c b/contrib/bind/lib/irs/dns_pr.c
index 2ca6aaf..77c6a93 100644
--- a/contrib/bind/lib/irs/dns_pr.c
+++ b/contrib/bind/lib/irs/dns_pr.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: dns_pr.c,v 1.9 1997/12/04 04:57:48 halley Exp $";
+static const char rcsid[] = "$Id: dns_pr.c,v 1.14 1999/09/04 22:06:14 vixie Exp $";
#endif
/* Imports */
@@ -25,6 +25,8 @@ static const char rcsid[] = "$Id: dns_pr.c,v 1.9 1997/12/04 04:57:48 halley Exp
#include <sys/types.h>
#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <stdio.h>
#include <string.h>
@@ -33,6 +35,7 @@ static const char rcsid[] = "$Id: dns_pr.c,v 1.9 1997/12/04 04:57:48 halley Exp
#include <stdlib.h>
#include <errno.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -44,7 +47,7 @@ static const char rcsid[] = "$Id: dns_pr.c,v 1.9 1997/12/04 04:57:48 halley Exp
/* Types. */
struct pvt {
- struct dns_p * dns;
+ struct dns_p * dns;
struct protoent proto;
char * prbuf;
};
@@ -57,6 +60,10 @@ static struct protoent * pr_bynumber(struct irs_pr *, int);
static struct protoent * pr_next(struct irs_pr *);
static void pr_rewind(struct irs_pr *);
static void pr_minimize(struct irs_pr *);
+static struct __res_state * pr_res_get(struct irs_pr *);
+static void pr_res_set(struct irs_pr *,
+ struct __res_state *,
+ void (*)(void *));
static struct protoent * parse_hes_list(struct irs_pr *, char **);
@@ -72,13 +79,13 @@ irs_dns_pr(struct irs_acc *this) {
errno = ENODEV;
return (NULL);
}
- if (!(pvt = malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
- if (!(pr = malloc(sizeof *pr))) {
- free(pvt);
+ if (!(pr = memget(sizeof *pr))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -91,6 +98,8 @@ irs_dns_pr(struct irs_acc *this) {
pr->rewind = pr_rewind;
pr->close = pr_close;
pr->minimize = pr_minimize;
+ pr->res_get = pr_res_get;
+ pr->res_set = pr_res_set;
return (pr);
}
@@ -104,7 +113,9 @@ pr_close(struct irs_pr *this) {
free(pvt->proto.p_aliases);
if (pvt->prbuf)
free(pvt->prbuf);
- free(this);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct protoent *
@@ -155,6 +166,23 @@ pr_minimize(struct irs_pr *this) {
/* NOOP */
}
+static struct __res_state *
+pr_res_get(struct irs_pr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ return (__hesiod_res_get(dns->hes_ctx));
+}
+
+static void
+pr_res_set(struct irs_pr *this, struct __res_state * res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ __hesiod_res_set(dns->hes_ctx, res, free_res);
+}
+
/* Private. */
static struct protoent *
diff --git a/contrib/bind/lib/irs/dns_pw.c b/contrib/bind/lib/irs/dns_pw.c
index 97612d1..5344c6e 100644
--- a/contrib/bind/lib/irs/dns_pw.c
+++ b/contrib/bind/lib/irs/dns_pw.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: dns_pw.c,v 1.13 1997/12/04 04:57:48 halley Exp $";
+static const char rcsid[] = "$Id: dns_pw.c,v 1.18 1999/09/04 22:06:14 vixie Exp $";
#endif
#include "port_before.h"
@@ -30,6 +30,13 @@ static int __bind_irs_pw_unneeded;
#include <errno.h>
#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
+
#include <irs.h>
#include "port_after.h"
@@ -41,7 +48,7 @@ static int __bind_irs_pw_unneeded;
/* Types. */
struct pvt {
- struct dns_p *dns;
+ struct dns_p * dns;
struct passwd passwd;
char * pwbuf;
};
@@ -54,6 +61,10 @@ static struct passwd * pw_byuid(struct irs_pw *, uid_t);
static struct passwd * pw_next(struct irs_pw *);
static void pw_rewind(struct irs_pw *);
static void pw_minimize(struct irs_pw *);
+static struct __res_state * pw_res_get(struct irs_pw *);
+static void pw_res_set(struct irs_pw *,
+ struct __res_state *,
+ void (*)(void *));
static struct passwd * getpwcommon(struct irs_pw *, const char *,
const char *);
@@ -70,14 +81,14 @@ irs_dns_pw(struct irs_acc *this) {
errno = ENODEV;
return (NULL);
}
- if (!(pvt = malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
pvt->dns = dns;
- if (!(pw = malloc(sizeof *pw))) {
- free(pvt);
+ if (!(pw = memget(sizeof *pw))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -89,6 +100,8 @@ irs_dns_pw(struct irs_acc *this) {
pw->next = pw_next;
pw->rewind = pw_rewind;
pw->minimize = pw_minimize;
+ pw->res_get = pw_res_get;
+ pw->res_set = pw_res_set;
return (pw);
}
@@ -100,7 +113,9 @@ pw_close(struct irs_pw *this) {
if (pvt->pwbuf)
free(pvt->pwbuf);
- free(this);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct passwd *
@@ -132,6 +147,23 @@ pw_minimize(struct irs_pw *this) {
/* NOOP */
}
+static struct __res_state *
+pw_res_get(struct irs_pw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ return (__hesiod_res_get(dns->hes_ctx));
+}
+
+static void
+pw_res_set(struct irs_pw *this, struct __res_state * res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ __hesiod_res_set(dns->hes_ctx, res, free_res);
+}
+
/* Private. */
static struct passwd *
diff --git a/contrib/bind/lib/irs/dns_sv.c b/contrib/bind/lib/irs/dns_sv.c
index 064e80a..ea0ba70 100644
--- a/contrib/bind/lib/irs/dns_sv.c
+++ b/contrib/bind/lib/irs/dns_sv.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: dns_sv.c,v 1.12 1997/12/04 04:57:49 halley Exp $";
+static const char rcsid[] = "$Id: dns_sv.c,v 1.17 1999/09/04 22:06:14 vixie Exp $";
#endif
/* Imports */
@@ -33,6 +33,12 @@ static const char rcsid[] = "$Id: dns_sv.c,v 1.12 1997/12/04 04:57:49 halley Exp
#include <stdlib.h>
#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -44,9 +50,11 @@ static const char rcsid[] = "$Id: dns_sv.c,v 1.12 1997/12/04 04:57:49 halley Exp
/* Definitions */
struct pvt {
- struct dns_p * dns;
+ struct dns_p * dns;
struct servent serv;
char * svbuf;
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward. */
@@ -58,6 +66,10 @@ static struct servent * sv_byport(struct irs_sv *, int, const char *);
static struct servent * sv_next(struct irs_sv *);
static void sv_rewind(struct irs_sv *);
static void sv_minimize(struct irs_sv *);
+static struct __res_state * sv_res_get(struct irs_sv *);
+static void sv_res_set(struct irs_sv *,
+ struct __res_state *,
+ void (*)(void *));
static struct servent * parse_hes_list(struct irs_sv *,
char **, const char *);
@@ -74,14 +86,14 @@ irs_dns_sv(struct irs_acc *this) {
errno = ENODEV;
return (NULL);
}
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
pvt->dns = dns;
- if (!(sv = malloc(sizeof *sv))) {
- free(pvt);
+ if (!(sv = memget(sizeof *sv))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -93,6 +105,8 @@ irs_dns_sv(struct irs_acc *this) {
sv->rewind = sv_rewind;
sv->close = sv_close;
sv->minimize = sv_minimize;
+ sv->res_get = sv_res_get;
+ sv->res_set = sv_res_set;
return (sv);
}
@@ -106,7 +120,11 @@ sv_close(struct irs_sv *this) {
free(pvt->serv.s_aliases);
if (pvt->svbuf)
free(pvt->svbuf);
- free(this);
+
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct servent *
@@ -248,3 +266,20 @@ static void
sv_minimize(struct irs_sv *this) {
/* NOOP */
}
+
+static struct __res_state *
+sv_res_get(struct irs_sv *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ return (__hesiod_res_get(dns->hes_ctx));
+}
+
+static void
+sv_res_set(struct irs_sv *this, struct __res_state * res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct dns_p *dns = pvt->dns;
+
+ __hesiod_res_set(dns->hes_ctx, res, free_res);
+}
diff --git a/contrib/bind/lib/irs/gai_strerror.c b/contrib/bind/lib/irs/gai_strerror.c
new file mode 100644
index 0000000..f56c6f5
--- /dev/null
+++ b/contrib/bind/lib/irs/gai_strerror.c
@@ -0,0 +1,45 @@
+/*
+%%% copyright-cmetz-97
+This software is Copyright 1997-1998 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+*/
+
+#include <port_before.h>
+#include <netdb.h>
+#include <errno.h>
+#include <port_after.h>
+
+char *
+gai_strerror(int errnum) {
+ switch(errnum) {
+ case 0:
+ return "no error";
+ case EAI_BADFLAGS:
+ return "invalid value for ai_flags";
+ case EAI_NONAME:
+ return "name or service is not known";
+ case EAI_AGAIN:
+ return "temporary failure in name resolution";
+ case EAI_FAIL:
+ return "non-recoverable failure in name resolution";
+ case EAI_NODATA:
+ return "no address associated with name";
+ case EAI_FAMILY:
+ return "ai_family not supported";
+ case EAI_SOCKTYPE:
+ return "ai_socktype not supported";
+ case EAI_SERVICE:
+ return "service not supported for ai_socktype";
+ case EAI_ADDRFAMILY:
+ return "address family for name not supported";
+ case EAI_MEMORY:
+ return "memory allocation failure";
+ case EAI_SYSTEM:
+ return "system error";
+ default:
+ return "unknown error";
+ };
+}
diff --git a/contrib/bind/lib/irs/gen.c b/contrib/bind/lib/irs/gen.c
index 325a526..fe41088 100644
--- a/contrib/bind/lib/irs/gen.c
+++ b/contrib/bind/lib/irs/gen.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gen.c,v 1.18 1998/03/21 00:59:46 halley Exp $";
+static const char rcsid[] = "$Id: gen.c,v 1.25 1999/10/13 16:39:29 vixie Exp $";
#endif
/*
@@ -35,13 +35,19 @@ static char rcsid[] = "$Id: gen.c,v 1.18 1998/03/21 00:59:46 halley Exp $";
#include "port_before.h"
-#include <assert.h>
+#include <isc/assertions.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -60,6 +66,7 @@ static const struct nameval acc_names[irs_nacc+1] = {
{ "local", irs_lcl },
{ "dns", irs_dns },
{ "nis", irs_nis },
+ { "irp", irs_irp },
{ NULL, irs_nacc }
};
@@ -73,6 +80,7 @@ static const accinit accs[irs_nacc+1] = {
#else
NULL,
#endif
+ irs_irp_acc,
NULL
};
@@ -96,8 +104,11 @@ static const struct nameval option_names[] = {
/* Forward */
static void gen_close(struct irs_acc *);
+static struct __res_state * gen_res_get(struct irs_acc *);
+static void gen_res_set(struct irs_acc *, struct __res_state *,
+ void (*)(void *));
static int find_name(const char *, const struct nameval nv[]);
-static void init_map_rules(struct gen_p *);
+static void init_map_rules(struct gen_p *, const char *conf_file);
static struct irs_rule *release_rule(struct irs_rule *);
static int add_rule(struct gen_p *,
enum irs_map_id, enum irs_acc_id,
@@ -106,25 +117,27 @@ static int add_rule(struct gen_p *,
/* Public */
struct irs_acc *
-irs_gen_acc(const char *options) {
+irs_gen_acc(const char *options, const char *conf_file) {
struct irs_acc *acc;
struct gen_p *irs;
- if (!(acc = malloc(sizeof *acc))) {
+ if (!(acc = memget(sizeof *acc))) {
errno = ENOMEM;
return (NULL);
}
memset(acc, 0x5e, sizeof *acc);
- if (!(irs = malloc(sizeof *irs))) {
+ if (!(irs = memget(sizeof *irs))) {
errno = ENOMEM;
- free(acc);
+ memput(acc, sizeof *acc);
return (NULL);
}
memset(irs, 0x5e, sizeof *irs);
irs->options = strdup(options);
+ irs->res = NULL;
+ irs->free_res = NULL;
memset(irs->accessors, 0, sizeof irs->accessors);
memset(irs->map_rules, 0, sizeof irs->map_rules);
- init_map_rules(irs);
+ init_map_rules(irs, conf_file);
acc->private = irs;
#ifdef WANT_IRS_GR
acc->gr_map = irs_gen_gr;
@@ -141,12 +154,65 @@ irs_gen_acc(const char *options) {
acc->ho_map = irs_gen_ho;
acc->nw_map = irs_gen_nw;
acc->ng_map = irs_gen_ng;
+ acc->res_get = gen_res_get;
+ acc->res_set = gen_res_set;
acc->close = gen_close;
return (acc);
}
/* Methods */
+static struct __res_state *
+gen_res_get(struct irs_acc *this) {
+ struct gen_p *irs = (struct gen_p *)this->private;
+
+ if (irs->res == NULL) {
+ struct __res_state *res;
+ res = (struct __res_state *)malloc(sizeof *res);
+ if (res == NULL)
+ return (NULL);
+ memset(res, 0, sizeof *res);
+ gen_res_set(this, res, free);
+ }
+
+ if (((irs->res->options & RES_INIT) == 0) && res_ninit(irs->res) < 0)
+ return (NULL);
+
+ return (irs->res);
+}
+
+static void
+gen_res_set(struct irs_acc *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct gen_p *irs = (struct gen_p *)this->private;
+#if 0
+ struct irs_rule *rule;
+ struct irs_ho *ho;
+ struct irs_nw *nw;
+#endif
+
+ if (irs->res && irs->free_res) {
+ res_nclose(irs->res);
+ (*irs->free_res)(irs->res);
+ }
+
+ irs->res = res;
+ irs->free_res = free_res;
+
+#if 0
+ for (rule = irs->map_rules[irs_ho]; rule; rule = rule->next) {
+ ho = rule->inst->ho;
+
+ (*ho->res_set)(ho, res, NULL);
+ }
+ for (rule = irs->map_rules[irs_nw]; rule; rule = rule->next) {
+ nw = rule->inst->nw;
+
+ (*nw->res_set)(nw, res, NULL);
+ }
+#endif
+}
+
static void
gen_close(struct irs_acc *this) {
struct gen_p *irs = (struct gen_p *)this->private;
@@ -182,11 +248,14 @@ gen_close(struct irs_acc *this) {
/* The options string was strdup'd. */
free((void*)irs->options);
+ if (irs->res && irs->free_res)
+ (*irs->free_res)(irs->res);
+
/* The private data container. */
- free(irs);
+ memput(irs, sizeof *irs);
/* The object. */
- free(this);
+ memput(this, sizeof *this);
}
/* Private */
@@ -205,7 +274,7 @@ static struct irs_rule *
release_rule(struct irs_rule *rule) {
struct irs_rule *next = rule->next;
- free(rule);
+ memput(rule, sizeof *rule);
return (next);
}
@@ -231,7 +300,7 @@ add_rule(struct gen_p *irs,
if (acc == irs_nis)
return (-1);
#endif
- new = (struct irs_rule *)malloc(sizeof *new);
+ new = memget(sizeof *new);
if (new == NULL)
return (-1);
memset(new, 0x5e, sizeof *new);
@@ -310,11 +379,15 @@ default_map_rules(struct gen_p *irs) {
}
static void
-init_map_rules(struct gen_p *irs) {
+init_map_rules(struct gen_p *irs, const char *conf_file) {
char line[1024], pattern[40], mapname[20], accname[20], options[100];
FILE *conf;
- if ((conf = fopen(_PATH_IRS_CONF, "r")) == NULL) {
+ if (conf_file == NULL)
+ conf_file = _PATH_IRS_CONF ;
+
+ /* A conf file of "" means compiled in defaults. Irpd wants this */
+ if (conf_file[0] == '\0' || (conf = fopen(conf_file, "r")) == NULL) {
default_map_rules(irs);
return;
}
@@ -337,13 +410,13 @@ init_map_rules(struct gen_p *irs) {
options[0] = '\0';
n = find_name(mapname, map_names);
- assert(n < irs_nmap);
+ INSIST(n < irs_nmap);
if (n < 0)
continue;
map = (enum irs_map_id) n;
n = find_name(accname, acc_names);
- assert(n < irs_nacc);
+ INSIST(n < irs_nacc);
if (n < 0)
continue;
acc = (enum irs_acc_id) n;
diff --git a/contrib/bind/lib/irs/gen_gr.c b/contrib/bind/lib/irs/gen_gr.c
index b0c61a8..ae23d2c 100644
--- a/contrib/bind/lib/irs/gen_gr.c
+++ b/contrib/bind/lib/irs/gen_gr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gen_gr.c,v 1.16 1998/03/21 00:59:47 halley Exp $";
+static const char rcsid[] = "$Id: gen_gr.c,v 1.21 1999/10/13 16:39:29 vixie Exp $";
#endif
/* Imports */
@@ -29,12 +29,17 @@ static int __bind_irs_gr_unneeded;
#include <sys/types.h>
-#include <assert.h>
+#include <isc/assertions.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -59,6 +64,8 @@ struct pvt {
size_t nmemb; /* Malloc'd max index of gr_mem[]. */
char * membuf;
size_t membufsize;
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward */
@@ -71,6 +78,10 @@ static void gr_rewind(struct irs_gr *);
static int gr_list(struct irs_gr *, const char *,
gid_t, gid_t *, int *);
static void gr_minimize(struct irs_gr *);
+static struct __res_state * gr_res_get(struct irs_gr *);
+static void gr_res_set(struct irs_gr *,
+ struct __res_state *,
+ void (*)(void *));
static void grmerge(struct irs_gr *gr, const struct group *src,
int preserve);
@@ -89,13 +100,13 @@ irs_gen_gr(struct irs_acc *this) {
struct irs_gr *gr;
struct pvt *pvt;
- if (!(gr = malloc(sizeof *gr))) {
+ if (!(gr = memget(sizeof *gr))) {
errno = ENOMEM;
return (NULL);
}
memset(gr, 0x5e, sizeof *gr);
- if (!(pvt = malloc(sizeof *pvt))) {
- free(gr);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(gr, sizeof *gr);
errno = ENOMEM;
return (NULL);
}
@@ -110,6 +121,8 @@ irs_gen_gr(struct irs_acc *this) {
gr->rewind = gr_rewind;
gr->list = gr_list;
gr->minimize = gr_minimize;
+ gr->res_get = gr_res_get;
+ gr->res_set = gr_res_set;
return (gr);
}
@@ -119,8 +132,8 @@ static void
gr_close(struct irs_gr *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct group *
@@ -266,6 +279,46 @@ gr_minimize(struct irs_gr *this) {
}
}
+static struct __res_state *
+gr_res_get(struct irs_gr *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);
+ gr_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+gr_res_set(struct irs_gr *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct irs_rule *rule;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
+
+ for (rule = pvt->rules; rule != NULL; rule = rule->next) {
+ struct irs_gr *gr = rule->inst->gr;
+
+ if (gr->res_set)
+ (*gr->res_set)(gr, pvt->res, NULL);
+ }
+}
+
/* Private. */
static void
@@ -310,7 +363,7 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) {
* Enlarge destination membuf; cp points at new portion.
*/
n = sizenew(pvt->group.gr_mem, src->gr_mem);
- assert((nnew == 0) == (n == 0));
+ INSIST((nnew == 0) == (n == 0));
if (!preserve) {
n += strlen(src->gr_name) + 1;
n += strlen(src->gr_passwd) + 1;
@@ -346,7 +399,7 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) {
strcpy(cp, src->gr_passwd);
cp += strlen(src->gr_passwd) + 1;
}
- assert(cp >= pvt->membuf && cp <= &pvt->membuf[pvt->membufsize]);
+ INSIST(cp >= pvt->membuf && cp <= &pvt->membuf[pvt->membufsize]);
}
static int
diff --git a/contrib/bind/lib/irs/gen_ho.c b/contrib/bind/lib/irs/gen_ho.c
index 7da829d..9e7a429 100644
--- a/contrib/bind/lib/irs/gen_ho.c
+++ b/contrib/bind/lib/irs/gen_ho.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,19 +16,26 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$Id: gen_ho.c,v 1.9 1997/12/04 04:57:50 halley Exp $";
+static const char rcsid[] = "$Id: gen_ho.c,v 1.15 1999/10/13 16:39:29 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
#include "port_before.h"
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
#include <errno.h>
#include <stdlib.h>
#include <netdb.h>
+#include <resolv.h>
#include <stdio.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -36,14 +43,14 @@ static char rcsid[] = "$Id: gen_ho.c,v 1.9 1997/12/04 04:57:50 halley Exp $";
#include "irs_p.h"
#include "gen_p.h"
-extern int h_errno;
-
/* Definitions */
struct pvt {
struct irs_rule * rules;
struct irs_rule * rule;
struct irs_ho * ho;
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forwards */
@@ -57,6 +64,12 @@ static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
static struct hostent * ho_next(struct irs_ho *this);
static void ho_rewind(struct irs_ho *this);
static void ho_minimize(struct irs_ho *this);
+static struct __res_state * ho_res_get(struct irs_ho *this);
+static void ho_res_set(struct irs_ho *this,
+ struct __res_state *res,
+ void (*free_res)(void *));
+
+static int init(struct irs_ho *this);
/* Exports */
@@ -66,17 +79,17 @@ irs_gen_ho(struct irs_acc *this) {
struct irs_ho *ho;
struct pvt *pvt;
- if (!(ho = malloc(sizeof *ho))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
- memset(ho, 0x5e, sizeof *ho);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(ho);
+ memset(pvt, 0, sizeof *pvt);
+ if (!(ho = memget(sizeof *ho))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
- memset(pvt, 0, sizeof *pvt);
+ memset(ho, 0x5e, sizeof *ho);
pvt->rules = accpvt->map_rules[irs_ho];
pvt->rule = pvt->rules;
ho->private = pvt;
@@ -87,6 +100,8 @@ irs_gen_ho(struct irs_acc *this) {
ho->next = ho_next;
ho->rewind = ho_rewind;
ho->minimize = ho_minimize;
+ ho->res_get = ho_res_get;
+ ho->res_set = ho_res_set;
return (ho);
}
@@ -96,8 +111,11 @@ static void
ho_close(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ ho_minimize(this);
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct hostent *
@@ -106,14 +124,25 @@ ho_byname(struct irs_ho *this, const char *name) {
struct irs_rule *rule;
struct hostent *rval;
struct irs_ho *ho;
+ int therrno = NETDB_INTERNAL;
+ int softerror = 0;
+
+ if (init(this) == -1)
+ return (NULL);
for (rule = pvt->rules; rule; rule = rule->next) {
ho = rule->inst->ho;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = 0;
rval = (*ho->byname)(ho, name);
if (rval != NULL)
return (rval);
+ if (softerror == 0 &&
+ pvt->res->res_h_errno != HOST_NOT_FOUND &&
+ pvt->res->res_h_errno != NETDB_INTERNAL) {
+ softerror = 1;
+ therrno = pvt->res->res_h_errno;
+ }
if (rule->flags & IRS_CONTINUE)
continue;
/*
@@ -121,12 +150,14 @@ ho_byname(struct irs_ho *this, const char *name) {
* is not available, or just that this particular name
* cannot be resolved now. We use the errno ECONNREFUSED
* to distinguish. If a lookup sets that errno when
- * h_errno is TRY_AGAIN, we continue to try other lookup
+ * H_ERRNO is TRY_AGAIN, we continue to try other lookup
* functions, otherwise we return the TRY_AGAIN error.
*/
- if (h_errno != TRY_AGAIN || errno != ECONNREFUSED)
+ if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
break;
}
+ if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
+ RES_SET_H_ERRNO(pvt->res, therrno);
return (NULL);
}
@@ -136,23 +167,36 @@ ho_byname2(struct irs_ho *this, const char *name, int af) {
struct irs_rule *rule;
struct hostent *rval;
struct irs_ho *ho;
+ int therrno = NETDB_INTERNAL;
+ int softerror = 0;
+
+ if (init(this) == -1)
+ return (NULL);
for (rule = pvt->rules; rule; rule = rule->next) {
ho = rule->inst->ho;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = 0;
rval = (*ho->byname2)(ho, name, af);
if (rval != NULL)
return (rval);
+ if (softerror == 0 &&
+ pvt->res->res_h_errno != HOST_NOT_FOUND &&
+ pvt->res->res_h_errno != NETDB_INTERNAL) {
+ softerror = 1;
+ therrno = pvt->res->res_h_errno;
+ }
if (rule->flags & IRS_CONTINUE)
continue;
/*
* See the comments in ho_byname() explaining
* the interpretation of TRY_AGAIN and ECONNREFUSED.
*/
- if (h_errno != TRY_AGAIN || errno != ECONNREFUSED)
+ if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
break;
}
+ if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
+ RES_SET_H_ERRNO(pvt->res, therrno);
return (NULL);
}
@@ -162,23 +206,38 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
struct irs_rule *rule;
struct hostent *rval;
struct irs_ho *ho;
+ int therrno = NETDB_INTERNAL;
+ int softerror = 0;
+
+
+ if (init(this) == -1)
+ return (NULL);
for (rule = pvt->rules; rule; rule = rule->next) {
ho = rule->inst->ho;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = 0;
rval = (*ho->byaddr)(ho, addr, len, af);
if (rval != NULL)
return (rval);
+ if (softerror == 0 &&
+ pvt->res->res_h_errno != HOST_NOT_FOUND &&
+ pvt->res->res_h_errno != NETDB_INTERNAL) {
+ softerror = 1;
+ therrno = pvt->res->res_h_errno;
+ }
+
if (rule->flags & IRS_CONTINUE)
continue;
/*
* See the comments in ho_byname() explaining
* the interpretation of TRY_AGAIN and ECONNREFUSED.
*/
- if (h_errno != TRY_AGAIN || errno != ECONNREFUSED)
+ if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
break;
}
+ if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
+ RES_SET_H_ERRNO(pvt->res, therrno);
return (NULL);
}
@@ -221,9 +280,64 @@ ho_minimize(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
struct irs_rule *rule;
+ if (pvt->res)
+ res_nclose(pvt->res);
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
struct irs_ho *ho = rule->inst->ho;
(*ho->minimize)(ho);
}
}
+
+static struct __res_state *
+ho_res_get(struct irs_ho *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);
+ ho_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+ho_res_set(struct irs_ho *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct irs_rule *rule;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
+
+ for (rule = pvt->rules; rule != NULL; rule = rule->next) {
+ struct irs_ho *ho = rule->inst->ho;
+
+ (*ho->res_set)(ho, pvt->res, NULL);
+ }
+}
+
+static int
+init(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res && !ho_res_get(this))
+ return (-1);
+
+ if (((pvt->res->options & RES_INIT) == 0) &&
+ (res_ninit(pvt->res) == -1))
+ return (-1);
+
+ return (0);
+}
diff --git a/contrib/bind/lib/irs/gen_ng.c b/contrib/bind/lib/irs/gen_ng.c
index 3958380..064d616 100644
--- a/contrib/bind/lib/irs/gen_ng.c
+++ b/contrib/bind/lib/irs/gen_ng.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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gen_ng.c,v 1.9 1997/12/04 04:57:50 halley Exp $";
+static const char rcsid[] = "$Id: gen_ng.c,v 1.14 1999/10/13 16:39:29 vixie Exp $";
#endif
/* Imports */
@@ -25,10 +25,15 @@ static char rcsid[] = "$Id: gen_ng.c,v 1.9 1997/12/04 04:57:50 halley Exp $";
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -62,13 +67,13 @@ irs_gen_ng(struct irs_acc *this) {
struct irs_ng *ng;
struct pvt *pvt;
- if (!(ng = malloc(sizeof *ng))) {
+ if (!(ng = memget(sizeof *ng))) {
errno = ENOMEM;
return (NULL);
}
memset(ng, 0x5e, sizeof *ng);
- if (!(pvt = malloc(sizeof *pvt))) {
- free(ng);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(ng, sizeof *ng);
errno = ENOMEM;
return (NULL);
}
@@ -90,10 +95,11 @@ static void
ng_close(struct irs_ng *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ ng_minimize(this);
if (pvt->curgroup)
free(pvt->curgroup);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static int
diff --git a/contrib/bind/lib/irs/gen_nw.c b/contrib/bind/lib/irs/gen_nw.c
index 8ae8074..fad436c 100644
--- a/contrib/bind/lib/irs/gen_nw.c
+++ b/contrib/bind/lib/irs/gen_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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gen_nw.c,v 1.8 1997/12/04 04:57:50 halley Exp $";
+static const char rcsid[] = "$Id: gen_nw.c,v 1.13 1999/10/13 16:39:29 vixie Exp $";
#endif
/* Imports */
@@ -25,10 +25,15 @@ static char rcsid[] = "$Id: gen_nw.c,v 1.8 1997/12/04 04:57:50 halley Exp $";
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
#include <errno.h>
+#include <resolv.h>
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -41,6 +46,8 @@ static char rcsid[] = "$Id: gen_nw.c,v 1.8 1997/12/04 04:57:50 halley Exp $";
struct pvt {
struct irs_rule * rules;
struct irs_rule * rule;
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward */
@@ -51,6 +58,12 @@ static struct nwent * nw_byname(struct irs_nw *, const char *, int);
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
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 int init(struct irs_nw *this);
/* Public */
@@ -60,17 +73,17 @@ irs_gen_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->rules = accpvt->map_rules[irs_nw];
pvt->rule = pvt->rules;
nw->private = pvt;
@@ -80,6 +93,8 @@ irs_gen_nw(struct irs_acc *this) {
nw->byaddr = nw_byaddr;
nw->rewind = nw_rewind;
nw->minimize = nw_minimize;
+ nw->res_get = nw_res_get;
+ nw->res_set = nw_res_set;
return (nw);
}
@@ -89,8 +104,13 @@ static void
nw_close(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ nw_minimize(this);
+
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct nwent *
@@ -99,6 +119,9 @@ nw_next(struct irs_nw *this) {
struct nwent *rval;
struct irs_nw *nw;
+ if (init(this) == -1)
+ return(NULL);
+
while (pvt->rule) {
nw = pvt->rule->inst->nw;
rval = (*nw->next)(nw);
@@ -122,13 +145,17 @@ nw_byname(struct irs_nw *this, const char *name, int type) {
struct nwent *rval;
struct irs_nw *nw;
+ if (init(this) == -1)
+ return(NULL);
+
for (rule = pvt->rules; rule; rule = rule->next) {
nw = rule->inst->nw;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
rval = (*nw->byname)(nw, name, type);
if (rval != NULL)
return (rval);
- if (h_errno != TRY_AGAIN && !(rule->flags & IRS_CONTINUE))
+ if (pvt->res->res_h_errno != TRY_AGAIN &&
+ !(rule->flags & IRS_CONTINUE))
break;
}
return (NULL);
@@ -141,13 +168,17 @@ nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
struct nwent *rval;
struct irs_nw *nw;
+ if (init(this) == -1)
+ return(NULL);
+
for (rule = pvt->rules; rule; rule = rule->next) {
nw = rule->inst->nw;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
rval = (*nw->byaddr)(nw, net, length, type);
if (rval != NULL)
return (rval);
- if (h_errno != TRY_AGAIN && !(rule->flags & IRS_CONTINUE))
+ if (pvt->res->res_h_errno != TRY_AGAIN &&
+ !(rule->flags & IRS_CONTINUE))
break;
}
return (NULL);
@@ -170,9 +201,62 @@ nw_minimize(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
struct irs_rule *rule;
+ if (pvt->res)
+ res_nclose(pvt->res);
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
struct irs_nw *nw = rule->inst->nw;
(*nw->minimize)(nw);
}
}
+
+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;
+ struct irs_rule *rule;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
+
+ for (rule = pvt->rules; rule != NULL; rule = rule->next) {
+ struct irs_nw *nw = rule->inst->nw;
+
+ (*nw->res_set)(nw, pvt->res, NULL);
+ }
+}
+
+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);
+}
diff --git a/contrib/bind/lib/irs/gen_p.h b/contrib/bind/lib/irs/gen_p.h
index 92e115d..b8210b0 100644
--- a/contrib/bind/lib/irs/gen_p.h
+++ b/contrib/bind/lib/irs/gen_p.h
@@ -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 @@
*/
/*
- * $Id: gen_p.h,v 1.7 1996/11/21 10:28:15 vixie Exp $
+ * $Id: gen_p.h,v 1.10 1999/01/18 07:46:50 vixie Exp $
*/
/* Notes:
@@ -43,6 +43,7 @@ enum irs_acc_id {
irs_lcl, /* Local. */
irs_dns, /* DNS or Hesiod. */
irs_nis, /* Sun NIS ("YP"). */
+ irs_irp, /* IR protocol. */
irs_nacc
};
@@ -92,13 +93,15 @@ struct gen_p {
const char * options;
struct irs_rule * map_rules[(int)irs_nmap];
struct irs_inst accessors[(int)irs_nacc];
+ struct __res_state * res;
+ void (*free_res) __P((void *));
};
/*
* Externs.
*/
-extern struct irs_acc * irs_gen_acc __P((const char *));
+extern struct irs_acc * irs_gen_acc __P((const char *, const char *conf_file));
extern struct irs_gr * irs_gen_gr __P((struct irs_acc *));
extern struct irs_pw * irs_gen_pw __P((struct irs_acc *));
extern struct irs_sv * irs_gen_sv __P((struct irs_acc *));
diff --git a/contrib/bind/lib/irs/gen_pr.c b/contrib/bind/lib/irs/gen_pr.c
index 096be51..de09571 100644
--- a/contrib/bind/lib/irs/gen_pr.c
+++ b/contrib/bind/lib/irs/gen_pr.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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gen_pr.c,v 1.8 1997/12/04 04:57:51 halley Exp $";
+static const char rcsid[] = "$Id: gen_pr.c,v 1.12 1999/10/13 16:39:30 vixie Exp $";
#endif
/* Imports */
@@ -24,11 +24,15 @@ static char rcsid[] = "$Id: gen_pr.c,v 1.8 1997/12/04 04:57:51 halley Exp $";
#include "port_before.h"
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
#include <errno.h>
+#include <resolv.h>
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -41,6 +45,8 @@ static char rcsid[] = "$Id: gen_pr.c,v 1.8 1997/12/04 04:57:51 halley Exp $";
struct pvt {
struct irs_rule * rules;
struct irs_rule * rule;
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward */
@@ -51,6 +57,10 @@ static struct protoent * pr_byname(struct irs_pr *, const char *);
static struct protoent * pr_bynumber(struct irs_pr *, int);
static void pr_rewind(struct irs_pr *);
static void pr_minimize(struct irs_pr *);
+static struct __res_state * pr_res_get(struct irs_pr *);
+static void pr_res_set(struct irs_pr *,
+ struct __res_state *,
+ void (*)(void *));
/* Public */
@@ -60,13 +70,13 @@ irs_gen_pr(struct irs_acc *this) {
struct irs_pr *pr;
struct pvt *pvt;
- if (!(pr = (struct irs_pr *)malloc(sizeof *pr))) {
+ if (!(pr = memget(sizeof *pr))) {
errno = ENOMEM;
return (NULL);
}
memset(pr, 0x5e, sizeof *pr);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(pr);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(pr, sizeof *pr);
errno = ENOMEM;
return (NULL);
}
@@ -80,6 +90,8 @@ irs_gen_pr(struct irs_acc *this) {
pr->bynumber = pr_bynumber;
pr->rewind = pr_rewind;
pr->minimize = pr_minimize;
+ pr->res_get = pr_res_get;
+ pr->res_set = pr_res_set;
return (pr);
}
@@ -89,8 +101,8 @@ static void
pr_close(struct irs_pr *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct protoent *
@@ -172,3 +184,43 @@ pr_minimize(struct irs_pr *this) {
(*pr->minimize)(pr);
}
}
+
+static struct __res_state *
+pr_res_get(struct irs_pr *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);
+ pr_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+pr_res_set(struct irs_pr *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct irs_rule *rule;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
+
+ for (rule = pvt->rules; rule != NULL; rule = rule->next) {
+ struct irs_pr *pr = rule->inst->pr;
+
+ if (pr->res_set)
+ (*pr->res_set)(pr, pvt->res, NULL);
+ }
+}
diff --git a/contrib/bind/lib/irs/gen_pw.c b/contrib/bind/lib/irs/gen_pw.c
index aaa82df..d80a64b 100644
--- a/contrib/bind/lib/irs/gen_pw.c
+++ b/contrib/bind/lib/irs/gen_pw.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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gen_pw.c,v 1.10 1997/12/04 04:57:51 halley Exp $";
+static const char rcsid[] = "$Id: gen_pw.c,v 1.14 1999/10/13 16:39:30 vixie Exp $";
#endif
/* Imports */
@@ -28,12 +28,16 @@ static int __bind_irs_pw_unneeded;
#else
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <errno.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -46,6 +50,8 @@ static int __bind_irs_pw_unneeded;
struct pvt {
struct irs_rule * rules;
struct irs_rule * rule;
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward */
@@ -56,6 +62,10 @@ static struct passwd * pw_byname(struct irs_pw *, const char *);
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
static void pw_rewind(struct irs_pw *);
static void pw_minimize(struct irs_pw *);
+static struct __res_state * pw_res_get(struct irs_pw *);
+static void pw_res_set(struct irs_pw *,
+ struct __res_state *,
+ void (*)(void *));
/* Public */
@@ -65,13 +75,13 @@ irs_gen_pw(struct irs_acc *this) {
struct irs_pw *pw;
struct pvt *pvt;
- if (!(pw = (struct irs_pw *)malloc(sizeof *pw))) {
+ if (!(pw = memget(sizeof *pw))) {
errno = ENOMEM;
return (NULL);
}
memset(pw, 0x5e, sizeof *pw);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(pw);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(pw, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -85,6 +95,8 @@ irs_gen_pw(struct irs_acc *this) {
pw->byuid = pw_byuid;
pw->rewind = pw_rewind;
pw->minimize = pw_minimize;
+ pw->res_get = pw_res_get;
+ pw->res_set = pw_res_set;
return (pw);
}
@@ -94,8 +106,8 @@ static void
pw_close(struct irs_pw *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct passwd *
@@ -178,4 +190,44 @@ pw_minimize(struct irs_pw *this) {
}
}
+static struct __res_state *
+pw_res_get(struct irs_pw *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);
+ pw_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+pw_res_set(struct irs_pw *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct irs_rule *rule;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
+
+ for (rule = pvt->rules; rule != NULL; rule = rule->next) {
+ struct irs_pw *pw = rule->inst->pw;
+
+ if (pw->res_set)
+ (*pw->res_set)(pw, pvt->res, NULL);
+ }
+}
+
#endif /* WANT_IRS_PW */
diff --git a/contrib/bind/lib/irs/gen_sv.c b/contrib/bind/lib/irs/gen_sv.c
index 22f0cde..e0c1cb6 100644
--- a/contrib/bind/lib/irs/gen_sv.c
+++ b/contrib/bind/lib/irs/gen_sv.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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gen_sv.c,v 1.8 1997/12/04 04:57:52 halley Exp $";
+static const char rcsid[] = "$Id: gen_sv.c,v 1.12 1999/10/13 16:39:30 vixie Exp $";
#endif
/* Imports */
@@ -24,11 +24,15 @@ static char rcsid[] = "$Id: gen_sv.c,v 1.8 1997/12/04 04:57:52 halley Exp $";
#include "port_before.h"
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -41,6 +45,8 @@ static char rcsid[] = "$Id: gen_sv.c,v 1.8 1997/12/04 04:57:52 halley Exp $";
struct pvt {
struct irs_rule * rules;
struct irs_rule * rule;
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward */
@@ -52,6 +58,10 @@ static struct servent * sv_byname(struct irs_sv *, const char *,
static struct servent * sv_byport(struct irs_sv *, int, const char *);
static void sv_rewind(struct irs_sv *);
static void sv_minimize(struct irs_sv *);
+static struct __res_state * sv_res_get(struct irs_sv *);
+static void sv_res_set(struct irs_sv *,
+ struct __res_state *,
+ void (*)(void *));
/* Public */
@@ -61,13 +71,13 @@ irs_gen_sv(struct irs_acc *this) {
struct irs_sv *sv;
struct pvt *pvt;
- if (!(sv = (struct irs_sv *)malloc(sizeof *sv))) {
+ if (!(sv = memget(sizeof *sv))) {
errno = ENOMEM;
return (NULL);
}
memset(sv, 0x5e, sizeof *sv);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(sv);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(sv, sizeof *sv);
errno = ENOMEM;
return (NULL);
}
@@ -81,6 +91,8 @@ irs_gen_sv(struct irs_acc *this) {
sv->byport = sv_byport;
sv->rewind = sv_rewind;
sv->minimize = sv_minimize;
+ sv->res_get = sv_res_get;
+ sv->res_set = sv_res_set;
return (sv);
}
@@ -90,8 +102,8 @@ static void
sv_close(struct irs_sv *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct servent *
@@ -173,3 +185,43 @@ sv_minimize(struct irs_sv *this) {
(*sv->minimize)(sv);
}
}
+
+static struct __res_state *
+sv_res_get(struct irs_sv *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);
+ sv_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+sv_res_set(struct irs_sv *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct irs_rule *rule;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
+
+ for (rule = pvt->rules; rule != NULL; rule = rule->next) {
+ struct irs_sv *sv = rule->inst->sv;
+
+ if (sv->res_set)
+ (*sv->res_set)(sv, pvt->res, NULL);
+ }
+}
diff --git a/contrib/bind/lib/irs/getaddrinfo.c b/contrib/bind/lib/irs/getaddrinfo.c
new file mode 100644
index 0000000..f95a681
--- /dev/null
+++ b/contrib/bind/lib/irs/getaddrinfo.c
@@ -0,0 +1,505 @@
+/*-
+ * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved.
+ * The Berkeley Software Design Inc. software License Agreement specifies
+ * the terms and conditions for redistribution.
+ *
+ * BSDI $Id: getaddrinfo.c,v 8.3 1999/06/11 01:25:58 vixie Exp $
+ */
+
+#include <port_before.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <arpa/inet.h>
+#include <port_after.h>
+
+#define SA(addr) ((struct sockaddr *)(addr))
+#define SIN(addr) ((struct sockaddr_in *)(addr))
+#define SIN6(addr) ((struct sockaddr_in6 *)(addr))
+#define SUN(addr) ((struct sockaddr_un *)(addr))
+
+static struct addrinfo
+ *ai_reverse(struct addrinfo *oai),
+ *ai_clone(struct addrinfo *oai, int family),
+ *ai_alloc(int family, int addrlen);
+#ifdef AF_LOCAL
+static int get_local(const char *name, int socktype, struct addrinfo **res);
+#endif
+
+static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static void set_order(int, int (**)());
+
+#define FOUND_IPV4 0x1
+#define FOUND_IPV6 0x2
+#define FOUND_MAX 2
+
+int
+getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct servent *sp;
+ char *proto;
+ int family, socktype, flags, protocol;
+ struct addrinfo *ai, *ai_list;
+ int port, err, i;
+ int (*net_order[FOUND_MAX+1])();
+
+ if (hostname == NULL && servname == NULL)
+ return (EAI_NONAME);
+
+ proto = NULL;
+ if (hints != NULL) {
+ if (hints->ai_flags & ~(AI_MASK))
+ return (EAI_BADFLAGS);
+ if (hints->ai_addrlen || hints->ai_canonname ||
+ hints->ai_addr || hints->ai_next) {
+ errno = EINVAL;
+ return (EAI_SYSTEM);
+ }
+ family = hints->ai_family;
+ socktype = hints->ai_socktype;
+ protocol = hints->ai_protocol;
+ flags = hints->ai_flags;
+ switch (family) {
+ case AF_UNSPEC:
+ switch (hints->ai_socktype) {
+ case SOCK_STREAM: proto = "tcp"; break;
+ case SOCK_DGRAM: proto = "udp"; break;
+ }
+ break;
+ case AF_INET:
+ case AF_INET6:
+ switch (hints->ai_socktype) {
+ case 0: break;
+ case SOCK_STREAM: proto = "tcp"; break;
+ case SOCK_DGRAM: proto = "udp"; break;
+ case SOCK_RAW: break;
+ default: return (EAI_SOCKTYPE);
+ }
+ break;
+#ifdef AF_LOCAL
+ case AF_LOCAL:
+ switch (hints->ai_socktype) {
+ case 0: break;
+ case SOCK_STREAM: break;
+ case SOCK_DGRAM: break;
+ default: return (EAI_SOCKTYPE);
+ }
+ break;
+#endif
+ default:
+ return (EAI_FAMILY);
+ }
+ } else {
+ protocol = 0;
+ family = 0;
+ socktype = 0;
+ flags = 0;
+ }
+
+#ifdef AF_LOCAL
+ /*
+ * First, deal with AF_LOCAL. If the family was not set,
+ * then assume AF_LOCAL if the first character of the
+ * hostname/servname is '/'.
+ */
+
+ if (hostname &&
+ (family == AF_LOCAL || (family == 0 && *hostname == '/')))
+ return (get_local(hostname, socktype, res));
+
+ if (servname &&
+ (family == AF_LOCAL || (family == 0 && *servname == '/')))
+ return (get_local(servname, socktype, res));
+#endif
+
+ /*
+ * Ok, only AF_INET and AF_INET6 left.
+ */
+ ai_list = NULL;
+
+ /*
+ * First, look up the service name (port) if it was
+ * requested. If the socket type wasn't specified, then
+ * try and figure it out.
+ */
+ if (servname) {
+ char *e;
+
+ port = strtol(servname, &e, 10);
+ if (*e == '\0') {
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+ if (port < 0 || port > 65535)
+ return (EAI_SERVICE);
+ port = htons(port);
+ } else {
+ sp = getservbyname(servname, proto);
+ if (sp == NULL)
+ return (EAI_SERVICE);
+ port = sp->s_port;
+ if (socktype == 0) {
+ if (strcmp(sp->s_proto, "tcp"))
+ socktype = SOCK_STREAM;
+ else if (strcmp(sp->s_proto, "udp"))
+ socktype = SOCK_DGRAM;
+ }
+ }
+ } else
+ port = 0;
+
+ /*
+ * Next, deal with just a service name, and no hostname.
+ * (we verified that one of them was non-null up above).
+ */
+ if (hostname == NULL && (flags & AI_PASSIVE) != 0) {
+ if (family == AF_INET || family == 0) {
+ ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN(ai->ai_addr)->sin_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ if (family == AF_INET6 || family == 0) {
+ ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
+ if (ai == NULL) {
+ freeaddrinfo(ai_list);
+ return (EAI_MEMORY);
+ }
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ *res = ai_list;
+ return (0);
+ }
+
+ /*
+ * If the family isn't specified or AI_NUMERICHOST specified,
+ * check first to see if it * is a numeric address.
+ * Though the gethostbyname2() routine
+ * will recognize numeric addresses, it will only recognize
+ * the format that it is being called for. Thus, a numeric
+ * AF_INET address will be treated by the AF_INET6 call as
+ * a domain name, and vice versa. Checking for both numerics
+ * here avoids that.
+ */
+ if (hostname != NULL &&
+ (family == 0 || (flags & AI_NUMERICHOST) != 0)) {
+ char abuf[sizeof(struct in6_addr)];
+ char nbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx00")];
+ int addrsize, addroff;
+
+ if (inet_aton(hostname, (struct in_addr *)abuf)) {
+ if (family == AF_INET6) {
+ /* Convert to a V4 mapped address */
+ struct in6_addr *a6 = (struct in6_addr *)abuf;
+ memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);
+ memset(&a6->s6_addr[10], 0xff, 2);
+ memset(&a6->s6_addr[0], 0, 10);
+ goto inet6_addr;
+ }
+ addrsize = sizeof(struct in_addr);
+ addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
+ family = AF_INET;
+ goto common;
+
+ } else if (inet_pton(AF_INET6, hostname, abuf)) {
+ if (family && family != AF_INET6)
+ return (EAI_NONAME);
+ inet6_addr:
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+
+ common:
+ if ((ai = ai_clone(ai_list, family)) == NULL)
+ return (EAI_MEMORY);
+ ai_list = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);
+ if (flags & AI_CANONNAME) {
+ inet_ntop(family, abuf, nbuf, sizeof(nbuf));
+ ai->ai_canonname = strdup(nbuf);
+ }
+ goto done;
+ } else if ((flags & AI_NUMERICHOST) != 0){
+ return (EAI_NONAME);
+ }
+ }
+
+ set_order(family, net_order);
+ for (i = 0; i < FOUND_MAX; i++) {
+ if (net_order[i] == NULL)
+ break;
+ if ((err = (net_order[i])(hostname, flags, &ai_list,
+ socktype, port)) != 0)
+ return(err);
+ }
+
+ if (ai_list == NULL)
+ return (EAI_NODATA);
+
+done:
+ ai_list = ai_reverse(ai_list);
+
+ *res = ai_list;
+ return (0);
+}
+
+static void
+set_order(family, net_order)
+ int family;
+ int (**net_order)();
+{
+ char *order, *tok;
+ int found;
+
+ if (family) {
+ switch (family) {
+ case AF_INET:
+ *net_order++ = add_ipv4;
+ break;
+ case AF_INET6:
+ *net_order++ = add_ipv6;
+ break;
+ }
+ } else {
+ order = getenv("NET_ORDER");
+ found = 0;
+ while (order != NULL) {
+ /* We ignore any unknown names. */
+ tok = strsep(&order, ":");
+ if (strcasecmp(tok, "inet6") == 0) {
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ found |= FOUND_IPV6;
+ } else if (strcasecmp(tok, "inet") == 0 ||
+ strcasecmp(tok, "inet4") == 0) {
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ found |= FOUND_IPV4;
+ }
+ }
+
+ /* Add in anything that we didn't find */
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ }
+ *net_order = NULL;
+ return;
+}
+
+static char v4_loop[4] = { 127, 0, 0, 1 };
+
+static int
+add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+ struct hostent *hp;
+ char **addr;
+
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ if ((ai = ai_clone(*aip, AF_INET)) == NULL) {
+ freeaddrinfo(*aip);
+ return(EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
+ } else if ((hp = gethostbyname2(hostname, AF_INET)) != NULL) {
+ for (addr = hp->h_addr_list; *addr; addr++) {
+ if ((ai = ai_clone(*aip, hp->h_addrtype)) == NULL) {
+ freeaddrinfo(*aip);
+ return(EAI_MEMORY);
+ }
+ *aip = ai;
+ ai->ai_socktype = socktype;
+
+ /* We get IPv6 addresses if RES_USE_INET6 is set */
+ if (hp->h_addrtype == AF_INET6) {
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr, *addr,
+ hp->h_length);
+ } else {
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr, *addr,
+ hp->h_length);
+ }
+ if (flags & AI_CANONNAME)
+ ai->ai_canonname = strdup(hp->h_name);
+ }
+ }
+ return(0);
+}
+
+static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+static int
+add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+ struct hostent *hp;
+ char **addr;
+
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ if ((ai = ai_clone(*aip, AF_INET6)) == NULL) {
+ freeaddrinfo(*aip);
+ return(EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
+ } else if ((hp = gethostbyname2(hostname, AF_INET6)) != NULL) {
+ for (addr = hp->h_addr_list; *addr; addr++) {
+ if ((ai = ai_clone(*aip, AF_INET6)) == NULL) {
+ freeaddrinfo(*aip);
+ return (EAI_MEMORY);
+ }
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr, *addr,
+ hp->h_length);
+ if (flags & AI_CANONNAME)
+ ai->ai_canonname = strdup(hp->h_name);
+ }
+ }
+ return (0);
+}
+
+void
+freeaddrinfo(struct addrinfo *ai) {
+ struct addrinfo *ai_next;
+
+ while (ai != NULL) {
+ ai_next = ai->ai_next;
+ if (ai->ai_addr)
+ free(ai->ai_addr);
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
+ free(ai);
+ ai = ai_next;
+ }
+}
+
+#ifdef AF_LOCAL
+static int
+get_local(const char *name, int socktype, struct addrinfo **res) {
+ struct addrinfo *ai;
+ struct sockaddr_un *sun;
+
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+
+ if ((ai = ai_alloc(AF_LOCAL, sizeof(*sun))) == NULL)
+ return (EAI_MEMORY);
+
+ sun = SUN(ai->ai_addr);
+ strncpy(sun->sun_path, name, sizeof(sun->sun_path));
+
+ ai->ai_socktype = socktype;
+ /*
+ * ai->ai_flags, ai->ai_protocol, ai->ai_canonname,
+ * and ai->ai_next were initialized to zero.
+ */
+
+ *res = ai;
+ return (0);
+}
+#endif
+
+/*
+ * Allocate an addrinfo structure, and a sockaddr structure
+ * of the specificed length. We initialize:
+ * ai_addrlen
+ * ai_family
+ * ai_addr
+ * ai_addr->sa_family
+ * ai_addr->sa_len (HAVE_SA_LEN)
+ * and everything else is initialized to zero.
+ */
+static struct addrinfo *
+ai_alloc(int family, int addrlen) {
+ struct addrinfo *ai;
+
+ if ((ai = (struct addrinfo *)calloc(1, sizeof(*ai))) == NULL)
+ return (NULL);
+
+ if ((ai->ai_addr = SA(calloc(1, addrlen))) == NULL) {
+ free(ai);
+ return (NULL);
+ }
+ ai->ai_addrlen = addrlen;
+ ai->ai_family = family;
+ ai->ai_addr->sa_family = family;
+#ifdef HAVE_SA_LEN
+ ai->ai_addr->sa_len = addrlen;
+#endif
+ return (ai);
+}
+
+static struct addrinfo *
+ai_clone(struct addrinfo *oai, int family) {
+ struct addrinfo *ai;
+
+ ai = ai_alloc(family, ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
+
+ if (ai == NULL) {
+ freeaddrinfo(oai);
+ return (NULL);
+ }
+ if (oai == NULL)
+ return (ai);
+
+ ai->ai_flags = oai->ai_flags;
+ ai->ai_socktype = oai->ai_socktype;
+ ai->ai_protocol = oai->ai_protocol;
+ ai->ai_canonname = NULL;
+ ai->ai_next = oai;
+ return (ai);
+}
+
+static struct addrinfo *
+ai_reverse(struct addrinfo *oai) {
+ struct addrinfo *nai, *tai;
+
+ nai = NULL;
+
+ while (oai) {
+ /* grab one off the old list */
+ tai = oai;
+ oai = oai->ai_next;
+ /* put it on the front of the new list */
+ tai->ai_next = nai;
+ nai = tai;
+ }
+ return (nai);
+}
diff --git a/contrib/bind/lib/irs/getgrent.c b/contrib/bind/lib/irs/getgrent.c
index df34447fb0..866e8c5 100644
--- a/contrib/bind/lib/irs/getgrent.c
+++ b/contrib/bind/lib/irs/getgrent.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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,21 +16,25 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: getgrent.c,v 1.13 1998/03/21 00:59:47 halley Exp $";
+static const char rcsid[] = "$Id: getgrent.c,v 1.19 1999/10/13 16:39:30 vixie Exp $";
#endif
/* Imports */
#include "port_before.h"
-#ifndef WANT_IRS_GR
+#if !defined(WANT_IRS_GR) || defined(__BIND_NOSTATIC)
static int __bind_irs_gr_unneeded;
#else
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
#include <errno.h>
#include <grp.h>
+#include <resolv.h>
#include <stdio.h>
#include <irs.h>
@@ -41,87 +45,150 @@ static int __bind_irs_gr_unneeded;
/* Forward */
-static struct irs_gr * init(void);
+static struct net_data *init(void);
void endgrent(void);
/* Public */
struct group *
getgrent() {
- struct irs_gr *gr = init();
-
- if (!gr)
- return (NULL);
- net_data.gr_last = (*gr->next)(gr);
- return (net_data.gr_last);
+ struct net_data *net_data = init();
+
+ return (getgrent_p(net_data));
}
struct group *
getgrnam(const char *name) {
- struct irs_gr *gr = init();
-
- if (!gr)
+ struct net_data *net_data = init();
+
+ return (getgrnam_p(name, net_data));
+}
+
+struct group *
+getgrgid(gid_t gid) {
+ struct net_data *net_data = init();
+
+ return (getgrgid_p(gid, net_data));
+}
+
+int
+setgroupent(int stayopen) {
+ struct net_data *net_data = init();
+
+ return (setgroupent_p(stayopen, net_data));
+}
+
+#ifdef SETGRENT_VOID
+void
+setgrent() {
+ struct net_data *net_data = init();
+
+ return (setgrent_p(net_data));
+}
+#else
+int
+setgrent() {
+ struct net_data *net_data = init();
+
+ return (setgrent_p(net_data));
+}
+#endif /* SETGRENT_VOID */
+
+void
+endgrent() {
+ struct net_data *net_data = init();
+
+ endgrent_p(net_data);
+}
+
+int
+getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroups) {
+ struct net_data *net_data = init();
+
+ return (getgrouplist_p(name, basegid, groups, ngroups, net_data));
+}
+
+/* Shared private. */
+
+struct group *
+getgrent_p(struct net_data *net_data) {
+ struct irs_gr *gr;
+
+ if (!net_data || !(gr = net_data->gr))
+ return (NULL);
+ net_data->gr_last = (*gr->next)(gr);
+ return (net_data->gr_last);
+}
+
+struct group *
+getgrnam_p(const char *name, struct net_data *net_data) {
+ struct irs_gr *gr;
+
+ if (!net_data || !(gr = net_data->gr))
return (NULL);
- if (net_data.gr_stayopen && net_data.gr_last &&
- !strcmp(net_data.gr_last->gr_name, name))
- return (net_data.gr_last);
- net_data.gr_last = (*gr->byname)(gr, name);
- if (!net_data.gr_stayopen)
+ if (net_data->gr_stayopen && net_data->gr_last &&
+ !strcmp(net_data->gr_last->gr_name, name))
+ return (net_data->gr_last);
+ net_data->gr_last = (*gr->byname)(gr, name);
+ if (!net_data->gr_stayopen)
endgrent();
- return (net_data.gr_last);
+ return (net_data->gr_last);
}
struct group *
-getgrgid(gid_t gid) {
- struct irs_gr *gr = init();
-
- if (!gr)
+getgrgid_p(gid_t gid, struct net_data *net_data) {
+ struct irs_gr *gr;
+
+ if (!net_data || !(gr = net_data->gr))
return (NULL);
- if (net_data.gr_stayopen && net_data.gr_last &&
- net_data.gr_last->gr_gid == gid)
- return (net_data.gr_last);
- net_data.gr_last = (*gr->bygid)(gr, gid);
- if (!net_data.gr_stayopen)
+ if (net_data->gr_stayopen && net_data->gr_last &&
+ net_data->gr_last->gr_gid == gid)
+ return (net_data->gr_last);
+ net_data->gr_last = (*gr->bygid)(gr, gid);
+ if (!net_data->gr_stayopen)
endgrent();
- return (net_data.gr_last);
+ return (net_data->gr_last);
}
int
-setgroupent(int stayopen) {
- struct irs_gr *gr = init();
-
- if (!gr)
+setgroupent_p(int stayopen, struct net_data *net_data) {
+ struct irs_gr *gr;
+
+ if (!net_data || !(gr = net_data->gr))
return (0);
(*gr->rewind)(gr);
- net_data.gr_stayopen = (stayopen != 0);
+ net_data->gr_stayopen = (stayopen != 0);
+ if (stayopen == 0)
+ net_data_minimize(net_data);
return (1);
}
#ifdef SETGRENT_VOID
void
-setgrent() {
- (void)setgroupent(0);
+setgrent_p(struct net_data *net_data) {
+ (void)setgroupent_p(0, net_data);
}
#else
int
-setgrent() {
- return (setgroupent(0));
+setgrent_p(struct net_data *net_data) {
+ return (setgroupent_p(0, net_data));
}
#endif /* SETGRENT_VOID */
void
-endgrent() {
- struct irs_gr *gr = init();
+endgrent_p(struct net_data *net_data) {
+ struct irs_gr *gr;
- if (gr != NULL)
+ if ((net_data != NULL) && ((gr = net_data->gr) != NULL))
(*gr->minimize)(gr);
}
int
-getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroups) {
- struct irs_gr *gr = init();
-
- if (!gr) {
+getgrouplist_p(const char *name, gid_t basegid, gid_t *groups, int *ngroups,
+ struct net_data *net_data) {
+ struct irs_gr *gr;
+
+ if (!net_data || !(gr = net_data->gr)) {
*ngroups = 0;
return (-1);
}
@@ -130,18 +197,25 @@ getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroups) {
/* Private */
-static struct irs_gr *
+static struct net_data *
init() {
- if (!net_data_init())
+ struct net_data *net_data;
+
+ if (!(net_data = net_data_init(NULL)))
goto error;
- if (!net_data.gr)
- net_data.gr = (*net_data.irs->gr_map)(net_data.irs);
- if (!net_data.gr) {
+ if (!net_data->gr) {
+ net_data->gr = (*net_data->irs->gr_map)(net_data->irs);
+
+ if (!net_data->gr || !net_data->res) {
error:
- errno = EIO;
- return (NULL);
+ errno = EIO;
+ return (NULL);
+ }
+ (*net_data->gr->res_set)(net_data->gr, net_data->res,
+ NULL);
}
- return (net_data.gr);
+
+ return (net_data);
}
#endif /* WANT_IRS_GR */
diff --git a/contrib/bind/lib/irs/getgrent_r.c b/contrib/bind/lib/irs/getgrent_r.c
new file mode 100644
index 0000000..df055db
--- /dev/null
+++ b/contrib/bind/lib/irs/getgrent_r.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1998-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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: getgrent_r.c,v 8.4 1999/01/18 07:46:51 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <port_before.h>
+#if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
+ static int getgrent_r_not_required = 0;
+#else
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <grp.h>
+#include <sys/param.h>
+#include <port_after.h>
+
+#ifdef GROUP_R_RETURN
+
+static int
+copy_group(struct group *, struct group *, char *buf, int buflen);
+
+/* POSIX 1003.1c */
+#ifdef POSIX_GETGRNAM_R
+int
+__posix_getgrnam_r(const char *name, struct group *gptr,
+ char *buf, int buflen, struct group **result) {
+#else
+int
+getgrnam_r(const char *name, struct group *gptr,
+ char *buf, size_t buflen, struct group **result) {
+#endif
+ struct group *ge = getgrnam(name);
+ int res;
+
+ if (ge == NULL) {
+ *result = NULL;
+ return (-1);
+ }
+
+ res = copy_group(ge, gptr, buf, buflen);
+ *result = res ? NULL : gptr;
+ return (res);
+}
+
+#ifdef POSIX_GETGRNAM_R
+struct group *
+getgrnam_r(const char *name, struct group *gptr,
+ char *buf, int buflen) {
+ struct group *ge = getgrnam(name);
+ int res;
+
+ if (ge == NULL)
+ return (NULL);
+ res = copy_group(ge, gptr, buf, buflen);
+ return (res ? NULL : gptr);
+}
+#endif /* POSIX_GETGRNAM_R */
+
+/* POSIX 1003.1c */
+#ifdef POSIX_GETGRGID_R
+int
+__posix_getgrgid_r(const gid_t gid, struct group *gptr,
+ char *buf, int buflen, struct group **result) {
+#else /* POSIX_GETGRGID_R */
+int
+getgrgid_r(const gid_t gid, struct group *gptr,
+ char *buf, size_t buflen, struct group **result) {
+#endif /* POSIX_GETGRGID_R */
+ struct group *ge = getgrgid(gid);
+ int res;
+
+ if (ge == NULL) {
+ *result = NULL;
+ return (-1);
+ }
+
+ res = copy_group(ge, gptr, buf, buflen);
+ *result = res ? NULL : gptr;
+ return (res);
+}
+
+#ifdef POSIX_GETGRGID_R
+struct group *
+getgrgid_r(const gid_t gid, struct group *gptr,
+ char *buf, int buflen) {
+ struct group *ge = getgrgid(gid);
+ int res;
+
+ if (ge == NULL)
+ return (NULL);
+
+ res = copy_group(ge, gptr, buf, buflen);
+ return (res ? NULL : gptr);
+}
+#endif
+
+/*
+ * These assume a single context is in operation per thread.
+ * If this is not the case we will need to call irs directly
+ * rather than through the base functions.
+ */
+
+GROUP_R_RETURN
+getgrent_r(struct group *gptr, GROUP_R_ARGS) {
+ struct group *ge = getgrent();
+ int res;
+
+ if (ge == NULL) {
+ return (GROUP_R_BAD);
+ }
+
+ res = copy_group(ge, gptr, buf, buflen);
+ return (res ? GROUP_R_BAD : GROUP_R_OK);
+}
+
+GROUP_R_SET_RETURN
+setgrent_r(GROUP_R_ENT_ARGS) {
+
+ setgrent();
+#ifdef GROUP_R_SET_RESULT
+ return (GROUP_R_SET_RESULT);
+#endif
+}
+
+GROUP_R_END_RETURN
+endgrent_r(GROUP_R_ENT_ARGS) {
+
+ endgrent();
+ GROUP_R_END_RESULT(GROUP_R_OK);
+}
+
+
+#if 0
+ /* XXX irs does not have a fgetgrent() */
+GROUP_R_RETURN
+fgetgrent_r(FILE *f, struct group *gptr, GROUP_R_ARGS) {
+ struct group *ge = fgetgrent(f);
+ int res;
+
+ if (ge == NULL)
+ return (GROUP_R_BAD);
+
+ res = copy_group(ge, gptr, buf, buflen);
+ return (res ? GROUP_R_BAD : GROUP_R_OK);
+}
+#endif
+
+/* Private */
+
+static int
+copy_group(struct group *ge, struct group *gptr, char *buf, int buflen) {
+ char *cp;
+ int i, n;
+ int numptr, len;
+
+ /* Find out the amount of space required to store the answer. */
+ numptr = 1; /* NULL ptr */
+ len = (char *)ALIGN(buf) - buf;
+ for (i = 0; ge->gr_mem[i]; i++, numptr++) {
+ len += strlen(ge->gr_mem[i]) + 1;
+ }
+ len += strlen(ge->gr_name) + 1;
+ len += strlen(ge->gr_passwd) + 1;
+ len += numptr * sizeof(char*);
+
+ if (len > buflen) {
+ errno = ERANGE;
+ return (-1);
+ }
+
+ /* copy group id */
+ gptr->gr_gid = ge->gr_gid;
+
+ cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
+
+ /* copy official name */
+ n = strlen(ge->gr_name) + 1;
+ strcpy(cp, ge->gr_name);
+ gptr->gr_name = cp;
+ cp += n;
+
+ /* copy member list */
+ gptr->gr_mem = (char **)ALIGN(buf);
+ for (i = 0 ; ge->gr_mem[i]; i++) {
+ n = strlen(ge->gr_mem[i]) + 1;
+ strcpy(cp, ge->gr_mem[i]);
+ gptr->gr_mem[i] = cp;
+ cp += n;
+ }
+ gptr->gr_mem[i] = NULL;
+
+ /* copy password */
+ n = strlen(ge->gr_passwd) + 1;
+ strcpy(cp, ge->gr_passwd);
+ gptr->gr_passwd = cp;
+ cp += n;
+
+ return (0);
+}
+#else /* GROUP_R_RETURN */
+ static int getgrent_r_unknown_system = 0;
+#endif /* GROUP_R_RETURN */
+#endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
diff --git a/contrib/bind/lib/irs/gethostent.c b/contrib/bind/lib/irs/gethostent.c
index 669cb95..ac66520 100644
--- a/contrib/bind/lib/irs/gethostent.c
+++ b/contrib/bind/lib/irs/gethostent.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996,1997 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,17 +16,21 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: gethostent.c,v 1.13 1997/12/04 04:57:52 halley Exp $";
+static const char rcsid[] = "$Id: gethostent.c,v 1.25 1999/10/19 22:27:20 cyarnell Exp $";
#endif
/* Imports */
#include "port_before.h"
+#if !defined(__BIND_NOSTATIC)
+
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/ioctl.h>
#include <netinet/in.h>
+#include <net/if.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
@@ -37,8 +41,10 @@ static char rcsid[] = "$Id: gethostent.c,v 1.13 1997/12/04 04:57:52 halley Exp $
#include <resolv.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
@@ -57,156 +63,747 @@ struct pvt {
/* Forward */
-static struct irs_ho * init(void);
-static void freepvt(void);
-static struct hostent * fakeaddr(const char *, int);
+static struct net_data *init(void);
+static void freepvt(struct net_data *);
+static struct hostent *fakeaddr(const char *, int, struct net_data *);
+
/* Public */
struct hostent *
gethostbyname(const char *name) {
+ struct net_data *net_data = init();
+
+ return (gethostbyname_p(name, net_data));
+}
+
+struct hostent *
+gethostbyname2(const char *name, int af) {
+ struct net_data *net_data = init();
+
+ return (gethostbyname2_p(name, af, net_data));
+}
+
+struct hostent *
+gethostbyaddr(const char *addr, int len, int af) {
+ struct net_data *net_data = init();
+
+ return (gethostbyaddr_p(addr, len, af, net_data));
+}
+
+struct hostent *
+gethostent() {
+ struct net_data *net_data = init();
+
+ return (gethostent_p(net_data));
+}
+
+void
+sethostent(int stayopen) {
+ struct net_data *net_data = init();
+ sethostent_p(stayopen, net_data);
+}
+
+
+void
+endhostent() {
+ struct net_data *net_data = init();
+ endhostent_p(net_data);
+}
+
+/* Shared private. */
+
+struct hostent *
+gethostbyname_p(const char *name, struct net_data *net_data) {
struct hostent *hp;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (!net_data)
return (NULL);
- if (_res.options & RES_USE_INET6) {
- hp = gethostbyname2(name, AF_INET6);
+
+ if (net_data->res->options & RES_USE_INET6) {
+ hp = gethostbyname2_p(name, AF_INET6, net_data);
if (hp)
return (hp);
}
- return (gethostbyname2(name, AF_INET));
+ return (gethostbyname2_p(name, AF_INET, net_data));
}
struct hostent *
-gethostbyname2(const char *name, int af) {
- struct irs_ho *ho = init();
+gethostbyname2_p(const char *name, int af, struct net_data *net_data) {
+ struct irs_ho *ho;
+ char tmp[NS_MAXDNAME];
struct hostent *hp;
const char *cp;
char **hap;
- if (!ho)
+ if (!net_data || !(ho = net_data->ho))
return (NULL);
- if (net_data.ho_stayopen && net_data.ho_last) {
- if (!strcasecmp(name, net_data.ho_last->h_name))
- return (net_data.ho_last);
- for (hap = net_data.ho_last->h_aliases; hap && *hap; hap++)
- if (!strcasecmp(name, *hap))
- return (net_data.ho_last);
+ if (net_data->ho_stayopen && net_data->ho_last) {
+ if (ns_samename(name, net_data->ho_last->h_name) == 1)
+ return (net_data->ho_last);
+ for (hap = net_data->ho_last->h_aliases; hap && *hap; hap++)
+ if (ns_samename(name, *hap) == 1)
+ return (net_data->ho_last);
}
- if (!strchr(name, '.') && (cp = hostalias(name)))
+ if (!strchr(name, '.') && (cp = res_hostalias(net_data->res, name,
+ tmp, sizeof tmp)))
name = cp;
- if ((hp = fakeaddr(name, af)) != NULL)
+ if ((hp = fakeaddr(name, af, net_data)) != NULL)
return (hp);
- net_data.ho_last = (*ho->byname2)(ho, name, af);
- if (!net_data.ho_stayopen)
+ net_data->ho_last = (*ho->byname2)(ho, name, af);
+ if (!net_data->ho_stayopen)
endhostent();
- return (net_data.ho_last);
+ return (net_data->ho_last);
}
struct hostent *
-gethostbyaddr(const char *addr, int len, int af) {
- struct irs_ho *ho = init();
+gethostbyaddr_p(const char *addr, int len, int af, struct net_data *net_data) {
+ struct irs_ho *ho;
char **hap;
- if (!ho)
+ if (!net_data || !(ho = net_data->ho))
return (NULL);
- if (net_data.ho_stayopen && net_data.ho_last &&
- net_data.ho_last->h_length == len)
- for (hap = net_data.ho_last->h_addr_list;
+ if (net_data->ho_stayopen && net_data->ho_last &&
+ net_data->ho_last->h_length == len)
+ for (hap = net_data->ho_last->h_addr_list;
hap && *hap;
hap++)
if (!memcmp(addr, *hap, len))
- return (net_data.ho_last);
- net_data.ho_last = (*ho->byaddr)(ho, addr, len, af);
- if (!net_data.ho_stayopen)
+ return (net_data->ho_last);
+ net_data->ho_last = (*ho->byaddr)(ho, addr, len, af);
+ if (!net_data->ho_stayopen)
endhostent();
- return (net_data.ho_last);
+ return (net_data->ho_last);
}
+
struct hostent *
-gethostent() {
- struct irs_ho *ho = init();
+gethostent_p(struct net_data *net_data) {
+ struct irs_ho *ho;
+ struct hostent *hp;
- if (!ho)
+ if (!net_data || !(ho = net_data->ho))
return (NULL);
- net_data.ho_last = (*ho->next)(ho);
- return (net_data.ho_last);
+ while ((hp = (*ho->next)(ho)) != NULL &&
+ hp->h_addrtype == AF_INET6 &&
+ (net_data->res->options & RES_USE_INET6) == 0)
+ continue;
+ net_data->ho_last = hp;
+ return (net_data->ho_last);
}
+
void
-sethostent(int stayopen) {
- struct irs_ho *ho = init();
+sethostent_p(int stayopen, struct net_data *net_data) {
+ struct irs_ho *ho;
- if (!ho)
+ if (!net_data || !(ho = net_data->ho))
return;
- freepvt();
+ freepvt(net_data);
(*ho->rewind)(ho);
- net_data.ho_stayopen = (stayopen != 0);
+ net_data->ho_stayopen = (stayopen != 0);
+ if (stayopen == 0)
+ net_data_minimize(net_data);
}
void
-endhostent() {
- struct irs_ho *ho = init();
+endhostent_p(struct net_data *net_data) {
+ struct irs_ho *ho;
- if (ho != NULL)
+ if ((net_data != NULL) && ((ho = net_data->ho) != NULL))
(*ho->minimize)(ho);
}
-/* Private */
+#if !defined(HAS_INET6_STRUCTS) || defined(MISSING_IN6ADDR_ANY)
+static const struct in6_addr in6addr_any;
+#endif
-static struct irs_ho *
-init() {
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+#ifndef IN6_IS_ADDR_V4COMPAT
+static const unsigned char in6addr_compat[12] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+#define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
+ ((x)->s6_addr[12] != 0 || \
+ (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && \
+ (x)->s6_addr[15] != 1)))
+#endif
+#ifndef IN6_IS_ADDR_V4MAPPED
+#define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
+#endif
+
+static const unsigned char in6addr_mapped[12] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+
+static int scan_interfaces(int *, int *);
+static struct hostent *copyandmerge(struct hostent *, struct hostent *, int, int *);
+
+/*
+ * Public functions
+ */
+
+/*
+ * AI_V4MAPPED + AF_INET6
+ * If no IPv6 address then a query for IPv4 and map returned values.
+ *
+ * AI_ALL + AI_V4MAPPED + AF_INET6
+ * Return IPv6 and IPv4 mapped.
+ *
+ * AI_ADDRCONFIG
+ * Only return IPv6 / IPv4 address if there is an interface of that
+ * type active.
+ */
+
+struct hostent *
+getipnodebyname(const char *name, int af, int flags, int *error_num) {
+ int have_v4 = 1, have_v6 = 1;
+ struct in_addr in4;
+ struct in6_addr in6;
+ struct hostent he, *he1 = NULL, *he2 = NULL, *he3;
+ int v4 = 0, v6 = 0;
+ struct net_data *net_data = init();
+ u_long options;
+ int tmp_err;
+
+ if (net_data == NULL) {
+ *error_num = NO_RECOVERY;
return (NULL);
- if (!net_data_init())
- goto error;
- if (!net_data.ho)
- net_data.ho = (*net_data.irs->ho_map)(net_data.irs);
- if (!net_data.ho) {
- error: errno = EIO;
- h_errno = NETDB_INTERNAL;
+ }
+
+ /* If we care about active interfaces then check. */
+ if ((flags & AI_ADDRCONFIG) != 0)
+ if (scan_interfaces(&have_v4, &have_v6) == -1) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ /* Check for literal address. */
+ if ((v4 = inet_pton(AF_INET, name, &in4)) != 1)
+ v6 = inet_pton(AF_INET6, name, &in6);
+
+ /* Impossible combination? */
+
+ if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) ||
+ (af == AF_INET && v6 == 1) ||
+ (have_v4 == 0 && v4 == 1) ||
+ (have_v6 == 0 && v6 == 1) ||
+ (have_v4 == 0 && af == AF_INET) ||
+ (have_v6 == 0 && af == AF_INET6)) {
+ *error_num = HOST_NOT_FOUND;
return (NULL);
}
- return (net_data.ho);
+
+ /* Literal address? */
+ if (v4 == 1 || v6 == 1) {
+ char *addr_list[2];
+ char *aliases[1];
+
+ he.h_name = (char *)name;
+ he.h_addr_list = addr_list;
+ he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6;
+ he.h_addr_list[1] = NULL;
+ he.h_aliases = aliases;
+ he.h_aliases[0] = NULL;
+ he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ;
+ he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6;
+ return (copyandmerge(&he, NULL, af, error_num));
+ }
+
+ options = net_data->res->options;
+ net_data->res->options &= ~RES_USE_INET6;
+
+ tmp_err = NO_RECOVERY;
+ if (have_v6 && af == AF_INET6) {
+ he2 = gethostbyname2_p(name, AF_INET6, net_data);
+ if (he2 != NULL) {
+ he1 = copyandmerge(he2, NULL, af, error_num);
+ if (he1 == NULL)
+ return (NULL);
+ he2 = NULL;
+ } else {
+ tmp_err = net_data->res->res_h_errno;
+ }
+ }
+
+ if (have_v4 &&
+ ((af == AF_INET) ||
+ (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 &&
+ (he1 == NULL || (flags & AI_ALL) != 0)))) {
+ he2 = gethostbyname2_p(name, AF_INET, net_data);
+ if (he1 == NULL && he2 == NULL) {
+ *error_num = net_data->res->res_h_errno;
+ return (NULL);
+ }
+ } else
+ *error_num = tmp_err;
+
+ net_data->res->options = options;
+
+ he3 = copyandmerge(he1, he2, af, error_num);
+
+ if (he1 != NULL)
+ freehostent(he1);
+ return (he3);
+}
+
+struct hostent *
+getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
+ struct hostent *he1, *he2;
+ struct net_data *net_data = init();
+
+ /* Sanity Checks. */
+ if (src == NULL) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ switch (af) {
+ case AF_INET:
+ if (len != INADDRSZ) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ case AF_INET6:
+ if (len != IN6ADDRSZ) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ default:
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ /*
+ * Lookup IPv4 and IPv4 mapped/compatible addresses
+ */
+ if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT((struct in6_addr *)src)) ||
+ (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) ||
+ (af == AF_INET)) {
+ const char *cp = src;
+
+ if (af == AF_INET6)
+ cp += 12;
+ he1 = gethostbyaddr_p(cp, 4, AF_INET, net_data);
+ if (he1 == NULL) {
+ *error_num = net_data->res->res_h_errno;
+ return (NULL);
+ }
+ he2 = copyandmerge(he1, NULL, af, error_num);
+ if (he2 == NULL)
+ return (NULL);
+ /*
+ * Restore original address if mapped/compatible.
+ */
+ if (af == AF_INET6)
+ memcpy(he1->h_addr, src, len);
+ return (he2);
+ }
+
+ /*
+ * Lookup IPv6 address.
+ */
+ if (memcmp((struct in6_addr *)src, &in6addr_any, 16) == 0) {
+ *error_num = HOST_NOT_FOUND;
+ return (NULL);
+ }
+
+ he1 = gethostbyaddr_p(src, 16, AF_INET6, net_data);
+ if (he1 == NULL) {
+ *error_num = net_data->res->res_h_errno;
+ return (NULL);
+ }
+ return (copyandmerge(he1, NULL, af, error_num));
+}
+
+void
+freehostent(struct hostent *he) {
+ char **cpp;
+ int names = 1;
+ int addresses = 1;
+
+ memput(he->h_name, strlen(he->h_name) + 1);
+
+ cpp = he->h_addr_list;
+ while (*cpp != NULL) {
+ memput(*cpp, (he->h_addrtype == AF_INET) ?
+ INADDRSZ : IN6ADDRSZ);
+ *cpp = NULL;
+ cpp++;
+ addresses++;
+ }
+
+ cpp = he->h_aliases;
+ while (*cpp != NULL) {
+ memput(*cpp, strlen(*cpp) + 1);
+ cpp++;
+ names++;
+ }
+
+ memput(he->h_aliases, sizeof(char *) * (names));
+ memput(he->h_addr_list, sizeof(char *) * (addresses));
+ memput(he, sizeof *he);
+}
+
+/*
+ * Private
+ */
+
+/*
+ * Scan the interface table and set have_v4 and have_v6 depending
+ * upon whether there are IPv4 and IPv6 interface addresses.
+ *
+ * Returns:
+ * 0 on success
+ * -1 on failure.
+ */
+
+static int
+scan_interfaces(int *have_v4, int *have_v6) {
+ struct ifconf ifc;
+ struct ifreq ifreq;
+ struct in_addr in4;
+ struct in6_addr in6;
+ char *buf = NULL, *cp, *cplim;
+ static int bufsiz = 4095;
+ int s, cpsize, n;
+
+ /* Set to zero. Used as loop terminators below. */
+ *have_v4 = *have_v6 = 0;
+
+ /* Get interface list from system. */
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ goto err_ret;
+
+ /*
+ * Grow buffer until large enough to contain all interface
+ * descriptions.
+ */
+ for (;;) {
+ buf = memget(bufsiz);
+ if (buf == NULL)
+ goto err_ret;
+ ifc.ifc_len = bufsiz;
+ ifc.ifc_buf = buf;
+#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
+ /*
+ * This is a fix for IRIX OS in which the call to ioctl with
+ * the flag SIOCGIFCONF may not return an entry for all the
+ * interfaces like most flavors of Unix.
+ */
+ if (emul_ioctl(&ifc) >= 0)
+ break;
+#else
+ if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) {
+ /*
+ * Some OS's just return what will fit rather
+ * than set EINVAL if the buffer is too small
+ * to fit all the interfaces in. If
+ * ifc.ifc_len is too near to the end of the
+ * buffer we will grow it just in case and
+ * retry.
+ */
+ if (ifc.ifc_len + 2 * sizeof(ifreq) < bufsiz)
+ break;
+ }
+#endif
+ if ((n == -1) && errno != EINVAL)
+ goto err_ret;
+
+ if (bufsiz > 1000000)
+ goto err_ret;
+
+ memput(buf, bufsiz);
+ bufsiz += 4096;
+ }
+
+ /* Parse system's interface list. */
+ cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */
+ for (cp = buf;
+ (*have_v4 == 0 || *have_v6 == 0) && cp < cplim;
+ cp += cpsize) {
+ memcpy(&ifreq, cp, sizeof ifreq);
+#ifdef HAVE_SA_LEN
+#ifdef FIX_ZERO_SA_LEN
+ if (ifreq.ifr_addr.sa_len == 0)
+ ifreq.ifr_addr.sa_len = 16;
+#endif
+#ifdef HAVE_MINIMUM_IFREQ
+ cpsize = sizeof ifreq;
+ if (ifreq.ifr_addr.sa_len > sizeof (struct sockaddr))
+ cpsize += (int)ifreq.ifr_addr.sa_len -
+ (int)(sizeof (struct sockaddr));
+#else
+ cpsize = sizeof ifreq.ifr_name + ifreq.ifr_addr.sa_len;
+#endif /* HAVE_MINIMUM_IFREQ */
+#elif defined SIOCGIFCONF_ADDR
+ cpsize = sizeof ifreq;
+#else
+ cpsize = sizeof ifreq.ifr_name;
+ /* XXX maybe this should be a hard error? */
+ if (ioctl(s, SIOCGIFADDR, (char *)&ifreq) < 0)
+ continue;
+#endif
+ switch (ifreq.ifr_addr.sa_family) {
+ case AF_INET:
+ if (*have_v4 == 0) {
+ memcpy(&in4,
+ &((struct sockaddr_in *)
+ &ifreq.ifr_addr)->sin_addr, sizeof in4);
+ if (in4.s_addr == INADDR_ANY)
+ break;
+ n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq);
+ if (n < 0)
+ break;
+ if ((ifreq.ifr_flags & IFF_UP) == 0)
+ break;
+ *have_v4 = 1;
+ }
+ break;
+ case AF_INET6:
+ if (*have_v6 == 0) {
+ memcpy(&in6,
+ &((struct sockaddr_in6 *)
+ &ifreq.ifr_addr)->sin6_addr, sizeof in6);
+ if (memcmp(&in6, &in6addr_any, sizeof in6) == 0)
+ break;
+ n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq);
+ if (n < 0)
+ break;
+ if ((ifreq.ifr_flags & IFF_UP) == 0)
+ break;
+ *have_v6 = 1;
+ }
+ break;
+ }
+ }
+ if (buf != NULL)
+ memput(buf, bufsiz);
+ close(s);
+ return (0);
+ err_ret:
+ if (buf != NULL)
+ memput(buf, bufsiz);
+ if (s != -1)
+ close(s);
+ return (-1);
+}
+
+static struct hostent *
+copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num) {
+ struct hostent *he = NULL;
+ int addresses = 1; /* NULL terminator */
+ int names = 1; /* NULL terminator */
+ int len = 0;
+ char **cpp, **npp;
+
+ /*
+ * Work out array sizes;
+ */
+ if (he1 != NULL) {
+ cpp = he1->h_addr_list;
+ while (*cpp != NULL) {
+ addresses++;
+ cpp++;
+ }
+ cpp = he1->h_aliases;
+ while (*cpp != NULL) {
+ names++;
+ cpp++;
+ }
+ }
+
+ if (he2 != NULL) {
+ cpp = he2->h_addr_list;
+ while (*cpp != NULL) {
+ addresses++;
+ cpp++;
+ }
+ if (he1 == NULL) {
+ cpp = he2->h_aliases;
+ while (*cpp != NULL) {
+ names++;
+ cpp++;
+ }
+ }
+ }
+
+ if (addresses == 1) {
+ *error_num = NO_ADDRESS;
+ return (NULL);
+ }
+
+ he = memget(sizeof *he);
+ if (he == NULL)
+ goto no_recovery;
+
+ he->h_addr_list = memget(sizeof(char *) * (addresses));
+ if (he->h_addr_list == NULL)
+ goto cleanup0;
+ memset(he->h_addr_list, 0, sizeof(char *) * (addresses));
+
+ /* copy addresses */
+ npp = he->h_addr_list;
+ if (he1 != NULL) {
+ cpp = he1->h_addr_list;
+ while (*cpp != NULL) {
+ *npp = memget((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ if (*npp == NULL)
+ goto cleanup1;
+ /* convert to mapped if required */
+ if (af == AF_INET6 && he1->h_addrtype == AF_INET) {
+ memcpy(*npp, in6addr_mapped,
+ sizeof in6addr_mapped);
+ memcpy(*npp + sizeof in6addr_mapped, *cpp,
+ INADDRSZ);
+ } else {
+ memcpy(*npp, *cpp,
+ (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ }
+ cpp++;
+ npp++;
+ }
+ }
+
+ if (he2 != NULL) {
+ cpp = he2->h_addr_list;
+ while (*cpp != NULL) {
+ *npp = memget((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ if (*npp == NULL)
+ goto cleanup1;
+ /* convert to mapped if required */
+ if (af == AF_INET6 && he2->h_addrtype == AF_INET) {
+ memcpy(*npp, in6addr_mapped,
+ sizeof in6addr_mapped);
+ memcpy(*npp + sizeof in6addr_mapped, *cpp,
+ INADDRSZ);
+ } else {
+ memcpy(*npp, *cpp,
+ (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ }
+ cpp++;
+ npp++;
+ }
+ }
+
+ he->h_aliases = memget(sizeof(char *) * (names));
+ if (he->h_aliases == NULL)
+ goto cleanup1;
+ memset(he->h_aliases, 0, sizeof(char *) * (names));
+
+ /* copy aliases */
+ npp = he->h_aliases;
+ cpp = (he1 != NULL) ? he1->h_aliases : he2->h_aliases;
+ while (*cpp != NULL) {
+ len = strlen (*cpp) + 1;
+ *npp = memget(len);
+ if (*npp == NULL)
+ goto cleanup2;
+ strcpy(*npp, *cpp);
+ npp++;
+ cpp++;
+ }
+
+ /* copy hostname */
+ he->h_name = memget(strlen((he1 != NULL) ?
+ he1->h_name : he2->h_name) + 1);
+ if (he->h_name == NULL)
+ goto cleanup2;
+ strcpy(he->h_name, (he1 != NULL) ? he1->h_name : he2->h_name);
+
+ /* set address type and length */
+ he->h_addrtype = af;
+ he->h_length = (af == AF_INET) ? INADDRSZ : IN6ADDRSZ;
+ return(he);
+
+ cleanup2:
+ cpp = he->h_aliases;
+ while (*cpp != NULL) {
+ memput(*cpp, strlen(*cpp) + 1);
+ cpp++;
+ }
+ memput(he->h_aliases, sizeof(char *) * (names));
+
+ cleanup1:
+ cpp = he->h_addr_list;
+ while (*cpp != NULL) {
+ memput(*cpp, (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ *cpp = NULL;
+ cpp++;
+ }
+ memput(he->h_addr_list, sizeof(char *) * (addresses));
+
+ cleanup0:
+ memput(he, sizeof *he);
+
+ no_recovery:
+ *error_num = NO_RECOVERY;
+ return (NULL);
+}
+
+static struct net_data *
+init() {
+ struct net_data *net_data;
+
+ if (!(net_data = net_data_init(NULL)))
+ goto error;
+ if (!net_data->ho) {
+ net_data->ho = (*net_data->irs->ho_map)(net_data->irs);
+ if (!net_data->ho || !net_data->res) {
+ error:
+ errno = EIO;
+ if (net_data && net_data->res)
+ RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
+ return (NULL);
+ }
+
+ (*net_data->ho->res_set)(net_data->ho, net_data->res, NULL);
+ }
+
+ return (net_data);
}
static void
-freepvt() {
- if (net_data.ho_data) {
- free(net_data.ho_data);
- net_data.ho_data = NULL;
+freepvt(struct net_data *net_data) {
+ if (net_data->ho_data) {
+ free(net_data->ho_data);
+ net_data->ho_data = NULL;
}
}
static struct hostent *
-fakeaddr(const char *name, int af) {
+fakeaddr(const char *name, int af, struct net_data *net_data) {
struct pvt *pvt;
- const char *cp;
- freepvt();
- net_data.ho_data = malloc(sizeof(struct pvt));
- if (!net_data.ho_data) {
+ freepvt(net_data);
+ net_data->ho_data = malloc(sizeof (struct pvt));
+ if (!net_data->ho_data) {
errno = ENOMEM;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
return (NULL);
}
- pvt = net_data.ho_data;
+ pvt = net_data->ho_data;
/*
- * Unlike its forebear (inet_aton), our friendly inet_pton() is strict
+ * Unlike its forebear(inet_aton), our friendly inet_pton() is strict
* in its interpretation of its input, and it will only return "1" if
- * the input string is a formally valid (and thus unambiguous with
+ * the input string is a formally valid(and thus unambiguous with
* respect to host names) internet address specification for this AF.
*
* This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now.
*/
if (inet_pton(af, name, pvt->addr) != 1) {
- h_errno = HOST_NOT_FOUND;
+ RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
return (NULL);
}
strncpy(pvt->name, name, NS_MAXDNAME);
pvt->name[NS_MAXDNAME] = '\0';
+ if (af == AF_INET && (net_data->res->options & RES_USE_INET6) != 0) {
+ map_v4v6_address(pvt->addr, pvt->addr);
+ af = AF_INET6;
+ }
pvt->host.h_addrtype = af;
- switch (af) {
+ switch(af) {
case AF_INET:
pvt->host.h_length = NS_INADDRSZ;
break;
@@ -215,7 +812,7 @@ fakeaddr(const char *name, int af) {
break;
default:
errno = EAFNOSUPPORT;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
return (NULL);
}
pvt->host.h_name = pvt->name;
@@ -224,9 +821,7 @@ fakeaddr(const char *name, int af) {
pvt->addrs[0] = (char *)pvt->addr;
pvt->addrs[1] = NULL;
pvt->host.h_addr_list = pvt->addrs;
- if (af == AF_INET && (_res.options & RES_USE_INET6))
- map_v4v6_address(pvt->addr, pvt->addr);
- h_errno = NETDB_SUCCESS;
+ RES_SET_H_ERRNO(net_data->res, NETDB_SUCCESS);
return (&pvt->host);
}
@@ -243,21 +838,23 @@ fakeaddr(const char *name, int af) {
*/
strncpy(hname2, hp->h_name, MAXDNAME);
hname2[MAXDNAME] = '\0';
- old_options = _res.options;
- _res.options &= ~RES_DNSRCH;
- _res.options |= RES_DEFNAMES;
+ old_options = net_data->res->options;
+ net_data->res->options &= ~RES_DNSRCH;
+ net_data->res->options |= RES_DEFNAMES;
if (!(rhp = gethostbyname(hname2))) {
- _res.options = old_options;
- h_errno = HOST_NOT_FOUND;
+ net_data->res->options = old_options;
+ RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
return (NULL);
}
- _res.options = old_options;
+ net_data->res->options = old_options;
for (haddr = rhp->h_addr_list; *haddr; haddr++)
if (!memcmp(*haddr, addr, INADDRSZ))
break;
if (!*haddr) {
- h_errno = HOST_NOT_FOUND;
+ RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
return (NULL);
}
}
#endif /* grot */
+
+#endif /*__BIND_NOSTATIC*/
diff --git a/contrib/bind/lib/irs/gethostent_r.c b/contrib/bind/lib/irs/gethostent_r.c
new file mode 100644
index 0000000..5da1a96
--- /dev/null
+++ b/contrib/bind/lib/irs/gethostent_r.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 1998-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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: gethostent_r.c,v 8.4 1999/01/18 07:46:52 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <port_before.h>
+#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
+ static int gethostent_r_not_required = 0;
+#else
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <port_after.h>
+
+#ifdef HOST_R_RETURN
+
+static HOST_R_RETURN
+copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS);
+
+HOST_R_RETURN
+gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) {
+ struct hostent *he = gethostbyname(name);
+
+ HOST_R_ERRNO;
+
+ if (he == NULL)
+ return (HOST_R_BAD);
+
+ return (copy_hostent(he, hptr, HOST_R_COPY));
+}
+
+HOST_R_RETURN
+gethostbyaddr_r(const char *addr, int len, int type,
+ struct hostent *hptr, HOST_R_ARGS) {
+ struct hostent *he = gethostbyaddr(addr, len, type);
+
+ HOST_R_ERRNO;
+
+ if (he == NULL)
+ return (HOST_R_BAD);
+
+ return (copy_hostent(he, hptr, HOST_R_COPY));
+}
+
+/*
+ * These assume a single context is in operation per thread.
+ * If this is not the case we will need to call irs directly
+ * rather than through the base functions.
+ */
+
+HOST_R_RETURN
+gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
+ struct hostent *he = gethostent();
+
+ HOST_R_ERRNO;
+
+ if (he == NULL)
+ return (HOST_R_BAD);
+
+ return (copy_hostent(he, hptr, HOST_R_COPY));
+}
+
+HOST_R_SET_RETURN
+#ifdef HOST_R_ENT_ARGS
+sethostent_r(int stay_open, HOST_R_ENT_ARGS)
+#else
+sethostent_r(int stay_open)
+#endif
+{
+ sethostent(stay_open);
+#ifdef HOST_R_SET_RESULT
+ return (HOST_R_SET_RESULT);
+#endif
+}
+
+HOST_R_END_RETURN
+#ifdef HOST_R_ENT_ARGS
+endhostent_r(HOST_R_ENT_ARGS)
+#else
+endhostent_r()
+#endif
+{
+ endhostent();
+ HOST_R_END_RESULT(HOST_R_OK);
+}
+
+/* Private */
+
+#ifndef HOSTENT_DATA
+static HOST_R_RETURN
+copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
+ char *cp;
+ char **ptr;
+ int i, n;
+ int nptr, len;
+
+ /* Find out the amount of space required to store the answer. */
+ nptr = 2; /* NULL ptrs */
+ len = (char *)ALIGN(buf) - buf;
+ for (i = 0; he->h_addr_list[i]; i++, nptr++) {
+ len += he->h_length;
+ }
+ for (i = 0; he->h_aliases[i]; i++, nptr++) {
+ len += strlen(he->h_aliases[i]) + 1;
+ }
+ len += strlen(he->h_name) + 1;
+ len += nptr * sizeof(char*);
+
+ if (len > buflen) {
+ errno = ERANGE;
+ return (HOST_R_BAD);
+ }
+
+ /* copy address size and type */
+ hptr->h_addrtype = he->h_addrtype;
+ n = hptr->h_length = he->h_length;
+
+ ptr = (char **)ALIGN(buf);
+ cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
+
+ /* copy address list */
+ hptr->h_addr_list = ptr;
+ for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
+ memcpy(cp, he->h_addr_list[i], n);
+ hptr->h_addr_list[i] = cp;
+ cp += n;
+ i++;
+ }
+ hptr->h_addr_list[i] = NULL;
+ ptr++;
+
+ /* copy official name */
+ n = strlen(he->h_name) + 1;
+ strcpy(cp, he->h_name);
+ hptr->h_name = cp;
+ cp += n;
+
+ /* copy aliases */
+ hptr->h_aliases = ptr;
+ for (i = 0 ; he->h_aliases[i]; i++) {
+ n = strlen(he->h_aliases[i]) + 1;
+ strcpy(cp, he->h_aliases[i]);
+ hptr->h_aliases[i] = cp;
+ cp += n;
+ }
+ hptr->h_aliases[i] = NULL;
+
+ return (HOST_R_OK);
+}
+#else /* !HOSTENT_DATA */
+static int
+copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
+ char *cp, *eob;
+ int i, n;
+
+ /* copy address size and type */
+ hptr->h_addrtype = he->h_addrtype;
+ n = hptr->h_length = he->h_length;
+
+ /* copy up to first 35 addresses */
+ i = 0;
+ cp = hdptr->hostaddr;
+ eob = hdptr->hostaddr + sizeof(hdptr->hostaddr);
+ hptr->h_addr_list = hdptr->h_addr_ptrs;
+ while (he->h_addr_list[i] && i < (_MAXADDRS)) {
+ if (n < (eob - cp)) {
+ memcpy(cp, he->h_addr_list[i], n);
+ hptr->h_addr_list[i] = cp;
+ cp += n;
+ } else {
+ break;
+ }
+ i++;
+ }
+ hptr->h_addr_list[i] = NULL;
+
+ /* copy official name */
+ cp = hdptr->hostbuf;
+ eob = hdptr->hostbuf + sizeof(hdptr->hostbuf);
+ if ((n = strlen(he->h_name) + 1) < (eob - cp)) {
+ strcpy(cp, he->h_name);
+ hptr->h_name = cp;
+ cp += n;
+ } else {
+ return (-1);
+ }
+
+ /* copy aliases */
+ i = 0;
+ hptr->h_aliases = hdptr->host_aliases;
+ while (he->h_aliases[i] && i < (_MAXALIASES-1)) {
+ if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) {
+ strcpy(cp, he->h_aliases[i]);
+ hptr->h_aliases[i] = cp;
+ cp += n;
+ } else {
+ break;
+ }
+ i++;
+ }
+ hptr->h_aliases[i] = NULL;
+
+ return (HOST_R_OK);
+}
+#endif /* !HOSTENT_DATA */
+#else /* HOST_R_RETURN */
+ static int gethostent_r_unknown_systemm = 0;
+#endif /* HOST_R_RETURN */
+#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
diff --git a/contrib/bind/lib/irs/getnameinfo.c b/contrib/bind/lib/irs/getnameinfo.c
new file mode 100644
index 0000000..3157c66
--- /dev/null
+++ b/contrib/bind/lib/irs/getnameinfo.c
@@ -0,0 +1,230 @@
+/*
+ * Issues to be discussed:
+ * - Thread safe-ness must be checked
+ * - Return values. There seems to be no standard for return value (RFC2133)
+ * but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by WIDE Project and
+ * its contributors.
+ * 4. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <port_before.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+
+#include <port_after.h>
+
+#define SUCCESS 0
+#define ANY 0
+#define YES 1
+#define NO 0
+
+/*
+ * Note that a_off will be dynamically adjusted so that to be consistent
+ * with the definition of sockaddr_in{,6}.
+ * The value presented below is just a guess.
+ */
+static struct afd {
+ int a_af;
+ int a_addrlen;
+ int a_socklen;
+ int a_off;
+} afdl [] = {
+ /* first entry is linked last... */
+ {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
+ 4 /*XXX*/},
+ {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
+ 8 /*XXX*/},
+ {0, 0, 0},
+};
+
+struct sockinet {
+ u_char si_len;
+ u_char si_family;
+ u_short si_port;
+};
+
+#define ENI_NOSOCKET 0
+#define ENI_NOSERVNAME 1
+#define ENI_NOHOSTNAME 2
+#define ENI_MEMORY 3
+#define ENI_SYSTEM 4
+#define ENI_FAMILY 5
+#define ENI_SALEN 6
+
+int
+getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
+ const struct sockaddr *sa;
+ size_t salen;
+ char *host;
+ size_t hostlen;
+ char *serv;
+ size_t servlen;
+ int flags;
+{
+ struct afd *afd;
+ struct servent *sp;
+ struct hostent *hp;
+ u_short port;
+#ifdef HAVE_SA_LEN
+ int len;
+#endif
+ int family, i;
+ char *addr, *p;
+ u_long v4a;
+ u_char pfx;
+ static int firsttime = 1;
+ static char numserv[512];
+ static char numaddr[512];
+
+
+ /* dynamically adjust a_off */
+ if (firsttime) {
+ struct afd *p;
+ u_char *q;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+
+ for (p = &afdl[0]; p->a_af; p++) {
+ switch (p->a_af) {
+ case PF_INET:
+ q = (u_char *)&sin.sin_addr.s_addr;
+ p->a_off = q - (u_char *)&sin;
+ break;
+ case PF_INET6:
+ q = (u_char *)&sin6.sin6_addr.s6_addr;
+ p->a_off = q - (u_char *)&sin6;
+ break;
+ default:
+ break;
+ }
+ }
+ firsttime = 0;
+ }
+
+ if (sa == NULL)
+ return ENI_NOSOCKET;
+
+#ifdef HAVE_SA_LEN
+ len = sa->sa_len;
+ if (len != salen) return ENI_SALEN;
+#endif
+
+ family = sa->sa_family;
+ for (i = 0; afdl[i].a_af; i++)
+ if (afdl[i].a_af == family) {
+ afd = &afdl[i];
+ goto found;
+ }
+ return ENI_FAMILY;
+
+ found:
+ if (salen != afd->a_socklen) return ENI_SALEN;
+
+ port = ((struct sockinet *)sa)->si_port; /* network byte order */
+ addr = (char *)sa + afd->a_off;
+
+ if (serv == NULL || servlen == 0) {
+ /* what we should do? */
+ } else if (flags & NI_NUMERICSERV) {
+ snprintf(numserv, strlen(numserv), "%d", ntohs(port));
+ if (strlen(numserv) > servlen)
+ return ENI_MEMORY;
+ strcpy(serv, numserv);
+ } else {
+ sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
+ if (sp) {
+ if (strlen(sp->s_name) > servlen)
+ return ENI_MEMORY;
+ strcpy(serv, sp->s_name);
+ } else
+ return ENI_NOSERVNAME;
+ }
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ flags |= NI_NUMERICHOST;
+ v4a >>= IN_CLASSA_NSHIFT;
+ if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ flags |= NI_NUMERICHOST;
+ break;
+ case AF_INET6:
+ pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0];
+ if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ flags |= NI_NUMERICHOST;
+ break;
+ }
+ if (host == NULL || hostlen == 0) {
+ /* what should we do? */
+ } else if (flags & NI_NUMERICHOST) {
+ if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ return ENI_SYSTEM;
+ if (strlen(numaddr) > hostlen)
+ return ENI_MEMORY;
+ strcpy(host, numaddr);
+ } else {
+ hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
+
+ if (hp) {
+ if (flags & NI_NOFQDN) {
+ p = strchr(hp->h_name, '.');
+ if (p) *p = '\0';
+ }
+ if (strlen(hp->h_name) > hostlen)
+ return ENI_MEMORY;
+ strcpy(host, hp->h_name);
+ } else {
+ if (flags & NI_NAMEREQD)
+ return ENI_NOHOSTNAME;
+ if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ return ENI_NOHOSTNAME;
+ if (strlen(numaddr) > hostlen)
+ return ENI_MEMORY;
+ strcpy(host, numaddr);
+ }
+ }
+ return SUCCESS;
+}
diff --git a/contrib/bind/lib/irs/getnetent.c b/contrib/bind/lib/irs/getnetent.c
index 17132f6..b63ddaf 100644
--- a/contrib/bind/lib/irs/getnetent.c
+++ b/contrib/bind/lib/irs/getnetent.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,15 +16,18 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: getnetent.c,v 1.10 1997/12/04 04:57:53 halley Exp $";
+static const char rcsid[] = "$Id: getnetent.c,v 1.17 1999/10/13 16:39:30 vixie Exp $";
#endif
/* Imports */
#include "port_before.h"
+#if !defined(__BIND_NOSTATIC)
+
#include <sys/types.h>
#include <sys/socket.h>
+
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
@@ -32,6 +35,7 @@ static char rcsid[] = "$Id: getnetent.c,v 1.10 1997/12/04 04:57:53 halley Exp $"
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
+#include <resolv.h>
#include <stdlib.h>
#include <string.h>
@@ -52,10 +56,10 @@ struct pvt {
/* Forward */
-static struct irs_nw * init(void);
-static struct netent * nw_to_net(struct nwent *);
-static void freepvt(void);
-static struct netent * fakeaddr(const char *, int af);
+static struct net_data *init(void);
+static struct netent *nw_to_net(struct nwent *, struct net_data *);
+static void freepvt(struct net_data *);
+static struct netent *fakeaddr(const char *, int af, struct net_data *);
/* Portability */
@@ -67,118 +71,182 @@ static struct netent * fakeaddr(const char *, int af);
struct netent *
getnetent() {
- struct irs_nw *nw = init();
-
- if (!nw)
- return (NULL);
- net_data.nw_last = nw_to_net((*nw->next)(nw));
- return (net_data.nw_last);
+ struct net_data *net_data = init();
+
+ return (getnetent_p(net_data));
}
struct netent *
getnetbyname(const char *name) {
- struct irs_nw *nw = init();
+ struct net_data *net_data = init();
+
+ return (getnetbyname_p(name, net_data));
+}
+
+struct netent *
+getnetbyaddr(unsigned long net, int type) {
+ struct net_data *net_data = init();
+
+ return (getnetbyaddr_p(net, type, net_data));
+}
+
+void
+setnetent(int stayopen) {
+ struct net_data *net_data = init();
+
+ setnetent_p(stayopen, net_data);
+}
+
+
+void
+endnetent() {
+ struct net_data *net_data = init();
+
+ endnetent_p(net_data);
+}
+
+/* Shared private. */
+
+struct netent *
+getnetent_p(struct net_data *net_data) {
+ struct irs_nw *nw;
+
+ if (!net_data || !(nw = net_data->nw))
+ return (NULL);
+ net_data->nww_last = (*nw->next)(nw);
+ net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
+ return (net_data->nw_last);
+}
+
+struct netent *
+getnetbyname_p(const char *name, struct net_data *net_data) {
+ struct irs_nw *nw;
struct netent *np;
char **nap;
-
- if (!nw)
+
+ if (!net_data || !(nw = net_data->nw))
return (NULL);
- if (net_data.nw_stayopen && net_data.nw_last) {
- if (!strcmp(net_data.nw_last->n_name, name))
- return (net_data.nw_last);
- for (nap = net_data.nw_last->n_aliases; nap && *nap; nap++)
+ if (net_data->nw_stayopen && net_data->nw_last) {
+ if (!strcmp(net_data->nw_last->n_name, name))
+ return (net_data->nw_last);
+ for (nap = net_data->nw_last->n_aliases; nap && *nap; nap++)
if (!strcmp(name, *nap))
- return (net_data.nw_last);
+ return (net_data->nw_last);
}
- if ((np = fakeaddr(name, AF_INET)) != NULL)
+ if ((np = fakeaddr(name, AF_INET, net_data)) != NULL)
return (np);
- net_data.nw_last = nw_to_net((*nw->byname)(nw, name, AF_INET));
- if (!net_data.nw_stayopen)
+ net_data->nww_last = (*nw->byname)(nw, name, AF_INET);
+ net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
+ if (!net_data->nw_stayopen)
endnetent();
- return (net_data.nw_last);
+ return (net_data->nw_last);
}
struct netent *
-getnetbyaddr(unsigned long net, int type) {
- struct irs_nw *nw = init();
+getnetbyaddr_p(unsigned long net, int type, struct net_data *net_data) {
+ struct irs_nw *nw;
u_char addr[4];
int bits;
-
- if (!nw)
+
+ if (!net_data || !(nw = net_data->nw))
return (NULL);
- if (net_data.nw_stayopen && net_data.nw_last)
- if (type == net_data.nw_last->n_addrtype &&
- net == net_data.nw_last->n_net)
- return (net_data.nw_last);
-
- addr[3] = (0xFF000000 & net) >> 24;
- addr[2] = (0x00FF0000 & net) >> 16;
- addr[1] = (0x0000FF00 & net) >> 8;
- addr[0] = (0x000000FF & net);
-
- /* Use the old class rules to figure out the network bits. */
- if (addr[3] >= 240)
- bits = 32;
- else if (addr[3] >= 224)
- bits = 4;
- else if (addr[3] >= 192)
- bits = 24;
- else if (addr[3] >= 128)
- bits = 16;
- else
+ if (net_data->nw_stayopen && net_data->nw_last)
+ if (type == net_data->nw_last->n_addrtype &&
+ net == net_data->nw_last->n_net)
+ return (net_data->nw_last);
+
+ /* cannonize net(host order) */
+ if (net < 256) {
+ net <<= 24;
bits = 8;
-
- net_data.nw_last = nw_to_net((*nw->byaddr)(nw, addr, bits, AF_INET));
- if (!net_data.nw_stayopen)
+ } else if (net < 65536) {
+ net <<= 16;
+ bits = 16;
+ } else if (net < 16777216) {
+ net <<= 8;
+ bits = 24;
+ } else
+ bits = 32;
+
+ /* convert to net order */
+ addr[0] = (0xFF000000 & net) >> 24;
+ addr[1] = (0x00FF0000 & net) >> 16;
+ addr[2] = (0x0000FF00 & net) >> 8;
+ addr[3] = (0x000000FF & net);
+
+ /* reduce bits to as close to natural number as possible */
+ if ((bits == 32) && (addr[0] < 224) && (addr[3] == 0))
+ if ((addr[0] < 192) && (addr[2] == 0))
+ if ((addr[0] < 128) && (addr[1] == 0))
+ bits = 8;
+ else
+ bits = 16;
+ else
+ bits = 24;
+
+ net_data->nww_last = (*nw->byaddr)(nw, addr, bits, AF_INET);
+ net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
+ if (!net_data->nw_stayopen)
endnetent();
- return (net_data.nw_last);
+ return (net_data->nw_last);
}
+
+
+
void
-setnetent(int stayopen) {
- struct irs_nw *nw = init();
-
- if (!nw)
+setnetent_p(int stayopen, struct net_data *net_data) {
+ struct irs_nw *nw;
+
+ if (!net_data || !(nw = net_data->nw))
return;
- freepvt();
+ freepvt(net_data);
(*nw->rewind)(nw);
- net_data.nw_stayopen = (stayopen != 0);
+ net_data->nw_stayopen = (stayopen != 0);
+ if (stayopen == 0)
+ net_data_minimize(net_data);
}
void
-endnetent() {
- struct irs_nw *nw = init();
+endnetent_p(struct net_data *net_data) {
+ struct irs_nw *nw;
- if (nw != NULL)
+ if ((net_data != NULL) && ((nw = net_data->nw) != NULL))
(*nw->minimize)(nw);
}
/* Private */
-static struct irs_nw *
+static struct net_data *
init() {
- if (!net_data_init())
+ struct net_data *net_data;
+
+ if (!(net_data = net_data_init(NULL)))
goto error;
- if (!net_data.nw)
- net_data.nw = (*net_data.irs->nw_map)(net_data.irs);
- if (!net_data.nw) {
+ if (!net_data->nw) {
+ net_data->nw = (*net_data->irs->nw_map)(net_data->irs);
+
+ if (!net_data->nw || !net_data->res) {
error:
- errno = EIO;
- return (NULL);
+ errno = EIO;
+ return (NULL);
+ }
+ (*net_data->nw->res_set)(net_data->nw, net_data->res, NULL);
}
- return (net_data.nw);
+
+ return (net_data);
}
static void
-freepvt() {
- if (net_data.nw_data) {
- free(net_data.nw_data);
- net_data.nw_data = NULL;
+freepvt(struct net_data *net_data) {
+ if (net_data->nw_data) {
+ free(net_data->nw_data);
+ net_data->nw_data = NULL;
}
}
static struct netent *
-fakeaddr(const char *name, int af) {
+fakeaddr(const char *name, int af, struct net_data *net_data) {
struct pvt *pvt;
const char *cp;
u_long tmp;
@@ -186,7 +254,7 @@ fakeaddr(const char *name, int af) {
if (af != AF_INET) {
/* XXX should support IPv6 some day */
errno = EAFNOSUPPORT;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
return (NULL);
}
if (!isascii(name[0]) || !isdigit(name[0]))
@@ -201,7 +269,7 @@ fakeaddr(const char *name, int af) {
tmp = inet_network(name);
if (tmp == INADDR_NONE) {
- h_errno = HOST_NOT_FOUND;
+ RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
return (NULL);
}
@@ -209,14 +277,14 @@ fakeaddr(const char *name, int af) {
* Fake up a netent as if we'd actually
* done a lookup.
*/
- freepvt();
- net_data.nw_data = malloc(sizeof(struct pvt));
- if (!net_data.nw_data) {
+ freepvt(net_data);
+ net_data->nw_data = malloc(sizeof (struct pvt));
+ if (!net_data->nw_data) {
errno = ENOMEM;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
return (NULL);
}
- pvt = net_data.nw_data;
+ pvt = net_data->nw_data;
strncpy(pvt->name, name, MAXDNAME);
pvt->name[MAXDNAME] = '\0';
@@ -230,29 +298,29 @@ fakeaddr(const char *name, int af) {
}
static struct netent *
-nw_to_net(struct nwent *nwent) {
+nw_to_net(struct nwent *nwent, struct net_data *net_data) {
struct pvt *pvt;
u_long addr = 0;
- int i;
+ int i;
int msbyte;
if (!nwent || nwent->n_addrtype != AF_INET)
return (NULL);
- freepvt();
- net_data.nw_data = malloc(sizeof(struct pvt));
- if (!net_data.nw_data) {
+ freepvt(net_data);
+ net_data->nw_data = malloc(sizeof (struct pvt));
+ if (!net_data->nw_data) {
errno = ENOMEM;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
return (NULL);
}
- pvt = net_data.nw_data;
+ pvt = net_data->nw_data;
pvt->netent.n_name = nwent->n_name;
pvt->netent.n_aliases = nwent->n_aliases;
pvt->netent.n_addrtype = nwent->n_addrtype;
-
+
/*
* What this code does: Converts net addresses from network to host form.
- *
+ *
* msbyte: the index of the most significant byte in the n_addr array.
*
* Shift bytes in significant order into addr. When all signicant
@@ -269,4 +337,4 @@ nw_to_net(struct nwent *nwent) {
return (&pvt->netent);
}
-
+#endif /*__BIND_NOSTATIC*/
diff --git a/contrib/bind/lib/irs/getnetent_r.c b/contrib/bind/lib/irs/getnetent_r.c
new file mode 100644
index 0000000..b78b45a
--- /dev/null
+++ b/contrib/bind/lib/irs/getnetent_r.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1998-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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: getnetent_r.c,v 8.4 1999/01/18 07:46:52 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <port_before.h>
+#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
+ static int getnetent_r_not_required = 0;
+#else
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <port_after.h>
+
+#ifdef NET_R_RETURN
+
+static NET_R_RETURN
+copy_netent(struct netent *, struct netent *, NET_R_COPY_ARGS);
+
+NET_R_RETURN
+getnetbyname_r(const char *name, struct netent *nptr, NET_R_ARGS) {
+ struct netent *ne = getnetbyname(name);
+
+ if (ne == NULL)
+ return (NET_R_BAD);
+
+ return (copy_netent(ne, nptr, NET_R_COPY));
+}
+
+#ifndef GETNETBYADDR_ADDR_T
+#define GETNETBYADDR_ADDR_T long
+#endif
+NET_R_RETURN
+getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_ARGS) {
+ struct netent *ne = getnetbyaddr(addr, type);
+
+ if (ne == NULL)
+ return (NET_R_BAD);
+
+ return (copy_netent(ne, nptr, NET_R_COPY));
+}
+
+/*
+ * These assume a single context is in operation per thread.
+ * If this is not the case we will need to call irs directly
+ * rather than through the base functions.
+ */
+
+NET_R_RETURN
+getnetent_r(struct netent *nptr, NET_R_ARGS) {
+ struct netent *ne = getnetent();
+
+ if (ne == NULL)
+ return (NET_R_BAD);
+
+ return (copy_netent(ne, nptr, NET_R_COPY));
+}
+
+NET_R_SET_RETURN
+#ifdef NET_R_ENT_ARGS
+setnetent_r(int stay_open, NET_R_ENT_ARGS)
+#else
+setnetent_r(int stay_open)
+#endif
+{
+ setnetent(stay_open);
+#ifdef NET_R_SET_RESULT
+ return (NET_R_SET_RESULT);
+#endif
+}
+
+NET_R_END_RETURN
+#ifdef NET_R_ENT_ARGS
+endnetent_r(NET_R_ENT_ARGS)
+#else
+endnetent_r()
+#endif
+{
+ endnetent();
+ NET_R_END_RESULT(NET_R_OK);
+}
+
+/* Private */
+
+#ifndef NETENT_DATA
+static NET_R_RETURN
+copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
+ char *cp;
+ int i, n;
+ int numptr, len;
+
+ /* Find out the amount of space required to store the answer. */
+ numptr = 1; /* NULL ptr */
+ len = (char *)ALIGN(buf) - buf;
+ for (i = 0; ne->n_aliases[i]; i++, numptr++) {
+ len += strlen(ne->n_aliases[i]) + 1;
+ }
+ len += strlen(ne->n_name) + 1;
+ len += numptr * sizeof(char*);
+
+ if (len > buflen) {
+ errno = ERANGE;
+ return (NET_R_BAD);
+ }
+
+ /* copy net value and type */
+ nptr->n_addrtype = ne->n_addrtype;
+ nptr->n_net = ne->n_net;
+
+ cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
+
+ /* copy official name */
+ n = strlen(ne->n_name) + 1;
+ strcpy(cp, ne->n_name);
+ nptr->n_name = cp;
+ cp += n;
+
+ /* copy aliases */
+ nptr->n_aliases = (char **)ALIGN(buf);
+ for (i = 0 ; ne->n_aliases[i]; i++) {
+ n = strlen(ne->n_aliases[i]) + 1;
+ strcpy(cp, ne->n_aliases[i]);
+ nptr->n_aliases[i] = cp;
+ cp += n;
+ }
+ nptr->n_aliases[i] = NULL;
+
+ return (NET_R_OK);
+}
+#else /* !NETENT_DATA */
+static int
+copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
+ char *cp, *eob;
+ int i, n;
+
+ /* copy net value and type */
+ nptr->n_addrtype = ne->n_addrtype;
+ nptr->n_net = ne->n_net;
+
+ /* copy official name */
+ cp = ndptr->line;
+ eob = ndptr->line + sizeof(ndptr->line);
+ if ((n = strlen(ne->n_name) + 1) < (eob - cp)) {
+ strcpy(cp, ne->n_name);
+ nptr->n_name = cp;
+ cp += n;
+ } else {
+ return (-1);
+ }
+
+ /* copy aliases */
+ i = 0;
+ nptr->n_aliases = ndptr->net_aliases;
+ while (ne->n_aliases[i] && i < (_MAXALIASES-1)) {
+ if ((n = strlen(ne->n_aliases[i]) + 1) < (eob - cp)) {
+ strcpy(cp, ne->n_aliases[i]);
+ nptr->n_aliases[i] = cp;
+ cp += n;
+ } else {
+ break;
+ }
+ i++;
+ }
+ nptr->n_aliases[i] = NULL;
+
+ return (NET_R_OK);
+}
+#endif /* !NETENT_DATA */
+#else /* NET_R_RETURN */
+ static int getnetent_r_unknown_systemm = 0;
+#endif /* NET_R_RETURN */
+#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
diff --git a/contrib/bind/lib/irs/getnetgrent.c b/contrib/bind/lib/irs/getnetgrent.c
index 0acb776..8c5f5f8 100644
--- a/contrib/bind/lib/irs/getnetgrent.c
+++ b/contrib/bind/lib/irs/getnetgrent.c
@@ -1,5 +1,5 @@
/*
- * Portions 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,14 +16,22 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: getnetgrent.c,v 1.9 1997/12/04 04:57:53 halley Exp $";
+static const char rcsid[] = "$Id: getnetgrent.c,v 1.14 1999/10/07 20:44:03 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
#include "port_before.h"
+#if !defined(__BIND_NOSTATIC)
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
#include <errno.h>
+#include <resolv.h>
#include <stdio.h>
#include <irs.h>
@@ -34,60 +42,100 @@ static const char rcsid[] = "$Id: getnetgrent.c,v 1.9 1997/12/04 04:57:53 halley
/* Forward */
-static struct irs_ng * init(void);
+static struct net_data *init(void);
+
/* Public */
void
setnetgrent(const char *netgroup) {
- struct irs_ng *ng = init();
-
- if (ng != NULL)
- (*ng->rewind)(ng, netgroup);
+ struct net_data *net_data = init();
+
+ setnetgrent_p(netgroup, net_data);
}
-void
+void
endnetgrent(void) {
- struct irs_ng *ng = init();
-
- if (ng)
- (*ng->close)(ng);
- net_data.ng = NULL;
+ struct net_data *net_data = init();
+
+ endnetgrent_p(net_data);
}
int
innetgr(const char *netgroup, const char *host,
const char *user, const char *domain) {
- struct irs_ng *ng = init();
-
- if (!ng)
+ struct net_data *net_data = init();
+
+ return (innetgr_p(netgroup, host, user, domain, net_data));
+}
+
+int
+getnetgrent(char **host, char **user, char **domain) {
+ struct net_data *net_data = init();
+
+ return (getnetgrent_p(host, user, domain, net_data));
+}
+
+/* Shared private. */
+
+void
+setnetgrent_p(const char *netgroup, struct net_data *net_data) {
+ struct irs_ng *ng;
+
+ if ((net_data != NULL) && ((ng = net_data->ng) != NULL))
+ (*ng->rewind)(ng, netgroup);
+}
+
+void
+endnetgrent_p(struct net_data *net_data) {
+ struct irs_ng *ng;
+
+ if (!net_data)
+ return;
+ if ((ng = net_data->ng) != NULL)
+ (*ng->close)(ng);
+ net_data->ng = NULL;
+}
+
+int
+innetgr_p(const char *netgroup, const char *host,
+ const char *user, const char *domain,
+ struct net_data *net_data) {
+ struct irs_ng *ng;
+
+ if (!net_data || !(ng = net_data->ng))
return (0);
return ((*ng->test)(ng, netgroup, host, user, domain));
}
int
-getnetgrent(char **host, char **user, char **domain) {
- struct irs_ng *ng = init();
- struct netgrp *ngent;
-
- if (!ng)
+getnetgrent_p(char **host, char **user, char **domain,
+ struct net_data *net_data ) {
+ struct irs_ng *ng;
+
+ if (!net_data || !(ng = net_data->ng))
return (0);
return ((*ng->next)(ng, host, user, domain));
}
/* Private */
-static struct irs_ng *
+static struct net_data *
init(void) {
-
- if (!net_data_init())
+ struct net_data *net_data;
+
+ if (!(net_data = net_data_init(NULL)))
goto error;
- if (!net_data.ng)
- net_data.ng = (*net_data.irs->ng_map)(net_data.irs);
- if (!net_data.ng) {
-error:
- errno = EIO;
- return (NULL);
+ if (!net_data->ng) {
+ net_data->ng = (*net_data->irs->ng_map)(net_data->irs);
+ if (!net_data->ng) {
+ error:
+ errno = EIO;
+ return (NULL);
+ }
}
- return (net_data.ng);
+
+ return (net_data);
}
+
+#endif /*__BIND_NOSTATIC*/
diff --git a/contrib/bind/lib/irs/getnetgrent_r.c b/contrib/bind/lib/irs/getnetgrent_r.c
new file mode 100644
index 0000000..e0c366c
--- /dev/null
+++ b/contrib/bind/lib/irs/getnetgrent_r.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 1998-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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.4 1999/01/18 07:46:52 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <port_before.h>
+#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
+ static int getnetgrent_r_not_required = 0;
+#else
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <port_after.h>
+
+#ifdef NGR_R_RETURN
+
+static NGR_R_RETURN
+copy_protoent(char **, char **, char **, char *, char *, char *,
+ NGR_R_COPY_ARGS);
+
+NGR_R_RETURN
+innetgr_r(const char *netgroup, const char *host, const char *user,
+ const char *domain) {
+
+ return (innetgr(netgroup, host, user, domain));
+}
+
+/*
+ * These assume a single context is in operation per thread.
+ * If this is not the case we will need to call irs directly
+ * rather than through the base functions.
+ */
+
+NGR_R_RETURN
+getnetgrent_r(char **machinep, char **userp, char **domainp, NGR_R_ARGS) {
+ char *mp, *up, *dp;
+ int res = getnetgrent(&mp, &up, &dp);
+
+ if (res != 1)
+ return (res);
+
+ return (copy_protoent(machinep, userp, domainp,
+ mp, up, dp, NGR_R_COPY));
+}
+
+NGR_R_SET_RETURN
+#ifdef NGR_R_ENT_ARGS
+setnetgrent_r(const char *netgroup, NGR_R_ENT_ARGS)
+#else
+setnetgrent_r(const char *netgroup)
+#endif
+{
+ setnetgrent(netgroup);
+#ifdef NGR_R_SET_RESULT
+ return (NGR_R_SET_RESULT);
+#endif
+}
+
+NGR_R_END_RETURN
+endnetgrent_r(NGR_R_ENT_ARGS) {
+ endnetgrent();
+ NGR_R_END_RESULT(NGR_R_OK);
+}
+
+/* Private */
+
+static int
+copy_protoent(char **machinep, char **userp, char **domainp,
+ char *mp, char *up, char *dp, NGR_R_COPY_ARGS) {
+ char *cp;
+ int i, n;
+ int len;
+
+ /* Find out the amount of space required to store the answer. */
+ len = 0;
+ if (mp != NULL) len += strlen(mp) + 1;
+ if (up != NULL) len += strlen(up) + 1;
+ if (dp != NULL) len += strlen(dp) + 1;
+
+ if (len > buflen) {
+ errno = ERANGE;
+ return (NGR_R_BAD);
+ }
+
+ cp = buf;
+
+ if (mp != NULL) {
+ n = strlen(mp) + 1;
+ strcpy(cp, mp);
+ *machinep = cp;
+ cp += n;
+ } else
+ *machinep = NULL;
+
+ if (up != NULL) {
+ n = strlen(up) + 1;
+ strcpy(cp, up);
+ *userp = cp;
+ cp += n;
+ } else
+ *userp = NULL;
+
+ if (dp != NULL) {
+ n = strlen(dp) + 1;
+ strcpy(cp, dp);
+ *domainp = cp;
+ cp += n;
+ } else
+ *domainp = NULL;
+
+ return (NGR_R_OK);
+}
+#else /* NGR_R_RETURN */
+ static int getnetgrent_r_unknown_system = 0;
+#endif /* NGR_R_RETURN */
+#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
diff --git a/contrib/bind/lib/irs/getprotoent.c b/contrib/bind/lib/irs/getprotoent.c
index f79a1c6..e3bfc37 100644
--- a/contrib/bind/lib/irs/getprotoent.c
+++ b/contrib/bind/lib/irs/getprotoent.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,16 +16,22 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: getprotoent.c,v 1.9 1997/12/04 04:57:53 halley Exp $";
+static const char rcsid[] = "$Id: getprotoent.c,v 1.15 1999/10/13 16:39:31 vixie Exp $";
#endif
/* Imports */
#include "port_before.h"
+#if !defined(__BIND_NOSTATIC)
+
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
#include <errno.h>
+#include <resolv.h>
#include <stdio.h>
#include <irs.h>
@@ -36,85 +42,132 @@ static char rcsid[] = "$Id: getprotoent.c,v 1.9 1997/12/04 04:57:53 halley Exp $
/* Forward */
-static struct irs_pr * init(void);
+static struct net_data *init(void);
/* Public */
struct protoent *
getprotoent() {
- struct irs_pr *pr = init();
-
- if (!pr)
- return (NULL);
- net_data.pr_last = (*pr->next)(pr);
- return (net_data.pr_last);
+ struct net_data *net_data = init();
+
+ return (getprotoent_p(net_data));
}
struct protoent *
getprotobyname(const char *name) {
- struct irs_pr *pr = init();
+ struct net_data *net_data = init();
+
+ return (getprotobyname_p(name, net_data));
+}
+
+struct protoent *
+getprotobynumber(int proto) {
+ struct net_data *net_data = init();
+
+ return (getprotobynumber_p(proto, net_data));
+}
+
+void
+setprotoent(int stayopen) {
+ struct net_data *net_data = init();
+
+ setprotoent_p(stayopen, net_data);
+}
+
+void
+endprotoent() {
+ struct net_data *net_data = init();
+
+ endprotoent_p(net_data);
+}
+
+/* Shared private. */
+
+struct protoent *
+getprotoent_p(struct net_data *net_data) {
+ struct irs_pr *pr;
+
+ if (!net_data || !(pr = net_data->pr))
+ return (NULL);
+ net_data->pr_last = (*pr->next)(pr);
+ return (net_data->pr_last);
+}
+
+struct protoent *
+getprotobyname_p(const char *name, struct net_data *net_data) {
+ struct irs_pr *pr;
char **pap;
- if (!pr)
+ if (!net_data || !(pr = net_data->pr))
return (NULL);
- if (net_data.pr_stayopen && net_data.pr_last) {
- if (!strcmp(net_data.pr_last->p_name, name))
- return (net_data.pr_last);
- for (pap = net_data.pr_last->p_aliases; pap && *pap; pap++)
+ if (net_data->pr_stayopen && net_data->pr_last) {
+ if (!strcmp(net_data->pr_last->p_name, name))
+ return (net_data->pr_last);
+ for (pap = net_data->pr_last->p_aliases; pap && *pap; pap++)
if (!strcmp(name, *pap))
- return (net_data.pr_last);
+ return (net_data->pr_last);
}
- net_data.pr_last = (*pr->byname)(pr, name);
- if (!net_data.pr_stayopen)
+ net_data->pr_last = (*pr->byname)(pr, name);
+ if (!net_data->pr_stayopen)
endprotoent();
- return (net_data.pr_last);
+ return (net_data->pr_last);
}
struct protoent *
-getprotobynumber(int proto) {
- struct irs_pr *pr = init();
+getprotobynumber_p(int proto, struct net_data *net_data) {
+ struct irs_pr *pr;
- if (!pr)
+ if (!net_data || !(pr = net_data->pr))
return (NULL);
- if (net_data.pr_stayopen && net_data.pr_last)
- if (net_data.pr_last->p_proto == proto)
- return (net_data.pr_last);
- net_data.pr_last = (*pr->bynumber)(pr, proto);
- if (!net_data.pr_stayopen)
+ if (net_data->pr_stayopen && net_data->pr_last)
+ if (net_data->pr_last->p_proto == proto)
+ return (net_data->pr_last);
+ net_data->pr_last = (*pr->bynumber)(pr, proto);
+ if (!net_data->pr_stayopen)
endprotoent();
- return (net_data.pr_last);
+ return (net_data->pr_last);
}
void
-setprotoent(int stayopen) {
- struct irs_pr *pr = init();
+setprotoent_p(int stayopen, struct net_data *net_data) {
+ struct irs_pr *pr;
- if (!pr)
+ if (!net_data || !(pr = net_data->pr))
return;
(*pr->rewind)(pr);
- net_data.pr_stayopen = (stayopen != 0);
+ net_data->pr_stayopen = (stayopen != 0);
+ if (stayopen == 0)
+ net_data_minimize(net_data);
}
void
-endprotoent() {
- struct irs_pr *pr = init();
+endprotoent_p(struct net_data *net_data) {
+ struct irs_pr *pr;
- if (pr != NULL)
+ if ((net_data != NULL) && ((pr = net_data->pr) != NULL))
(*pr->minimize)(pr);
}
/* Private */
-static struct irs_pr *
+static struct net_data *
init() {
- if (!net_data_init())
+ struct net_data *net_data;
+
+ if (!(net_data = net_data_init(NULL)))
goto error;
- if (!net_data.pr)
- net_data.pr = (*net_data.irs->pr_map)(net_data.irs);
- if (!net_data.pr) {
+ if (!net_data->pr) {
+ net_data->pr = (*net_data->irs->pr_map)(net_data->irs);
+
+ if (!net_data->pr || !net_data->res) {
error:
- errno = EIO;
- return (NULL);
+ errno = EIO;
+ return (NULL);
+ }
+ (*net_data->pr->res_set)(net_data->pr, net_data->res, NULL);
}
- return (net_data.pr);
+
+ return (net_data);
}
+
+#endif /*__BIND_NOSTATIC*/
diff --git a/contrib/bind/lib/irs/getprotoent_r.c b/contrib/bind/lib/irs/getprotoent_r.c
new file mode 100644
index 0000000..e5c54d7
--- /dev/null
+++ b/contrib/bind/lib/irs/getprotoent_r.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 1998-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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: getprotoent_r.c,v 8.4 1999/01/18 07:46:52 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <port_before.h>
+#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
+ static int getprotoent_r_not_required = 0;
+#else
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <port_after.h>
+
+#ifdef PROTO_R_RETURN
+
+static PROTO_R_RETURN
+copy_protoent(struct protoent *, struct protoent *, PROTO_R_COPY_ARGS);
+
+PROTO_R_RETURN
+getprotobyname_r(const char *name, struct protoent *pptr, PROTO_R_ARGS) {
+ struct protoent *pe = getprotobyname(name);
+
+ if (pe == NULL)
+ return (PROTO_R_BAD);
+
+ return (copy_protoent(pe, pptr, PROTO_R_COPY));
+}
+
+PROTO_R_RETURN
+getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) {
+ struct protoent *pe = getprotobynumber(proto);
+
+ if (pe == NULL)
+ return (PROTO_R_BAD);
+
+ return (copy_protoent(pe, pptr, PROTO_R_COPY));
+}
+
+/*
+ * These assume a single context is in operation per thread.
+ * If this is not the case we will need to call irs directly
+ * rather than through the base functions.
+ */
+
+PROTO_R_RETURN
+getprotoent_r(struct protoent *pptr, PROTO_R_ARGS) {
+ struct protoent *pe = getprotoent();
+
+ if (pe == NULL)
+ return (PROTO_R_BAD);
+
+ return (copy_protoent(pe, pptr, PROTO_R_COPY));
+}
+
+PROTO_R_SET_RETURN
+#ifdef PROTO_R_ENT_ARGS
+setprotoent_r(int stay_open, PROTO_R_ENT_ARGS)
+#else
+setprotoent_r(int stay_open)
+#endif
+{
+ setprotoent(stay_open);
+#ifdef PROTO_R_SET_RESULT
+ return (PROTO_R_SET_RESULT);
+#endif
+}
+
+PROTO_R_END_RETURN
+#ifdef PROTO_R_ENT_ARGS
+endprotoent_r(PROTO_R_ENT_ARGS)
+#else
+endprotoent_r()
+#endif
+{
+ endprotoent();
+ PROTO_R_END_RESULT(PROTO_R_OK);
+}
+
+/* Private */
+
+#ifndef PROTOENT_DATA
+static PROTO_R_RETURN
+copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
+ char *cp;
+ int i, n;
+ int numptr, len;
+
+ /* Find out the amount of space required to store the answer. */
+ numptr = 1; /* NULL ptr */
+ len = (char *)ALIGN(buf) - buf;
+ for (i = 0; pe->p_aliases[i]; i++, numptr++) {
+ len += strlen(pe->p_aliases[i]) + 1;
+ }
+ len += strlen(pe->p_name) + 1;
+ len += numptr * sizeof(char*);
+
+ if (len > buflen) {
+ errno = ERANGE;
+ return (PROTO_R_BAD);
+ }
+
+ /* copy protocol value*/
+ pptr->p_proto = pe->p_proto;
+
+ cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
+
+ /* copy official name */
+ n = strlen(pe->p_name) + 1;
+ strcpy(cp, pe->p_name);
+ pptr->p_name = cp;
+ cp += n;
+
+ /* copy aliases */
+ pptr->p_aliases = (char **)ALIGN(buf);
+ for (i = 0 ; pe->p_aliases[i]; i++) {
+ n = strlen(pe->p_aliases[i]) + 1;
+ strcpy(cp, pe->p_aliases[i]);
+ pptr->p_aliases[i] = cp;
+ cp += n;
+ }
+ pptr->p_aliases[i] = NULL;
+
+ return (PROTO_R_OK);
+}
+#else /* !PROTOENT_DATA */
+static int
+copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
+ char *cp, *eob;
+ int i, n;
+
+ /* copy protocol value */
+ pptr->p_proto = pe->p_proto;
+
+ /* copy official name */
+ cp = pdptr->line;
+ eob = pdptr->line + sizeof(pdptr->line);
+ if ((n = strlen(pe->p_name) + 1) < (eob - cp)) {
+ strcpy(cp, pe->p_name);
+ pptr->p_name = cp;
+ cp += n;
+ } else {
+ return (-1);
+ }
+
+ /* copy aliases */
+ i = 0;
+ pptr->p_aliases = pdptr->proto_aliases;
+ while (pe->p_aliases[i] && i < (_MAXALIASES-1)) {
+ if ((n = strlen(pe->p_aliases[i]) + 1) < (eob - cp)) {
+ strcpy(cp, pe->p_aliases[i]);
+ pptr->p_aliases[i] = cp;
+ cp += n;
+ } else {
+ break;
+ }
+ i++;
+ }
+ pptr->p_aliases[i] = NULL;
+
+ return (PROTO_R_OK);
+}
+#endif /* PROTOENT_DATA */
+#else /* PROTO_R_RETURN */
+ static int getprotoent_r_unknown_systemm = 0;
+#endif /* PROTO_R_RETURN */
+#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
diff --git a/contrib/bind/lib/irs/getpwent.c b/contrib/bind/lib/irs/getpwent.c
index 8e4d897..94f2df5 100644
--- a/contrib/bind/lib/irs/getpwent.c
+++ b/contrib/bind/lib/irs/getpwent.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,21 +16,25 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: getpwent.c,v 1.13 1998/03/21 00:59:48 halley Exp $";
+static const char rcsid[] = "$Id: getpwent.c,v 1.20 1999/10/13 16:39:31 vixie Exp $";
#endif
/* Imports */
#include "port_before.h"
-#ifndef WANT_IRS_PW
+#if !defined(WANT_IRS_PW) || defined(__BIND_NOSTATIC)
static int __bind_irs_pw_unneeded;
#else
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
#include <errno.h>
#include <pwd.h>
+#include <resolv.h>
#include <stdio.h>
#include <irs.h>
@@ -41,95 +45,155 @@ static int __bind_irs_pw_unneeded;
/* Forward */
-static struct irs_pw * init(void);
+static struct net_data * init(void);
/* Public */
struct passwd *
getpwent(void) {
- struct irs_pw *pw = init();
+ struct net_data *net_data = init();
- if (!pw)
- return (NULL);
- net_data.pw_last = (*pw->next)(pw);
- return (net_data.pw_last);
+ return (getpwent_p(net_data));
}
struct passwd *
getpwnam(const char *name) {
- struct irs_pw *pw = init();
-
- if (!pw)
+ struct net_data *net_data = init();
+
+ return (getpwnam_p(name, net_data));
+}
+
+struct passwd *
+getpwuid(uid_t uid) {
+ struct net_data *net_data = init();
+
+ return (getpwuid_p(uid, net_data));
+}
+
+int
+setpassent(int stayopen) {
+ struct net_data *net_data = init();
+
+ return (setpassent_p(stayopen, net_data));
+}
+
+#ifdef SETPWENT_VOID
+void
+setpwent() {
+ struct net_data *net_data = init();
+
+ setpwent_p(net_data);
+}
+#else
+int
+setpwent() {
+ struct net_data *net_data = init();
+
+ return (setpwent_p(net_data));
+}
+#endif
+
+void
+endpwent() {
+ struct net_data *net_data = init();
+
+ return (endpwent_p(net_data));
+}
+
+/* Shared private. */
+
+struct passwd *
+getpwent_p(struct net_data *net_data) {
+ struct irs_pw *pw;
+
+ if (!net_data || !(pw = net_data->pw))
+ return (NULL);
+ net_data->pw_last = (*pw->next)(pw);
+ return (net_data->pw_last);
+}
+
+struct passwd *
+getpwnam_p(const char *name, struct net_data *net_data) {
+ struct irs_pw *pw;
+
+ if (!net_data || !(pw = net_data->pw))
return (NULL);
- if (net_data.pw_stayopen && net_data.pw_last &&
- !strcmp(net_data.pw_last->pw_name, name))
- return (net_data.pw_last);
- net_data.pw_last = (*pw->byname)(pw, name);
- if (!net_data.pw_stayopen)
+ if (net_data->pw_stayopen && net_data->pw_last &&
+ !strcmp(net_data->pw_last->pw_name, name))
+ return (net_data->pw_last);
+ net_data->pw_last = (*pw->byname)(pw, name);
+ if (!net_data->pw_stayopen)
endpwent();
- return (net_data.pw_last);
+ return (net_data->pw_last);
}
struct passwd *
-getpwuid(uid_t uid) {
- struct irs_pw *pw = init();
+getpwuid_p(uid_t uid, struct net_data *net_data) {
+ struct irs_pw *pw;
- if (!pw)
+ if (!net_data || !(pw = net_data->pw))
return (NULL);
- if (net_data.pw_stayopen && net_data.pw_last &&
- net_data.pw_last->pw_uid == uid)
- return (net_data.pw_last);
- net_data.pw_last = (*pw->byuid)(pw, uid);
- if (!net_data.pw_stayopen)
+ if (net_data->pw_stayopen && net_data->pw_last &&
+ net_data->pw_last->pw_uid == uid)
+ return (net_data->pw_last);
+ net_data->pw_last = (*pw->byuid)(pw, uid);
+ if (!net_data->pw_stayopen)
endpwent();
- return (net_data.pw_last);
+ return (net_data->pw_last);
}
int
-setpassent(int stayopen) {
- struct irs_pw *pw = init();
-
- if (!pw)
+setpassent_p(int stayopen, struct net_data *net_data) {
+ struct irs_pw *pw;
+
+ if (!net_data || !(pw = net_data->pw))
return (0);
(*pw->rewind)(pw);
- net_data.pw_stayopen = (stayopen != 0);
+ net_data->pw_stayopen = (stayopen != 0);
+ if (stayopen == 0)
+ net_data_minimize(net_data);
return (1);
}
#ifdef SETPWENT_VOID
void
-setpwent() {
- (void) setpassent(0);
+setpwent_p(struct net_data *net_data) {
+ (void) setpassent_p(0, net_data);
}
#else
-int
-setpwent() {
- return (setpassent(0));
+int
+setpwent_p(struct net_data *net_data) {
+ return (setpassent_p(0, net_data));
}
#endif
void
-endpwent() {
- struct irs_pw *pw = init();
+endpwent_p(struct net_data *net_data) {
+ struct irs_pw *pw;
- if (pw != NULL)
+ if ((net_data != NULL) && ((pw = net_data->pw) != NULL))
(*pw->minimize)(pw);
}
/* Private */
-static struct irs_pw *
+static struct net_data *
init() {
- if (!net_data_init())
+ struct net_data *net_data;
+ if (!(net_data = net_data_init(NULL)))
goto error;
- if (!net_data.pw)
- net_data.pw = (*net_data.irs->pw_map)(net_data.irs);
- if (!net_data.pw) {
+ if (!net_data->pw) {
+ net_data->pw = (*net_data->irs->pw_map)(net_data->irs);
+
+ if (!net_data->pw || !net_data->res) {
error:
- errno = EIO;
- return (NULL);
+ errno = EIO;
+ return (NULL);
+ }
+ (*net_data->pw->res_set)(net_data->pw, net_data->res, NULL);
}
- return (net_data.pw);
+
+ return (net_data);
}
#endif /* WANT_IRS_PW */
diff --git a/contrib/bind/lib/irs/getpwent_r.c b/contrib/bind/lib/irs/getpwent_r.c
new file mode 100644
index 0000000..761fa45
--- /dev/null
+++ b/contrib/bind/lib/irs/getpwent_r.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 1998-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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: getpwent_r.c,v 8.3 1999/01/08 19:24:33 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <port_before.h>
+#if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
+ static int getpwent_r_not_required = 0;
+#else
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <port_after.h>
+
+#ifdef PASS_R_RETURN
+
+static int
+copy_passwd(struct passwd *, struct passwd *, char *buf, int buflen);
+
+/* POSIX 1003.1c */
+#ifdef POSIX_GETPWNAM_R
+int
+__posix_getpwnam_r(const char *login, struct passwd *pwptr,
+ char *buf, size_t buflen, struct passwd **result) {
+#else
+int
+getpwnam_r(const char *login, struct passwd *pwptr,
+ char *buf, size_t buflen, struct passwd **result) {
+#endif
+ struct passwd *pw = getpwnam(login);
+ int res;
+
+ if (pw == NULL) {
+ *result = NULL;
+ return (-1);
+ }
+
+ res = copy_passwd(pw, pwptr, buf, buflen);
+ *result = res ? NULL : pwptr;
+ return (res);
+}
+
+#ifdef POSIX_GETPWNAM_R
+struct passwd *
+getpwnam_r(const char *login, struct passwd *pwptr, char *buf, int buflen) {
+ struct passwd *pw = getpwnam(login);
+ int res;
+
+ if (pw == NULL)
+ return (NULL);
+
+ res = copy_passwd(pw, pwptr, buf, buflen);
+ return (res ? NULL : pwptr);
+}
+#endif
+
+/* POSIX 1003.1c */
+#ifdef POSIX_GETPWUID_R
+int
+__posix_getpwuid_r(uid_t uid, struct passwd *pwptr,
+ char *buf, int buflen, struct passwd **result) {
+#else
+int
+getpwuid_r(uid_t uid, struct passwd *pwptr,
+ char *buf, size_t buflen, struct passwd **result) {
+#endif
+ struct passwd *pw = getpwuid(uid);
+ int res;
+
+ if (pw == NULL) {
+ *result = NULL;
+ return (-1);
+ }
+
+ res = copy_passwd(pw, pwptr, buf, buflen);
+ *result = res ? NULL : pwptr;
+ return (res);
+}
+
+#ifdef POSIX_GETPWUID_R
+struct passwd *
+getpwuid_r(uid_t uid, struct passwd *pwptr, char *buf, int buflen) {
+ struct passwd *pw = getpwuid(uid);
+ int res;
+
+ if (pw == NULL)
+ return (NULL);
+
+ res = copy_passwd(pw, pwptr, buf, buflen);
+ return (res ? NULL : pwptr);
+}
+#endif
+
+/*
+ * These assume a single context is in operation per thread.
+ * If this is not the case we will need to call irs directly
+ * rather than through the base functions.
+ */
+
+PASS_R_RETURN
+getpwent_r(struct passwd *pwptr, PASS_R_ARGS) {
+ struct passwd *pw = getpwent();
+ int res;
+
+ if (pw == NULL)
+ return (PASS_R_BAD);
+
+ res = copy_passwd(pw, pwptr, buf, buflen);
+ return (res ? PASS_R_BAD : PASS_R_OK);
+}
+
+PASS_R_SET_RETURN
+#ifdef PASS_R_ENT_ARGS
+setpassent_r(int stayopen, PASS_R_ENT_ARGS)
+#else
+setpassent_r(int stayopen)
+#endif
+{
+
+ setpassent(stayopen);
+#ifdef PASS_R_SET_RESULT
+ return (PASS_R_SET_RESULT);
+#endif
+}
+
+PASS_R_SET_RETURN
+setpwent_r(PASS_R_ENT_ARGS) {
+
+ setpwent();
+#ifdef PASS_R_SET_RESULT
+ return (PASS_R_SET_RESULT);
+#endif
+}
+
+PASS_R_END_RETURN
+endpwent_r(PASS_R_ENT_ARGS) {
+
+ endpwent();
+ PASS_R_END_RESULT(PASS_R_OK);
+}
+
+
+#ifdef HAS_FGETPWENT
+PASS_R_RETURN
+fgetpwent_r(FILE *f, struct passwd *pwptr, PASS_R_COPY_ARGS) {
+ struct passwd *pw = fgetpwent(f);
+ int res;
+
+ if (pw == NULL)
+ return (PASS_R_BAD);
+
+ res = copy_passwd(pw, pwptr, PASS_R_COPY);
+ return (res ? PASS_R_BAD : PASS_R_OK );
+}
+#endif
+
+/* Private */
+
+static int
+copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) {
+ char *cp;
+ int i, n;
+ int numptr, len;
+
+ /* Find out the amount of space required to store the answer. */
+ len = strlen(pw->pw_name) + 1;
+ len += strlen(pw->pw_passwd) + 1;
+#ifdef HAVE_PW_CLASS
+ len += strlen(pw->pw_class) + 1;
+#endif
+ len += strlen(pw->pw_gecos) + 1;
+ len += strlen(pw->pw_dir) + 1;
+ len += strlen(pw->pw_shell) + 1;
+
+ if (len > buflen) {
+ errno = ERANGE;
+ return (-1);
+ }
+
+ /* copy fixed atomic values*/
+ pwptr->pw_uid = pw->pw_uid;
+ pwptr->pw_gid = pw->pw_gid;
+#ifdef HAVE_PW_CHANGE
+ pwptr->pw_change = pw->pw_change;
+#endif
+#ifdef HAVE_PW_EXPIRE
+ pwptr->pw_expire = pw->pw_expire;
+#endif
+
+ cp = buf;
+
+ /* copy official name */
+ n = strlen(pw->pw_name) + 1;
+ strcpy(cp, pw->pw_name);
+ pwptr->pw_name = cp;
+ cp += n;
+
+ /* copy password */
+ n = strlen(pw->pw_passwd) + 1;
+ strcpy(cp, pw->pw_passwd);
+ pwptr->pw_passwd = cp;
+ cp += n;
+
+#ifdef HAVE_PW_CLASS
+ /* copy class */
+ n = strlen(pw->pw_class) + 1;
+ strcpy(cp, pw->pw_class);
+ pwptr->pw_class = cp;
+ cp += n;
+#endif
+
+ /* copy gecos */
+ n = strlen(pw->pw_gecos) + 1;
+ strcpy(cp, pw->pw_gecos);
+ pwptr->pw_gecos = cp;
+ cp += n;
+
+ /* copy directory */
+ n = strlen(pw->pw_dir) + 1;
+ strcpy(cp, pw->pw_dir);
+ pwptr->pw_dir = cp;
+ cp += n;
+
+ /* copy login shell */
+ n = strlen(pw->pw_shell) + 1;
+ strcpy(cp, pw->pw_shell);
+ pwptr->pw_shell = cp;
+ cp += n;
+
+ return (0);
+}
+#else /* PASS_R_RETURN */
+ static int getpwent_r_unknown_systemm = 0;
+#endif /* PASS_R_RETURN */
+#endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
diff --git a/contrib/bind/lib/irs/getservent.c b/contrib/bind/lib/irs/getservent.c
index 64ac2dc..d2b8b50 100644
--- a/contrib/bind/lib/irs/getservent.c
+++ b/contrib/bind/lib/irs/getservent.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,16 +16,22 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: getservent.c,v 1.10 1997/12/04 04:57:54 halley Exp $";
+static const char rcsid[] = "$Id: getservent.c,v 1.16 1999/10/13 16:39:31 vixie Exp $";
#endif
/* Imports */
#include "port_before.h"
+#if !defined(__BIND_NOSTATIC)
+
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
#include <errno.h>
+#include <resolv.h>
#include <stdio.h>
#include <irs.h>
@@ -36,87 +42,135 @@ static char rcsid[] = "$Id: getservent.c,v 1.10 1997/12/04 04:57:54 halley Exp $
/* Forward */
-static struct irs_sv * init(void);
+static struct net_data *init(void);
/* Public */
struct servent *
getservent(void) {
- struct irs_sv *sv = init();
-
- if (!sv)
- return (NULL);
- net_data.sv_last = (*sv->next)(sv);
- return (net_data.sv_last);
+ struct net_data *net_data = init();
+
+ return (getservent_p(net_data));
}
struct servent *
getservbyname(const char *name, const char *proto) {
- struct irs_sv *sv = init();
+ struct net_data *net_data = init();
+
+ return (getservbyname_p(name, proto, net_data));
+}
+
+struct servent *
+getservbyport(int port, const char *proto) {
+ struct net_data *net_data = init();
+
+ return (getservbyport_p(port, proto, net_data));
+}
+
+void
+setservent(int stayopen) {
+ struct net_data *net_data = init();
+
+ setservent_p(stayopen, net_data);
+}
+
+void
+endservent() {
+ struct net_data *net_data = init();
+
+ endservent_p(net_data);
+}
+
+/* Shared private. */
+
+struct servent *
+getservent_p(struct net_data *net_data) {
+ struct irs_sv *sv;
+
+ if (!net_data || !(sv = net_data->sv))
+ return (NULL);
+ net_data->sv_last = (*sv->next)(sv);
+ return (net_data->sv_last);
+}
+
+struct servent *
+getservbyname_p(const char *name, const char *proto,
+ struct net_data *net_data) {
+ struct irs_sv *sv;
char **sap;
-
- if (!sv)
+
+ if (!net_data || !(sv = net_data->sv))
return (NULL);
- if (net_data.sv_stayopen && net_data.sv_last)
- if (!proto || !strcmp(net_data.sv_last->s_proto,proto)) {
- if (!strcmp(net_data.sv_last->s_name, name))
- return (net_data.sv_last);
- for (sap = net_data.sv_last->s_aliases;
- sap && *sap; sap++)
+ if (net_data->sv_stayopen && net_data->sv_last)
+ if (!proto || !strcmp(net_data->sv_last->s_proto, proto)) {
+ if (!strcmp(net_data->sv_last->s_name, name))
+ return (net_data->sv_last);
+ for (sap = net_data->sv_last->s_aliases;
+ sap && *sap; sap++)
if (!strcmp(name, *sap))
- return (net_data.sv_last);
+ return (net_data->sv_last);
}
- net_data.sv_last = (*sv->byname)(sv, name, proto);
- if (!net_data.sv_stayopen)
+ net_data->sv_last = (*sv->byname)(sv, name, proto);
+ if (!net_data->sv_stayopen)
endservent();
- return (net_data.sv_last);
+ return (net_data->sv_last);
}
struct servent *
-getservbyport(int port, const char *proto) {
- struct irs_sv *sv = init();
-
- if (!sv)
+getservbyport_p(int port, const char *proto, struct net_data *net_data) {
+ struct irs_sv *sv;
+
+ if (!net_data || !(sv = net_data->sv))
return (NULL);
- if (net_data.sv_stayopen && net_data.sv_last)
- if (port == net_data.sv_last->s_port &&
- ( !proto ||
- !strcmp(net_data.sv_last->s_proto, proto)))
- return (net_data.sv_last);
- net_data.sv_last = (*sv->byport)(sv, port,proto);
- return (net_data.sv_last);
+ if (net_data->sv_stayopen && net_data->sv_last)
+ if (port == net_data->sv_last->s_port &&
+ ( !proto ||
+ !strcmp(net_data->sv_last->s_proto, proto)))
+ return (net_data->sv_last);
+ net_data->sv_last = (*sv->byport)(sv, port, proto);
+ return (net_data->sv_last);
}
void
-setservent(int stayopen) {
- struct irs_sv *sv = init();
+setservent_p(int stayopen, struct net_data *net_data) {
+ struct irs_sv *sv;
- if (!sv)
+ if (!net_data || !(sv = net_data->sv))
return;
(*sv->rewind)(sv);
- net_data.sv_stayopen = (stayopen != 0);
+ net_data->sv_stayopen = (stayopen != 0);
+ if (stayopen == 0)
+ net_data_minimize(net_data);
}
void
-endservent() {
- struct irs_sv *sv = init();
+endservent_p(struct net_data *net_data) {
+ struct irs_sv *sv;
- if (sv != NULL)
+ if ((net_data != NULL) && ((sv = net_data->sv) != NULL))
(*sv->minimize)(sv);
}
/* Private */
-static struct irs_sv *
+static struct net_data *
init() {
- if (!net_data_init())
+ struct net_data *net_data;
+
+ if (!(net_data = net_data_init(NULL)))
goto error;
- if (!net_data.sv)
- net_data.sv = (*net_data.irs->sv_map)(net_data.irs);
- if (!net_data.sv) {
+ if (!net_data->sv) {
+ net_data->sv = (*net_data->irs->sv_map)(net_data->irs);
+
+ if (!net_data->sv || !net_data->res) {
error:
- errno = EIO;
- return (NULL);
+ errno = EIO;
+ return (NULL);
+ }
+ (*net_data->sv->res_set)(net_data->sv, net_data->res, NULL);
}
- return (net_data.sv);
+
+ return (net_data);
}
+
+#endif /*__BIND_NOSTATIC*/
diff --git a/contrib/bind/lib/irs/getservent_r.c b/contrib/bind/lib/irs/getservent_r.c
new file mode 100644
index 0000000..4da9dc2
--- /dev/null
+++ b/contrib/bind/lib/irs/getservent_r.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1998-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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: getservent_r.c,v 8.3 1999/01/08 19:24:36 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <port_before.h>
+#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
+ static int getservent_r_not_required = 0;
+#else
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <port_after.h>
+
+#ifdef SERV_R_RETURN
+
+static SERV_R_RETURN
+copy_servent(struct servent *, struct servent *, SERV_R_COPY_ARGS);
+
+SERV_R_RETURN
+getservbyname_r(const char *name, const char *proto,
+ struct servent *sptr, SERV_R_ARGS) {
+ struct servent *se = getservbyname(name, proto);
+
+ if (se == NULL)
+ return (SERV_R_BAD);
+
+ return (copy_servent(se, sptr, SERV_R_COPY));
+}
+
+SERV_R_RETURN
+getservbyport_r(int port, const char *proto,
+ struct servent *sptr, SERV_R_ARGS) {
+ struct servent *se = getservbyport(port, proto);
+
+ if (se == NULL)
+ return (SERV_R_BAD);
+
+ return (copy_servent(se, sptr, SERV_R_COPY));
+}
+
+/*
+ * These assume a single context is in operation per thread.
+ * If this is not the case we will need to call irs directly
+ * rather than through the base functions.
+ */
+
+SERV_R_RETURN
+getservent_r(struct servent *sptr, SERV_R_ARGS) {
+ struct servent *se = getservent();
+
+ if (se == NULL)
+ return (SERV_R_BAD);
+
+ return (copy_servent(se, sptr, SERV_R_COPY));
+}
+
+SERV_R_SET_RETURN
+#ifdef SERV_R_ENT_ARGS
+setservent_r(int stay_open, SERV_R_ENT_ARGS)
+#else
+setservent_r(int stay_open)
+#endif
+{
+
+ setservent(stay_open);
+#ifdef SERV_R_SET_RESULT
+ return (SERV_R_SET_RESULT);
+#endif
+}
+
+SERV_R_END_RETURN
+#ifdef SERV_R_ENT_ARGS
+endservent_r(SERV_R_ENT_ARGS)
+#else
+endservent_r()
+#endif
+{
+
+ endservent();
+ SERV_R_END_RESULT(SERV_R_OK);
+}
+
+/* Private */
+
+#ifndef SERVENT_DATA
+static SERV_R_RETURN
+copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
+ char *cp;
+ int i, n;
+ int numptr, len;
+
+ /* Find out the amount of space required to store the answer. */
+ numptr = 1; /* NULL ptr */
+ len = (char *)ALIGN(buf) - buf;
+ for (i = 0; se->s_aliases[i]; i++, numptr++) {
+ len += strlen(se->s_aliases[i]) + 1;
+ }
+ len += strlen(se->s_name) + 1;
+ len += strlen(se->s_proto) + 1;
+ len += numptr * sizeof(char*);
+
+ if (len > buflen) {
+ errno = ERANGE;
+ return (SERV_R_BAD);
+ }
+
+ /* copy port value */
+ sptr->s_port = se->s_port;
+
+ cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
+
+ /* copy official name */
+ n = strlen(se->s_name) + 1;
+ strcpy(cp, se->s_name);
+ sptr->s_name = cp;
+ cp += n;
+
+ /* copy aliases */
+ sptr->s_aliases = (char **)ALIGN(buf);
+ for (i = 0 ; se->s_aliases[i]; i++) {
+ n = strlen(se->s_aliases[i]) + 1;
+ strcpy(cp, se->s_aliases[i]);
+ sptr->s_aliases[i] = cp;
+ cp += n;
+ }
+ sptr->s_aliases[i] = NULL;
+
+ /* copy proto */
+ n = strlen(se->s_proto) + 1;
+ strcpy(cp, se->s_proto);
+ sptr->s_proto = cp;
+ cp += n;
+
+ return (SERV_R_OK);
+}
+#else /* !SERVENT_DATA */
+static int
+copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
+ char *cp, *eob;
+ int i, n;
+
+ /* copy port value */
+ sptr->s_port = se->s_port;
+
+ /* copy official name */
+ cp = ndptr->line;
+ eob = ndptr->line + sizeof(ndptr->line);
+ if ((n = strlen(se->s_name) + 1) < (eob - cp)) {
+ strcpy(cp, se->s_name);
+ sptr->s_name = cp;
+ cp += n;
+ } else {
+ return (-1);
+ }
+
+ /* copy aliases */
+ i = 0;
+ sptr->s_aliases = ndptr->serv_aliases;
+ while (se->s_aliases[i] && i < (_MAXALIASES-1)) {
+ if ((n = strlen(se->s_aliases[i]) + 1) < (eob - cp)) {
+ strcpy(cp, se->s_aliases[i]);
+ sptr->s_aliases[i] = cp;
+ cp += n;
+ } else {
+ break;
+ }
+ i++;
+ }
+ sptr->s_aliases[i] = NULL;
+
+ /* copy proto */
+ if ((n = strlen(se->s_proto) + 1) < (eob - cp)) {
+ strcpy(cp, se->s_proto);
+ sptr->s_proto = cp;
+ cp += n;
+ } else {
+ return (-1);
+ }
+
+ return (SERV_R_OK);
+}
+#endif /* !SERVENT_DATA */
+#else /*SERV_R_RETURN */
+ static int getservent_r_unknown_systemm = 0;
+#endif /*SERV_R_RETURN */
+#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
diff --git a/contrib/bind/lib/irs/hesiod.c b/contrib/bind/lib/irs/hesiod.c
index a56d213..54a6657 100644
--- a/contrib/bind/lib/irs/hesiod.c
+++ b/contrib/bind/lib/irs/hesiod.c
@@ -1,9 +1,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: hesiod.c,v 1.15 1998/01/26 23:08:24 halley Exp $";
+static const char rcsid[] = "$Id: hesiod.c,v 1.20 1999/02/22 04:09:06 vixie Exp $";
#endif
/*
- * 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
@@ -65,6 +65,7 @@ void hesiod_free_list(void *context, char **list);
static int parse_config_file(struct hesiod_p *ctx, const char *filename);
static char ** get_txt_records(struct hesiod_p *ctx, int class,
const char *name);
+static int init(struct hesiod_p *ctx);
/* Public */
@@ -131,15 +132,16 @@ hesiod_init(void **context) {
goto cleanup;
}
+#if 0
+ if (res_ninit(ctx->res) < 0)
+ goto cleanup;
+#endif
+
*context = ctx;
return (0);
cleanup:
- if (ctx->LHS)
- free(ctx->LHS);
- if (ctx->RHS)
- free(ctx->RHS);
- free(ctx);
+ hesiod_end(ctx);
return (-1);
}
@@ -149,12 +151,18 @@ hesiod_init(void **context) {
void
hesiod_end(void *context) {
struct hesiod_p *ctx = (struct hesiod_p *) context;
+ int save_errno = errno;
+ if (ctx->res)
+ res_nclose(ctx->res);
if (ctx->RHS)
free(ctx->RHS);
if (ctx->LHS)
free(ctx->LHS);
+ if (ctx->res && ctx->free_res)
+ (*ctx->free_res)(ctx->res);
free(ctx);
+ errno = save_errno;
}
/*
@@ -226,11 +234,17 @@ hesiod_resolve(void *context, const char *name, const char *type) {
char *bindname = hesiod_to_bind(context, name, type);
char **retvec;
- if (!bindname)
+ if (bindname == NULL)
+ return (NULL);
+ if (init(ctx) == -1) {
+ free(bindname);
return (NULL);
+ }
- if ((retvec = get_txt_records(ctx, C_IN, bindname)))
+ if ((retvec = get_txt_records(ctx, C_IN, bindname))) {
+ free(bindname);
return (retvec);
+ }
if (errno != ENOENT)
return (NULL);
@@ -322,8 +336,6 @@ parse_config_file(struct hesiod_p *ctx, const char *filename) {
/*
* Given a DNS class and a DNS name, do a lookup for TXT records, and
* return a list of them.
- *
- * XXX we're still using the non-thread safe res_* routines.
*/
static char **
get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
@@ -333,7 +345,6 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
int dlen; /* len of data section */
u_char *data; /* pointer to data */
} rr;
- struct __res_state save_res;
HEADER *hp;
u_char qbuf[MAX_HESRESP], abuf[MAX_HESRESP];
u_char *cp, *erdata, *eom;
@@ -342,22 +353,15 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
int i, j, n, skip;
/*
- * Construct the query and send it. We play games with _res
- * since we don't have our own resolver state. Once the
- * resolver routines are rewritten to use their own context
- * variable, we'll use it here.
+ * Construct the query and send it.
*/
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
- return (NULL);
- save_res = _res;
- n = res_mkquery(QUERY, name, class, T_TXT, NULL, 0,
- NULL, qbuf, MAX_HESRESP);
+ n = res_nmkquery(ctx->res, QUERY, name, class, T_TXT, NULL, 0,
+ NULL, qbuf, MAX_HESRESP);
if (n < 0) {
errno = EMSGSIZE;
return (NULL);
}
- n = res_send(qbuf, n, abuf, MAX_HESRESP);
- _res = save_res;
+ n = res_nsend(ctx->res, qbuf, n, abuf, MAX_HESRESP);
if (n < 0) {
errno = ECONNREFUSED;
return (NULL);
@@ -452,3 +456,48 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
free(list);
return (NULL);
}
+
+struct __res_state *
+__hesiod_res_get(void *context) {
+ struct hesiod_p *ctx = context;
+
+ if (!ctx->res) {
+ struct __res_state *res;
+ res = (struct __res_state *)malloc(sizeof *res);
+ if (res == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(res, 0, sizeof *res);
+ __hesiod_res_set(ctx, res, free);
+ }
+
+ return (ctx->res);
+}
+
+void
+__hesiod_res_set(void *context, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct hesiod_p *ctx = context;
+
+ if (ctx->res && ctx->free_res) {
+ res_nclose(ctx->res);
+ (*ctx->free_res)(ctx->res);
+ }
+
+ ctx->res = res;
+ ctx->free_res = free_res;
+}
+
+static int
+init(struct hesiod_p *ctx) {
+
+ if (!ctx->res && !__hesiod_res_get(ctx))
+ return (-1);
+
+ if (((ctx->res->options & RES_INIT) == 0) &&
+ (res_ninit(ctx->res) == -1))
+ return (-1);
+
+ return (0);
+}
diff --git a/contrib/bind/lib/irs/hesiod_p.h b/contrib/bind/lib/irs/hesiod_p.h
index d2204db..eb32166 100644
--- a/contrib/bind/lib/irs/hesiod_p.h
+++ b/contrib/bind/lib/irs/hesiod_p.h
@@ -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
@@ -20,7 +20,7 @@
*/
/*
- * $Id: hesiod_p.h,v 1.6 1996/11/18 09:09:32 vixie Exp $
+ * $Id: hesiod_p.h,v 1.9 1999/01/08 19:24:39 vixie Exp $
*/
/*
@@ -36,6 +36,11 @@
struct hesiod_p {
char * LHS; /* normally ".ns" */
char * RHS; /* AKA the default hesiod domain */
+ struct __res_state * res; /* resolver context */
+ void (*free_res)(void *);
+ void (*res_set)(struct hesiod_p *, struct __res_state *,
+ void (*)(void *));
+ struct __res_state * (*res_get)(struct hesiod_p *);
};
#define MAX_HESRESP 1024
diff --git a/contrib/bind/lib/irs/irp.c b/contrib/bind/lib/irs/irp.c
new file mode 100644
index 0000000..c2b64ab
--- /dev/null
+++ b/contrib/bind/lib/irs/irp.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 1996, 1998 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if !defined(LINT) && !defined(CODECENTER)
+static const char rcsid[] = "$Id: irp.c,v 8.5 1999/10/13 17:11:18 vixie Exp $";
+#endif
+
+/* Imports */
+
+#include "port_before.h"
+
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include <isc/memcluster.h>
+
+#include <irs.h>
+#include <irp.h>
+
+#include "irs_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
+/* Forward. */
+
+static void irp_close(struct irs_acc *);
+
+#define LINEINCR 128
+
+#if !defined(SUN_LEN)
+#define SUN_LEN(su) \
+ (sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path))
+#endif
+
+
+/* Public */
+
+
+/* send errors to syslog if true. */
+int irp_log_errors = 1;
+
+/*
+ * This module handles the irp module connection to irpd.
+ *
+ * The client expects a synchronous interface to functions like
+ * getpwnam(3), so we can't use the ctl_* i/o library on this end of
+ * the wire (it's used in the server).
+ */
+
+/*
+ * irs_acc *irs_irp_acc(const char *options);
+ *
+ * Initialize the irp module.
+ */
+struct irs_acc *
+irs_irp_acc(const char *options) {
+ struct irs_acc *acc;
+ struct irp_p *irp;
+
+ if (!(acc = memget(sizeof *acc))) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(acc, 0x5e, sizeof *acc);
+ if (!(irp = memget(sizeof *irp))) {
+ errno = ENOMEM;
+ free(acc);
+ return (NULL);
+ }
+ irp->inlast = 0;
+ irp->incurr = 0;
+ irp->fdCxn = -1;
+ acc->private = irp;
+
+#ifdef WANT_IRS_GR
+ acc->gr_map = irs_irp_gr;
+#else
+ acc->gr_map = NULL;
+#endif
+#ifdef WANT_IRS_PW
+ acc->pw_map = irs_irp_pw;
+#else
+ acc->pw_map = NULL;
+#endif
+ acc->sv_map = irs_irp_sv;
+ acc->pr_map = irs_irp_pr;
+ acc->ho_map = irs_irp_ho;
+ acc->nw_map = irs_irp_nw;
+ acc->ng_map = irs_irp_ng;
+ acc->close = irp_close;
+ return (acc);
+}
+
+
+int
+irs_irp_connection_setup(struct irp_p *cxndata, int *warned) {
+ if (irs_irp_is_connected(cxndata)) {
+ return (0);
+ } else if (irs_irp_connect(cxndata) != 0) {
+ if (warned != NULL && !*warned) {
+ syslog(LOG_ERR, "irpd connection failed: %m\n");
+ (*warned)++;
+ }
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * int irs_irp_connect(void);
+ *
+ * Sets up the connection to the remote irpd server.
+ *
+ * Returns:
+ *
+ * 0 on success, -1 on failure.
+ *
+ */
+int
+irs_irp_connect(struct irp_p *pvt) {
+ int flags;
+ struct sockaddr *addr;
+ struct sockaddr_in iaddr;
+ struct sockaddr_un uaddr;
+ long ipaddr;
+ const char *irphost;
+ int code;
+ char text[256];
+ int socklen = 0;
+
+ if (pvt->fdCxn != -1) {
+ perror("fd != 1");
+ return (-1);
+ }
+
+ memset(&uaddr, 0, sizeof uaddr);
+ memset(&iaddr, 0, sizeof iaddr);
+
+ irphost = getenv(IRPD_HOST_ENV);
+ if (irphost == NULL) {
+ irphost = "127.0.0.1";
+ }
+
+ if (irphost[0] == '/') {
+ addr = (struct sockaddr *)&uaddr;
+ strncpy(uaddr.sun_path, irphost, sizeof uaddr.sun_path);
+ uaddr.sun_family = AF_UNIX;
+ socklen = SUN_LEN(&uaddr);
+#ifdef HAVE_SA_LEN
+ uaddr.sun_len = socklen;
+#endif
+ } else {
+ if (inet_pton(AF_INET, irphost, &ipaddr) != 1) {
+ errno = EADDRNOTAVAIL;
+ perror("inet_pton");
+ return (-1);
+ }
+
+ addr = (struct sockaddr *)&iaddr;
+ socklen = sizeof iaddr;
+#ifdef HAVE_SA_LEN
+ iaddr.sin_len = socklen;
+#endif
+ iaddr.sin_family = AF_INET;
+ iaddr.sin_port = htons(IRPD_PORT);
+ iaddr.sin_addr.s_addr = ipaddr;
+ }
+
+
+ pvt->fdCxn = socket(addr->sa_family, SOCK_STREAM, PF_UNSPEC);
+ if (pvt->fdCxn < 0) {
+ perror("socket");
+ return (-1);
+ }
+
+ if (connect(pvt->fdCxn, addr, socklen) != 0) {
+ perror("connect");
+ return (-1);
+ }
+
+ flags = fcntl(pvt->fdCxn, F_GETFL, 0);
+ if (flags < 0) {
+ close(pvt->fdCxn);
+ perror("close");
+ return (-1);
+ }
+
+#if 0
+ flags |= O_NONBLOCK;
+ if (fcntl(pvt->fdCxn, F_SETFL, flags) < 0) {
+ close(pvt->fdCxn);
+ perror("fcntl");
+ return (-1);
+ }
+#endif
+
+ code = irs_irp_read_response(pvt, text, sizeof text);
+ if (code != IRPD_WELCOME_CODE) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "Connection failed: %s", text);
+ }
+ irs_irp_disconnect(pvt);
+ return (-1);
+ }
+
+ return (0);
+}
+
+
+
+/*
+ * int irs_irp_is_connected(struct irp_p *pvt);
+ *
+ * Returns:
+ *
+ * Non-zero if streams are setup to remote.
+ *
+ */
+
+int
+irs_irp_is_connected(struct irp_p *pvt) {
+ return (pvt->fdCxn >= 0);
+}
+
+
+
+/*
+ * void
+ * irs_irp_disconnect(struct irp_p *pvt);
+ *
+ * Closes streams to remote.
+ */
+
+void
+irs_irp_disconnect(struct irp_p *pvt) {
+ if (pvt->fdCxn != -1) {
+ close(pvt->fdCxn);
+ pvt->fdCxn = -1;
+ }
+}
+
+
+
+int
+irs_irp_read_line(struct irp_p *pvt, char *buffer, int len) {
+ char *realstart = &pvt->inbuffer[0];
+ char *p, *start, *end;
+ int spare;
+ int i;
+ int buffpos = 0;
+ int left = len - 1;
+
+ while (left > 0) {
+ start = p = &pvt->inbuffer[pvt->incurr];
+ end = &pvt->inbuffer[pvt->inlast];
+
+ while (p != end && *p != '\n')
+ p++;
+
+ if (p == end) {
+ /* Found no newline so shift data down if necessary
+ * and append new data to buffer
+ */
+ if (start > realstart) {
+ memmove(realstart, start, end - start);
+ pvt->inlast = end - start;
+ start = realstart;
+ pvt->incurr = 0;
+ end = &pvt->inbuffer[pvt->inlast];
+ }
+
+ spare = sizeof (pvt->inbuffer) - pvt->inlast;
+
+ p = end;
+ i = read(pvt->fdCxn, end, spare);
+ if (i < 0) {
+ close(pvt->fdCxn);
+ pvt->fdCxn = -1;
+ return (buffpos > 0 ? buffpos : -1);
+ } else if (i == 0) {
+ return (buffpos);
+ }
+
+ end += i;
+ pvt->inlast += i;
+
+ while (p != end && *p != '\n')
+ p++;
+ }
+
+ if (p == end) {
+ /* full buffer and still no newline */
+ i = sizeof pvt->inbuffer;
+ } else {
+ /* include newline */
+ i = p - start + 1;
+ }
+
+ if (i > left)
+ i = left;
+ memcpy(buffer + buffpos, start, i);
+ pvt->incurr += i;
+ buffpos += i;
+ buffer[buffpos] = '\0';
+
+ if (p != end) {
+ left = 0;
+ } else {
+ left -= i;
+ }
+ }
+
+#if 0
+ fprintf(stderr, "read line: %s\n", buffer);
+#endif
+ return (buffpos);
+}
+
+
+
+
+
+/*
+ * int irp_read_response(struct irp_p *pvt);
+ *
+ * Returns:
+ *
+ * The number found at the beginning of the line read from
+ * FP. 0 on failure(0 is not a legal response code). The
+ * rest of the line is discarded.
+ *
+ */
+
+int
+irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen) {
+ char line[1024];
+ int code;
+ char *p;
+
+ if (irs_irp_read_line(pvt, line, sizeof line) <= 0) {
+ return (0);
+ }
+
+ p = strchr(line, '\n');
+ if (p == NULL) {
+ return (0);
+ }
+
+ if (sscanf(line, "%d", &code) != 1) {
+ code = 0;
+ } else if (text != NULL && textlen > 0) {
+ p = line;
+ while (isspace(*p)) p++;
+ while (isdigit(*p)) p++;
+ while (isspace(*p)) p++;
+ strncpy(text, p, textlen - 1);
+ p[textlen - 1] = '\0';
+ }
+
+ return (code);
+}
+
+
+
+/*
+ * char *irp_read_body(struct irp_p *pvt, size_t *size);
+ *
+ * Read in the body of a response. Terminated by a line with
+ * just a dot on it. Lines should be terminated with a CR-LF
+ * sequence, but we're nt piccky if the CR is missing.
+ * No leading dot escaping is done as the protcol doesn't
+ * use leading dots anywhere.
+ *
+ * Returns:
+ *
+ * Pointer to null-terminated buffer allocated by memget.
+ * *SIZE is set to the length of the buffer.
+ *
+ */
+
+char *
+irs_irp_read_body(struct irp_p *pvt, size_t *size) {
+ char line[1024];
+ u_int linelen;
+ size_t len = LINEINCR;
+ char *buffer = memget(len);
+ int idx = 0;
+
+ for (;;) {
+ if (irs_irp_read_line(pvt, line, sizeof line) <= 0 ||
+ strchr(line, '\n') == NULL)
+ goto death;
+
+ linelen = strlen(line);
+
+ if (line[linelen - 1] != '\n')
+ goto death;
+
+ /* We're not strict about missing \r. Should we be?? */
+ if (linelen > 2 && line[linelen - 2] == '\r') {
+ line[linelen - 2] = '\n';
+ line[linelen - 1] = '\0';
+ linelen--;
+ }
+
+ if (linelen == 2 && line[0] == '.') {
+ *size = len;
+ buffer[idx] = '\0';
+
+ return (buffer);
+ }
+
+ if (linelen > (len - (idx + 1))) {
+ char *p = memget(len + LINEINCR);
+
+ if (p == NULL)
+ goto death;
+ memcpy(p, buffer, len);
+ memput(buffer, len);
+ buffer = p;
+ len += LINEINCR;
+ }
+
+ memcpy(buffer + idx, line, linelen);
+ idx += linelen;
+ }
+ death:
+ memput(buffer, len);
+ return (NULL);
+}
+
+
+/*
+ * int irs_irp_get_full_response(struct irp_p *pvt, int *code,
+ * char **body, size_t *bodylen);
+ *
+ * Gets the response to a command. If the response indicates
+ * there's a body to follow(code % 10 == 1), then the
+ * body buffer is allcoated with memget and stored in
+ * *BODY. The length of the allocated body buffer is stored
+ * in *BODY. The caller must give the body buffer back to
+ * memput when done. The results code is stored in *CODE.
+ *
+ * Returns:
+ *
+ * 0 if a result was read. -1 on some sort of failure.
+ *
+ */
+
+int
+irs_irp_get_full_response(struct irp_p *pvt, int *code, char *text,
+ size_t textlen, char **body, size_t *bodylen) {
+ int result = irs_irp_read_response(pvt, text, textlen);
+
+ *body = NULL;
+
+ if (result == 0) {
+ return (-1);
+ }
+
+ *code = result;
+
+ /* Code that matches 2xx is a good result code.
+ * Code that matches xx1 means there's a response body coming.
+ */
+ if ((result / 100) == 2 && (result % 10) == 1) {
+ *body = irs_irp_read_body(pvt, bodylen);
+ if (*body == NULL) {
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+ * int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...);
+ *
+ * Sends command to remote connected via the PVT
+ * struture. FMT and args after it are fprintf-like
+ * arguments for formatting.
+ *
+ * Returns:
+ *
+ * 0 on success, -1 on failure.
+ */
+
+int
+irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) {
+ va_list ap;
+ char buffer[1024];
+ int pos = 0;
+ int i, todo;
+
+
+ if (pvt->fdCxn < 0) {
+ return (-1);
+ }
+
+ va_start(ap, fmt);
+ todo = vsprintf(buffer, fmt, ap);
+ if (todo > sizeof buffer - 2) {
+ syslog(LOG_CRIT, "memory overrun in irs_irp_send_command()");
+ exit(1);
+ }
+ strcat(buffer, "\r\n");
+ todo = strlen(buffer);
+
+ while (todo > 0) {
+ i = write(pvt->fdCxn, buffer + pos, todo);
+#if 0
+ /* XXX brister */
+ fprintf(stderr, "Wrote: \"");
+ fwrite(buffer + pos, sizeof (char), todo, stderr);
+ fprintf(stderr, "\"\n");
+#endif
+ if (i < 0) {
+ close(pvt->fdCxn);
+ pvt->fdCxn = -1;
+ return (-1);
+ }
+ todo -= i;
+ }
+ va_end(ap);
+
+ return (0);
+}
+
+
+/* Methods */
+
+
+
+/*
+ * void irp_close(struct irs_acc *this)
+ *
+ */
+
+static void
+irp_close(struct irs_acc *this) {
+ struct irp_p *irp = (struct irp_p *)this->private;
+
+ if (irp != NULL) {
+ irs_irp_disconnect(irp);
+ memput(irp, sizeof *irp);
+ }
+
+ memput(this, sizeof *this);
+}
+
+
+
diff --git a/contrib/bind/lib/irs/irp_gr.c b/contrib/bind/lib/irs/irp_gr.c
new file mode 100644
index 0000000..4e2a28c
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_gr.c
@@ -0,0 +1,405 @@
+/*
+ * Portions Copyright(c) 1996, 1998 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: irp_gr.c,v 8.1 1999/01/18 07:46:53 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/* extern */
+
+#include "port_before.h"
+
+#ifndef WANT_IRS_PW
+static int __bind_irs_gr_unneeded;
+#else
+
+#include <syslog.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#include <irs.h>
+#include <irp.h>
+#include <isc/memcluster.h>
+#include <isc/irpmarshall.h>
+
+#include "irs_p.h"
+#include "lcl_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
+
+/* Types. */
+
+/*
+ * Module for the getnetgrent(3) family to use when connected to a
+ * remote irp daemon.
+ *
+ * See irpd.c for justification of caching done here.
+ *
+ */
+
+struct pvt {
+ struct irp_p *girpdata; /* global IRP data */
+ int warned;
+ struct group group;
+};
+
+/* Forward. */
+
+static void gr_close(struct irs_gr *);
+static struct group * gr_next(struct irs_gr *);
+static struct group * gr_byname(struct irs_gr *, const char *);
+static struct group * gr_bygid(struct irs_gr *, gid_t);
+static void gr_rewind(struct irs_gr *);
+static void gr_minimize(struct irs_gr *);
+
+/* Private */
+static void free_group(struct group *gr);
+
+
+/* Public. */
+
+
+
+
+
+/*
+ * struct irs_gr * irs_irp_gr(struct irs_acc *this)
+ *
+ * Notes:
+ *
+ * Initialize the group sub-module.
+ *
+ * Notes:
+ *
+ * Module data.
+ *
+ */
+
+struct irs_gr *
+irs_irp_gr(struct irs_acc *this) {
+ struct irs_gr *gr;
+ struct pvt *pvt;
+
+ if (!(gr = memget(sizeof *gr))) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(gr, 0x0, sizeof *gr);
+
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(gr, sizeof *gr);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pvt, 0x0, sizeof *pvt);
+ pvt->girpdata = this->private;
+
+ gr->private = pvt;
+ gr->close = gr_close;
+ gr->next = gr_next;
+ gr->byname = gr_byname;
+ gr->bygid = gr_bygid;
+ gr->rewind = gr_rewind;
+ gr->list = make_group_list;
+ gr->minimize = gr_minimize;
+ return (gr);
+}
+
+/* Methods. */
+
+
+
+/*
+ * void gr_close(struct irs_gr *this)
+ *
+ * Notes:
+ *
+ * Close the sub-module.
+ *
+ */
+
+static void
+gr_close(struct irs_gr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ gr_minimize(this);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
+}
+
+
+
+
+/*
+ * struct group * gr_next(struct irs_gr *this)
+ *
+ * Notes:
+ *
+ * Gets the next group out of the cached data and returns it.
+ *
+ */
+
+static struct group *
+gr_next(struct irs_gr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct group *gr = &pvt->group;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getgrent") != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "getgrent failed: %s", text);
+ }
+ return (NULL);
+ }
+
+ if (code == IRPD_GETGROUP_OK) {
+ free_group(gr);
+ if (irp_unmarshall_gr(gr, body) != 0) {
+ gr = NULL;
+ }
+ } else {
+ gr = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (gr);
+}
+
+
+
+
+
+/*
+ * struct group * gr_byname(struct irs_gr *this, const char *name)
+ *
+ * Notes:
+ *
+ * Gets a group by name from irpd and returns it.
+ *
+ */
+
+static struct group *
+gr_byname(struct irs_gr *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct group *gr = &pvt->group;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+
+ if (gr->gr_name != NULL && strcmp(name, gr->gr_name) == 0) {
+ return (gr);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getgrnam %s", name) != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETGROUP_OK) {
+ free_group(gr);
+ if (irp_unmarshall_gr(gr, body) != 0) {
+ gr = NULL;
+ }
+ } else {
+ gr = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (gr);
+}
+
+
+
+
+
+/*
+ * struct group * gr_bygid(struct irs_gr *this, gid_t gid)
+ *
+ * Notes:
+ *
+ * Gets a group by gid from irpd and returns it.
+ *
+ */
+
+static struct group *
+gr_bygid(struct irs_gr *this, gid_t gid) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct group *gr = &pvt->group;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (gr->gr_name != NULL && gr->gr_gid == gid) {
+ return (gr);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getgrgid %d", gid) != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETGROUP_OK) {
+ free_group(gr);
+ if (irp_unmarshall_gr(gr, body) != 0) {
+ gr = NULL;
+ }
+ } else {
+ gr = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (gr);
+}
+
+
+
+
+/*
+ * void gr_rewind(struct irs_gr *this)
+ *
+ */
+
+static void
+gr_rewind(struct irs_gr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char text[256];
+ int code;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return;
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "setgrent") != 0) {
+ return;
+ }
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code != IRPD_GETGROUP_SETOK) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "setgrent failed: %s", text);
+ }
+ }
+
+ return;
+}
+
+
+
+
+/*
+ * void gr_minimize(struct irs_gr *this)
+ *
+ * Notes:
+ *
+ * Frees up cached data and disconnects(if necessary) from the remote.
+ *
+ */
+
+static void
+gr_minimize(struct irs_gr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ free_group(&pvt->group);
+ irs_irp_disconnect(pvt->girpdata);
+}
+
+/* Private. */
+
+
+
+/*
+ * static void free_group(struct group *gr);
+ *
+ * Deallocate all the memory irp_unmarshall_gr allocated.
+ *
+ */
+
+static void
+free_group(struct group *gr) {
+ char **p;
+
+ if (gr == NULL)
+ return;
+
+ if (gr->gr_name != NULL)
+ free(gr->gr_name);
+
+ if (gr->gr_passwd != NULL)
+ free(gr->gr_passwd);
+
+ for (p = gr->gr_mem ; p != NULL && *p != NULL ; p++)
+ free(*p);
+
+ if (p != NULL)
+ free(p);
+}
+
+
+#endif /* WANT_IRS_GR */
diff --git a/contrib/bind/lib/irs/irp_ho.c b/contrib/bind/lib/irs/irp_ho.c
new file mode 100644
index 0000000..7bfd0e2
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_ho.c
@@ -0,0 +1,418 @@
+/*
+ * Portions Copyright (c) 1996,1998 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: irp_ho.c,v 8.2 1999/10/13 16:39:31 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/* Imports. */
+
+#include "port_before.h"
+
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <irs.h>
+#include <irp.h>
+#include <isc/irpmarshall.h>
+#include <isc/memcluster.h>
+
+#include "irs_p.h"
+#include "dns_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
+/* Definitions. */
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+#define Max(a,b) ((a) > (b) ? (a) : (b))
+
+
+struct pvt {
+ struct irp_p *girpdata;
+ int warned;
+ struct hostent host;
+};
+
+/* Forward. */
+
+static void ho_close(struct irs_ho *this);
+static struct hostent * ho_byname(struct irs_ho *this, const char *name);
+static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
+ int af);
+static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
+ int len, int af);
+static struct hostent * ho_next(struct irs_ho *this);
+static void ho_rewind(struct irs_ho *this);
+static void ho_minimize(struct irs_ho *this);
+
+static void free_host(struct hostent *ho);
+
+
+/* Public. */
+
+
+
+/*
+ * struct irs_ho * irs_irp_ho(struct irs_acc *this)
+ *
+ * Notes:
+ *
+ * Initializes the irp_ho module.
+ *
+ */
+
+struct irs_ho *
+irs_irp_ho(struct irs_acc *this) {
+ struct irs_ho *ho;
+ struct pvt *pvt;
+
+ if (!(ho = memget(sizeof *ho))) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(ho, 0x0, sizeof *ho);
+
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(ho, sizeof *ho);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pvt, 0, sizeof *pvt);
+ pvt->girpdata = this->private;
+
+ ho->private = pvt;
+ ho->close = ho_close;
+ ho->byname = ho_byname;
+ ho->byname2 = ho_byname2;
+ ho->byaddr = ho_byaddr;
+ ho->next = ho_next;
+ ho->rewind = ho_rewind;
+ ho->minimize = ho_minimize;
+
+ return (ho);
+}
+
+/* Methods. */
+
+
+
+/*
+ * void ho_close(struct irs_ho *this)
+ *
+ * Notes:
+ *
+ * Closes down the module.
+ *
+ */
+
+static void
+ho_close(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ ho_minimize(this);
+
+ free_host(&pvt->host);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
+}
+
+
+
+/*
+ * struct hostent * ho_byname(struct irs_ho *this, const char *name)
+ *
+ */
+
+static struct hostent *
+ho_byname(struct irs_ho *this, const char *name) {
+ return (ho_byname2(this, name, AF_INET));
+}
+
+
+
+
+
+/*
+ * struct hostent * ho_byname2(struct irs_ho *this, const char *name, int af)
+ *
+ */
+
+static struct hostent *
+ho_byname2(struct irs_ho *this, const char *name, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct hostent *ho = &pvt->host;
+ char *body = NULL;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (ho->h_name != NULL &&
+ strcmp(name, ho->h_name) == 0 &&
+ af == ho->h_addrtype) {
+ return (ho);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "gethostbyname2 %s %s",
+ name, ADDR_T_STR(af)) != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETHOST_OK) {
+ free_host(ho);
+ if (irp_unmarshall_ho(ho, body) != 0) {
+ ho = NULL;
+ }
+ } else {
+ ho = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (ho);
+}
+
+
+
+/*
+ * struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
+ * int len, int af)
+ *
+ */
+
+static struct hostent *
+ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct hostent *ho = &pvt->host;
+ char *body = NULL;
+ size_t bodylen;
+ int code;
+ char **p;
+ char paddr[MAXPADDRSIZE];
+ char text[256];
+
+ if (ho->h_name != NULL &&
+ af == ho->h_addrtype &&
+ len == ho->h_length) {
+ for (p = ho->h_addr_list ; *p != NULL ; p++) {
+ if (memcmp(*p, addr, len) == 0)
+ return (ho);
+ }
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (inet_ntop(af, addr, paddr, sizeof paddr) == NULL) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "gethostbyaddr %s %s",
+ paddr, ADDR_T_STR(af)) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETHOST_OK) {
+ free_host(ho);
+ if (irp_unmarshall_ho(ho, body) != 0) {
+ ho = NULL;
+ }
+ } else {
+ ho = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (ho);
+}
+
+
+
+
+
+/*
+ * struct hostent * ho_next(struct irs_ho *this)
+ *
+ * Notes:
+ *
+ * The implementation for gethostent(3). The first time it's
+ * called all the data is pulled from the remote(i.e. what
+ * the maximum number of gethostent(3) calls would return)
+ * and that data is cached.
+ *
+ */
+
+static struct hostent *
+ho_next(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct hostent *ho = &pvt->host;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "gethostent") != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETHOST_OK) {
+ free_host(ho);
+ if (irp_unmarshall_ho(ho, body) != 0) {
+ ho = NULL;
+ }
+ } else {
+ ho = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (ho);
+}
+
+
+
+
+
+/*
+ * void ho_rewind(struct irs_ho *this)
+ *
+ */
+
+static void
+ho_rewind(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char text[256];
+ int code;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return;
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "sethostent") != 0) {
+ return;
+ }
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code != IRPD_GETHOST_SETOK) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "sethostent failed: %s", text);
+ }
+ }
+
+ return;
+}
+
+
+
+
+/*
+ * void ho_minimize(struct irs_ho *this)
+ *
+ */
+
+static void
+ho_minimize(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ free_host(&pvt->host);
+
+ irs_irp_disconnect(pvt->girpdata);
+}
+
+
+
+
+/*
+ * void free_host(struct hostent *ho)
+ *
+ */
+
+static void
+free_host(struct hostent *ho) {
+ char **p;
+
+ if (ho == NULL) {
+ return;
+ }
+
+ if (ho->h_name != NULL)
+ free(ho->h_name);
+
+ if (ho->h_aliases != NULL) {
+ for (p = ho->h_aliases ; *p != NULL ; p++)
+ free(*p);
+ free(ho->h_aliases);
+ }
+
+ if (ho->h_addr_list != NULL) {
+ for (p = ho->h_addr_list ; *p != NULL ; p++)
+ free(*p);
+ free(ho->h_addr_list);
+ }
+}
+
diff --git a/contrib/bind/lib/irs/irp_ng.c b/contrib/bind/lib/irs/irp_ng.c
new file mode 100644
index 0000000..e96f66c
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_ng.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 1996, 1998 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if !defined(LINT) && !defined(CODECENTER)
+static const char rcsid[] = "$Id: irp_ng.c,v 8.2 1999/10/13 16:39:31 vixie Exp $";
+#endif
+
+/* Imports */
+
+#include "port_before.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#include <irs.h>
+#include <irp.h>
+#include <isc/memcluster.h>
+#include <isc/irpmarshall.h>
+
+#include "irs_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
+/* Definitions */
+
+struct pvt {
+ struct irp_p *girpdata;
+ int warned;
+};
+
+
+/* Forward */
+
+static void ng_rewind(struct irs_ng *, const char*);
+static void ng_close(struct irs_ng *);
+static int ng_next(struct irs_ng *, char **, char **, char **);
+static int ng_test(struct irs_ng *, const char *,
+ const char *, const char *,
+ const char *);
+static void ng_minimize(struct irs_ng *);
+
+
+/* Public */
+
+
+
+/*
+ * struct irs_ng * irs_irp_ng(struct irs_acc *this)
+ *
+ * Notes:
+ *
+ * Intialize the irp netgroup module.
+ *
+ */
+
+struct irs_ng *
+irs_irp_ng(struct irs_acc *this) {
+ struct irs_ng *ng;
+ struct pvt *pvt;
+
+ if (!(ng = memget(sizeof *ng))) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(ng, 0x5e, sizeof *ng);
+
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(ng, sizeof *ng);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pvt, 0, sizeof *pvt);
+ pvt->girpdata = this->private;
+
+ ng->private = pvt;
+ ng->close = ng_close;
+ ng->next = ng_next;
+ ng->test = ng_test;
+ ng->rewind = ng_rewind;
+ ng->minimize = ng_minimize;
+ return (ng);
+}
+
+/* Methods */
+
+
+
+/*
+ * void ng_close(struct irs_ng *this)
+ *
+ */
+
+static void
+ng_close(struct irs_ng *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ ng_minimize(this);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
+}
+
+
+
+
+/*
+ * void ng_rewind(struct irs_ng *this, const char *group)
+ *
+ *
+ */
+
+static void
+ng_rewind(struct irs_ng *this, const char *group) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char text[256];
+ int code;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return;
+ }
+
+ if (irs_irp_send_command(pvt->girpdata,
+ "setnetgrent %s", group) != 0) {
+ return;
+ }
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code != IRPD_GETNETGR_SETOK) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "setnetgrent(%s) failed: %s",
+ group, text);
+ }
+ }
+
+ return;
+}
+
+
+
+
+/*
+ * int ng_next(struct irs_ng *this, char **host, char **user, char **domain)
+ *
+ * Notes:
+ *
+ * Get the next netgroup item from the cache.
+ *
+ */
+
+static int
+ng_next(struct irs_ng *this, char **host, char **user, char **domain) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ int code;
+ char *body = NULL;
+ size_t bodylen;
+ int rval = 0;
+ char text[256];
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (0);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getnetgrent") != 0)
+ return (0);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (0);
+ }
+
+ if (code == IRPD_GETNETGR_OK) {
+ if (irp_unmarshall_ng(host, user, domain, body) == 0) {
+ rval = 1;
+ }
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (rval);
+}
+
+
+
+/*
+ * int ng_test(struct irs_ng *this, const char *name, const char *host,
+ * const char *user, const char *domain)
+ *
+ * Notes:
+ *
+ * Search for a match in a netgroup.
+ *
+ */
+
+static int
+ng_test(struct irs_ng *this, const char *name,
+ const char *host, const char *user, const char *domain)
+{
+ struct pvt *pvt = (struct pvt *)this->private;
+ char *body = NULL;
+ size_t bodylen = 0;
+ int code;
+ char text[256];
+ int rval = 0;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (0);
+ }
+
+ if (irp_marshall_ng(host, user, domain, &body, &bodylen) != 0) {
+ return (0);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "innetgr %s", body) == 0) {
+ memput(body, bodylen);
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code == IRPD_GETNETGR_MATCHES) {
+ rval = 1;
+ }
+ }
+
+ return (rval);
+}
+
+
+
+
+/*
+ * void ng_minimize(struct irs_ng *this)
+ *
+ */
+
+static void
+ng_minimize(struct irs_ng *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ irs_irp_disconnect(pvt->girpdata);
+}
+
+
+
+
+/* Private */
+
diff --git a/contrib/bind/lib/irs/irp_nw.c b/contrib/bind/lib/irs/irp_nw.c
new file mode 100644
index 0000000..c0bcbfa
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_nw.c
@@ -0,0 +1,375 @@
+/*
+ * Portions Copyright (c) 1996,1998 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: irp_nw.c,v 8.1 1999/01/18 07:46:54 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#if 0
+
+#endif
+
+/* Imports */
+
+#include "port_before.h"
+
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <irs.h>
+#include <irp.h>
+#include <isc/irpmarshall.h>
+
+#include <isc/memcluster.h>
+#include <isc/misc.h>
+
+#include "irs_p.h"
+#include "lcl_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
+#define MAXALIASES 35
+#define MAXADDRSIZE 4
+
+struct pvt {
+ struct irp_p *girpdata;
+ int warned;
+ struct nwent net;
+};
+
+/* Forward */
+
+static void nw_close(struct irs_nw *);
+static struct nwent * nw_byname(struct irs_nw *, const char *, int);
+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 void free_nw(struct nwent *nw);
+
+
+/* Public */
+
+
+
+/*
+ * struct irs_nw * irs_irp_nw(struct irs_acc *this)
+ *
+ */
+
+struct irs_nw *
+irs_irp_nw(struct irs_acc *this) {
+ struct irs_nw *nw;
+ struct pvt *pvt;
+
+ if (!(pvt = memget(sizeof *pvt))) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pvt, 0, sizeof *pvt);
+
+ if (!(nw = memget(sizeof *nw))) {
+ memput(pvt, sizeof *pvt);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(nw, 0x0, sizeof *nw);
+ pvt->girpdata = this->private;
+
+ nw->private = pvt;
+ nw->close = nw_close;
+ nw->byname = nw_byname;
+ nw->byaddr = nw_byaddr;
+ nw->next = nw_next;
+ nw->rewind = nw_rewind;
+ nw->minimize = nw_minimize;
+ return (nw);
+}
+
+/* Methods */
+
+
+
+/*
+ * void nw_close(struct irs_nw *this)
+ *
+ */
+
+static void
+nw_close(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ nw_minimize(this);
+
+ free_nw(&pvt->net);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
+}
+
+
+
+
+/*
+ * struct nwent * nw_byaddr(struct irs_nw *this, void *net,
+ * int length, int type)
+ *
+ */
+
+static struct nwent *
+nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct nwent *nw = &pvt->net;
+ char *body = NULL;
+ size_t bodylen;
+ int code;
+ char paddr[24]; /* bigenough for ip4 w/ cidr spec. */
+ char text[256];
+
+ if (inet_net_ntop(type, net, length, paddr, sizeof paddr) == NULL) {
+ return (NULL);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getnetbyaddr %s %s",
+ paddr, ADDR_T_STR(type)) != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETNET_OK) {
+ free_nw(nw);
+ if (irp_unmarshall_nw(nw, body) != 0) {
+ nw = NULL;
+ }
+ } else {
+ nw = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (nw);
+}
+
+
+
+
+/*
+ * struct nwent * nw_byname(struct irs_nw *this, const char *name, int type)
+ *
+ */
+
+static struct nwent *
+nw_byname(struct irs_nw *this, const char *name, int type) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct nwent *nw = &pvt->net;
+ char *body = NULL;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (nw->n_name != NULL &&
+ strcmp(name, nw->n_name) == 0 &&
+ nw->n_addrtype == type) {
+ return (nw);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getnetbyname %s", name) != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETNET_OK) {
+ free_nw(nw);
+ if (irp_unmarshall_nw(nw, body) != 0) {
+ nw = NULL;
+ }
+ } else {
+ nw = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (nw);
+}
+
+
+
+
+/*
+ * void nw_rewind(struct irs_nw *this)
+ *
+ */
+
+static void
+nw_rewind(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char text[256];
+ int code;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return;
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "setnetent") != 0) {
+ return;
+ }
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code != IRPD_GETNET_SETOK) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "setnetent failed: %s", text);
+ }
+ }
+
+ return;
+}
+
+
+
+
+
+
+/*
+ * struct nwent * nw_next(struct irs_nw *this)
+ *
+ * Notes:
+ *
+ * Prepares the cache if necessary and returns the first, or
+ * next item from it.
+ */
+
+static struct nwent *
+nw_next(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct nwent *nw = &pvt->net;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getnetent") != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETNET_OK) {
+ free_nw(nw);
+ if (irp_unmarshall_nw(nw, body) != 0) {
+ nw = NULL;
+ }
+ } else {
+ nw = NULL;
+ }
+
+ return (nw);
+}
+
+
+
+
+
+
+/*
+ * void nw_minimize(struct irs_nw *this)
+ *
+ */
+
+static void
+nw_minimize(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ irs_irp_disconnect(pvt->girpdata);
+}
+
+
+
+
+/* private. */
+
+
+
+/*
+ * static void free_passwd(struct passwd *pw);
+ *
+ * deallocate all the memory irp_unmarshall_pw allocated.
+ *
+ */
+
+static void
+free_nw(struct nwent *nw) {
+ char **p;
+
+ if (nw == NULL)
+ return;
+
+ if (nw->n_name != NULL)
+ free(nw->n_name);
+
+ if (nw->n_aliases != NULL) {
+ for (p = nw->n_aliases ; *p != NULL ; p++) {
+ free(*p);
+ }
+ free(nw->n_aliases);
+ }
+
+ if (nw->n_addr != NULL)
+ free(nw->n_addr);
+}
diff --git a/contrib/bind/lib/irs/irp_p.h b/contrib/bind/lib/irs/irp_p.h
new file mode 100644
index 0000000..adf8174
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_p.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1996 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * $Id: irp_p.h,v 8.1 1999/01/18 07:46:54 vixie Exp $
+ */
+
+#ifndef _IRP_P_H_INCLUDED
+#define _IRP_P_H_INCLUDED
+
+#include <stdio.h>
+
+struct irp_p {
+ char inbuffer[1024];
+ int inlast; /* index of one past the last char in buffer */
+ int incurr; /* index of the next char to be read from buffer */
+
+ int fdCxn;
+};
+
+/*
+ * Externs.
+ */
+
+extern struct irs_acc * irs_irp_acc __P((const char *));
+extern struct irs_gr * irs_irp_gr __P((struct irs_acc *));
+extern struct irs_pw * irs_irp_pw __P((struct irs_acc *));
+extern struct irs_sv * irs_irp_sv __P((struct irs_acc *));
+extern struct irs_pr * irs_irp_pr __P((struct irs_acc *));
+extern struct irs_ho * irs_irp_ho __P((struct irs_acc *));
+extern struct irs_nw * irs_irp_nw __P((struct irs_acc *));
+extern struct irs_ng * irs_irp_ng __P((struct irs_acc *));
+
+int irs_irp_connect(struct irp_p *pvt);
+int irs_irp_is_connected(struct irp_p *pvt);
+void irs_irp_disconnect(struct irp_p *pvt);
+int irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen);
+char *irs_irp_read_body(struct irp_p *pvt, size_t *size);
+int irs_irp_get_full_response(struct irp_p *pvt, int *code,
+ char *text, size_t textlen,
+ char **body, size_t *bodylen);
+int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...);
+
+
+extern int irp_log_errors;
+
+#endif
diff --git a/contrib/bind/lib/irs/irp_pr.c b/contrib/bind/lib/irs/irp_pr.c
new file mode 100644
index 0000000..1de304e
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_pr.c
@@ -0,0 +1,353 @@
+/*
+ * Portions Copyright (c) 1996 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: irp_pr.c,v 8.1 1999/01/18 07:46:54 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/* extern */
+
+#include "port_before.h"
+
+#include <syslog.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <syslog.h>
+
+#include <irs.h>
+#include <irp.h>
+#include <isc/memcluster.h>
+#include <isc/irpmarshall.h>
+
+#include "irs_p.h"
+#include "lcl_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
+
+#define MAXALIASES 35
+
+/* Types */
+
+struct pvt {
+ struct irp_p *girpdata;
+ int warned;
+ struct protoent proto;
+};
+
+/* Forward */
+
+static void pr_close(struct irs_pr *);
+static struct protoent * pr_next(struct irs_pr *);
+static struct protoent * pr_byname(struct irs_pr *, const char *);
+static struct protoent * pr_bynumber(struct irs_pr *, int);
+static void pr_rewind(struct irs_pr *);
+static void pr_minimize(struct irs_pr *);
+
+static void free_proto(struct protoent *pr);
+
+/* Public */
+
+
+
+/*
+ * struct irs_pr * irs_irp_pr(struct irs_acc *this)
+ *
+ */
+
+struct irs_pr *
+irs_irp_pr(struct irs_acc *this) {
+ struct irs_pr *pr;
+ struct pvt *pvt;
+
+ if (!(pr = memget(sizeof *pr))) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pr, 0x0, sizeof *pr);
+
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(pr, sizeof *pr);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pvt, 0, sizeof *pvt);
+ pvt->girpdata = this->private;
+
+ pr->private = pvt;
+ pr->close = pr_close;
+ pr->byname = pr_byname;
+ pr->bynumber = pr_bynumber;
+ pr->next = pr_next;
+ pr->rewind = pr_rewind;
+ pr->minimize = pr_minimize;
+ return (pr);
+}
+
+/* Methods */
+
+
+
+/*
+ * void pr_close(struct irs_pr *this)
+ *
+ */
+
+static void
+pr_close(struct irs_pr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ pr_minimize(this);
+
+ free_proto(&pvt->proto);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
+}
+
+
+
+/*
+ * struct protoent * pr_byname(struct irs_pr *this, const char *name)
+ *
+ */
+
+static struct protoent *
+pr_byname(struct irs_pr *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct protoent *pr = &pvt->proto;
+ char *body = NULL;
+ size_t bodylen;
+ int code;
+ int i;
+ char text[256];
+
+ if (pr->p_name != NULL && strcmp(name, pr->p_name) == 0) {
+ return (pr);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ i = irs_irp_send_command(pvt->girpdata, "getprotobyname %s", name);
+ if (i != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETPROTO_OK) {
+ free_proto(pr);
+ if (irp_unmarshall_pr(pr, body) != 0) {
+ pr = NULL;
+ }
+ } else {
+ pr = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (pr);
+}
+
+
+
+/*
+ * struct protoent * pr_bynumber(struct irs_pr *this, int proto)
+ *
+ */
+
+static struct protoent *
+pr_bynumber(struct irs_pr *this, int proto) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct protoent *pr = &pvt->proto;
+ char *body = NULL;
+ size_t bodylen;
+ int code;
+ int i;
+ char text[256];
+
+ if (pr->p_name != NULL && proto == pr->p_proto) {
+ return (pr);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ i = irs_irp_send_command(pvt->girpdata, "getprotobynumber %d", proto);
+ if (i != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETPROTO_OK) {
+ free_proto(pr);
+ if (irp_unmarshall_pr(pr, body) != 0) {
+ pr = NULL;
+ }
+ } else {
+ pr = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (pr);
+}
+
+
+
+
+/*
+ * void pr_rewind(struct irs_pr *this)
+ *
+ */
+
+static void
+pr_rewind(struct irs_pr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char text[256];
+ int code;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return;
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "setprotoent") != 0) {
+ return;
+ }
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code != IRPD_GETPROTO_SETOK) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "setprotoent failed: %s", text);
+ }
+ }
+
+ return;
+}
+
+
+
+
+/*
+ * struct protoent * pr_next(struct irs_pr *this)
+ *
+ * Notes:
+ *
+ * Prepares the cache if necessary and returns the next item in it.
+ *
+ */
+
+static struct protoent *
+pr_next(struct irs_pr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct protoent *pr = &pvt->proto;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getprotoent") != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETPROTO_OK) {
+ free_proto(pr);
+ if (irp_unmarshall_pr(pr, body) != 0) {
+ pr = NULL;
+ }
+ } else {
+ pr = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (pr);
+}
+
+
+
+
+/*
+ * void pr_minimize(struct irs_pr *this)
+ *
+ */
+
+static void
+pr_minimize(struct irs_pr *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ irs_irp_disconnect(pvt->girpdata);
+}
+
+
+
+
+
+
+/*
+ * static void free_proto(struct protoent *pw);
+ *
+ * Deallocate all the memory irp_unmarshall_pr allocated.
+ *
+ */
+
+static void
+free_proto(struct protoent *pr) {
+ char **p;
+
+ if (pr == NULL)
+ return;
+
+ if (pr->p_name != NULL)
+ free(pr->p_name);
+
+ for (p = pr->p_aliases ; p != NULL && *p != NULL ; p++)
+ free(*p);
+}
diff --git a/contrib/bind/lib/irs/irp_pw.c b/contrib/bind/lib/irs/irp_pw.c
new file mode 100644
index 0000000..f23cb73
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_pw.c
@@ -0,0 +1,356 @@
+/*
+ * Portions Copyright (c) 1996 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: irp_pw.c,v 8.1 1999/01/18 07:46:54 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/* Extern */
+
+#include "port_before.h"
+
+#ifndef WANT_IRS_PW
+static int __bind_irs_pw_unneeded;
+#else
+
+#include <syslog.h>
+#include <sys/param.h>
+
+#include <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <utmp.h>
+#include <unistd.h>
+
+#include <irs.h>
+#include <irp.h>
+#include <isc/memcluster.h>
+#include <isc/irpmarshall.h>
+
+#include "port_after.h"
+
+#include "irs_p.h"
+#include "irp_p.h"
+
+
+/* Types */
+
+struct pvt {
+ struct irp_p *girpdata; /* global IRP data */
+ int warned;
+ struct passwd passwd; /* password structure */
+};
+
+/* Forward */
+
+static void pw_close(struct irs_pw *);
+static struct passwd * pw_next(struct irs_pw *);
+static struct passwd * pw_byname(struct irs_pw *, const char *);
+static struct passwd * pw_byuid(struct irs_pw *, uid_t);
+static void pw_rewind(struct irs_pw *);
+static void pw_minimize(struct irs_pw *);
+
+static void free_passwd(struct passwd *pw);
+
+/* Public */
+struct irs_pw *
+irs_irp_pw(struct irs_acc *this) {
+ struct irs_pw *pw;
+ struct pvt *pvt;
+
+ if (!(pw = memget(sizeof *pw))) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pw, 0, sizeof *pw);
+
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(pw, sizeof *pw);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pvt, 0, sizeof *pvt);
+ pvt->girpdata = this->private;
+
+ pw->private = pvt;
+ pw->close = pw_close;
+ pw->next = pw_next;
+ pw->byname = pw_byname;
+ pw->byuid = pw_byuid;
+ pw->rewind = pw_rewind;
+ pw->minimize = pw_minimize;
+
+ return (pw);
+}
+
+/* Methods */
+
+
+
+/*
+ * void pw_close(struct irs_pw *this)
+ *
+ */
+
+static void
+pw_close(struct irs_pw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ pw_minimize(this);
+
+ free_passwd(&pvt->passwd);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
+}
+
+
+
+
+/*
+ * struct passwd * pw_next(struct irs_pw *this)
+ *
+ */
+
+static struct passwd *
+pw_next(struct irs_pw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct passwd *pw = &pvt->passwd;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getpwent") != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETUSER_OK) {
+ free_passwd(pw);
+ if (irp_unmarshall_pw(pw, body) != 0) {
+ pw = NULL;
+ }
+ } else {
+ pw = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (pw);
+}
+
+
+
+
+/*
+ * struct passwd * pw_byname(struct irs_pw *this, const char *name)
+ *
+ */
+
+static struct passwd *
+pw_byname(struct irs_pw *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct passwd *pw = &pvt->passwd;
+ char *body = NULL;
+ char text[256];
+ size_t bodylen;
+ int code;
+
+ if (pw->pw_name != NULL && strcmp(name, pw->pw_name) == 0) {
+ return (pw);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getpwnam %s", name) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETUSER_OK) {
+ free_passwd(pw);
+ if (irp_unmarshall_pw(pw, body) != 0) {
+ pw = NULL;
+ }
+ } else {
+ pw = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (pw);
+}
+
+
+
+
+/*
+ * struct passwd * pw_byuid(struct irs_pw *this, uid_t uid)
+ *
+ */
+
+static struct passwd *
+pw_byuid(struct irs_pw *this, uid_t uid) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char *body;
+ char text[256];
+ size_t bodylen;
+ int code;
+ struct passwd *pw = &pvt->passwd;
+
+ if (pw->pw_name != NULL && pw->pw_uid == uid) {
+ return (pw);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getpwuid %d", uid) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETUSER_OK) {
+ free_passwd(pw);
+ if (irp_unmarshall_pw(pw, body) != 0) {
+ pw = NULL;
+ }
+ } else {
+ pw = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (pw);
+}
+
+
+
+
+/*
+ * void pw_rewind(struct irs_pw *this)
+ *
+ */
+
+static void
+pw_rewind(struct irs_pw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char text[256];
+ int code;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return;
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "setpwent") != 0) {
+ return;
+ }
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code != IRPD_GETUSER_SETOK) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "setpwent failed: %s", text);
+ }
+ }
+
+ return;
+}
+
+
+/*
+ * void pw_minimize(struct irs_pw *this)
+ *
+ */
+
+static void
+pw_minimize(struct irs_pw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ irs_irp_disconnect(pvt->girpdata);
+}
+
+
+/* Private. */
+
+
+
+/*
+ * static void free_passwd(struct passwd *pw);
+ *
+ * Deallocate all the memory irp_unmarshall_pw allocated.
+ *
+ */
+
+static void
+free_passwd(struct passwd *pw) {
+ if (pw == NULL)
+ return;
+
+ if (pw->pw_name != NULL)
+ free(pw->pw_name);
+
+ if (pw->pw_passwd != NULL)
+ free(pw->pw_passwd);
+
+ if (pw->pw_class != NULL)
+ free(pw->pw_class);
+
+ if (pw->pw_gecos != NULL)
+ free(pw->pw_gecos);
+
+ if (pw->pw_dir != NULL)
+ free(pw->pw_dir);
+
+ if (pw->pw_shell != NULL)
+ free(pw->pw_shell);
+}
+
+#endif /* WANT_IRS_PW */
diff --git a/contrib/bind/lib/irs/irp_sv.c b/contrib/bind/lib/irs/irp_sv.c
new file mode 100644
index 0000000..6a12c5b
--- /dev/null
+++ b/contrib/bind/lib/irs/irp_sv.c
@@ -0,0 +1,369 @@
+/*
+ * Portions Copyright (c) 1996,1998 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: irp_sv.c,v 8.1 1999/01/18 07:46:54 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/* extern */
+
+#include "port_before.h"
+
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifdef IRS_LCL_SV_DB
+#include <db.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+#include <irs.h>
+#include <irp.h>
+#include <isc/irpmarshall.h>
+#include <isc/memcluster.h>
+
+#include "irs_p.h"
+#include "lcl_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
+/* Types */
+
+struct pvt {
+ struct irp_p *girpdata;
+ int warned;
+ struct servent service;
+};
+
+/* Forward */
+
+static void sv_close(struct irs_sv*);
+static struct servent * sv_next(struct irs_sv *);
+static struct servent * sv_byname(struct irs_sv *, const char *,
+ const char *);
+static struct servent * sv_byport(struct irs_sv *, int, const char *);
+static void sv_rewind(struct irs_sv *);
+static void sv_minimize(struct irs_sv *);
+
+static void free_service(struct servent *sv);
+
+
+
+/* Public */
+
+
+
+/*
+ * struct irs_sv * irs_irp_sv(struct irs_acc *this)
+ *
+ */
+
+struct irs_sv *
+irs_irp_sv(struct irs_acc *this) {
+ struct irs_sv *sv;
+ struct pvt *pvt;
+
+ if ((sv = memget(sizeof *sv)) == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(sv, 0x0, sizeof *sv);
+
+ if ((pvt = memget(sizeof *pvt)) == NULL) {
+ memput(sv, sizeof *sv);
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(pvt, 0, sizeof *pvt);
+ pvt->girpdata = this->private;
+
+ sv->private = pvt;
+ sv->close = sv_close;
+ sv->next = sv_next;
+ sv->byname = sv_byname;
+ sv->byport = sv_byport;
+ sv->rewind = sv_rewind;
+ sv->minimize = sv_minimize;
+
+ return (sv);
+}
+
+/* Methods */
+
+
+
+/*
+ * void sv_close(struct irs_sv *this)
+ *
+ */
+
+static void
+sv_close(struct irs_sv *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ sv_minimize(this);
+
+ free_service(&pvt->service);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
+}
+
+
+
+
+/*
+ * struct servent * sv_next(struct irs_sv *this)
+ *
+ * Notes:
+ *
+ * Fills the cache if necessary and returns the next item from it.
+ *
+ */
+
+static struct servent *
+sv_next(struct irs_sv *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct servent *sv = &pvt->service;
+ char *body;
+ size_t bodylen;
+ int code;
+ char text[256];
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getservent") != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETSERVICE_OK) {
+ free_service(sv);
+ if (irp_unmarshall_sv(sv, body) != 0) {
+ sv = NULL;
+ }
+ } else {
+ sv = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (sv);
+}
+
+
+
+
+/*
+ * struct servent * sv_byname(struct irs_sv *this, const char *name,
+ * const char *proto)
+ *
+ */
+
+static struct servent *
+sv_byname(struct irs_sv *this, const char *name, const char *proto) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct servent *sv = &pvt->service;
+ char *body;
+ char text[256];
+ size_t bodylen;
+ int code;
+
+ if (sv->s_name != NULL &&
+ strcmp(name, sv->s_name) == 0 &&
+ strcasecmp(proto, sv->s_proto) == 0) {
+ return (sv);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getservbyname %s %s",
+ name, proto) != 0)
+ return (NULL);
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETSERVICE_OK) {
+ free_service(sv);
+ if (irp_unmarshall_sv(sv, body) != 0) {
+ sv = NULL;
+ }
+ } else {
+ sv = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (sv);
+}
+
+
+
+
+/*
+ * struct servent * sv_byport(struct irs_sv *this, int port,
+ * const char *proto)
+ *
+ */
+
+static struct servent *
+sv_byport(struct irs_sv *this, int port, const char *proto) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct servent *sv = &pvt->service;
+ char *body;
+ size_t bodylen;
+ char text[256];
+ int code;
+
+ if (sv->s_name != NULL &&
+ port == sv->s_port &&
+ strcasecmp(proto, sv->s_proto) == 0) {
+ return (sv);
+ }
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "getservbyport %d %s",
+ ntohs((short)port), proto) != 0) {
+ return (NULL);
+ }
+
+ if (irs_irp_get_full_response(pvt->girpdata, &code,
+ text, sizeof text,
+ &body, &bodylen) != 0) {
+ return (NULL);
+ }
+
+ if (code == IRPD_GETSERVICE_OK) {
+ free_service(sv);
+ if (irp_unmarshall_sv(sv, body) != 0) {
+ sv = NULL;
+ }
+ } else {
+ sv = NULL;
+ }
+
+ if (body != NULL) {
+ memput(body, bodylen);
+ }
+
+ return (sv);
+}
+
+
+
+
+
+/*
+ * void sv_rewind(struct irs_sv *this)
+ *
+ */
+
+static void
+sv_rewind(struct irs_sv *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+ char text[256];
+ int code;
+
+ if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
+ return;
+ }
+
+ if (irs_irp_send_command(pvt->girpdata, "setservent") != 0) {
+ return;
+ }
+
+ code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
+ if (code != IRPD_GETSERVICE_SETOK) {
+ if (irp_log_errors) {
+ syslog(LOG_WARNING, "setservent failed: %s", text);
+ }
+ }
+
+ return;
+}
+
+
+
+
+
+/*
+ * void sv_minimize(struct irs_sv *this)
+ *
+ */
+
+static void
+sv_minimize(struct irs_sv *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ irs_irp_disconnect(pvt->girpdata);
+}
+
+
+
+
+
+
+static void
+free_service(struct servent *sv) {
+ char **p;
+
+ if (sv == NULL) {
+ return;
+ }
+
+ if (sv->s_name != NULL) {
+ free(sv->s_name);
+ }
+
+ for (p = sv->s_aliases ; p != NULL && *p != NULL ; p++) {
+ free(*p);
+ }
+
+ if (sv->s_proto != NULL) {
+ free(sv->s_proto);
+ }
+}
+
+
diff --git a/contrib/bind/lib/irs/irpmarshall.c b/contrib/bind/lib/irs/irpmarshall.c
new file mode 100644
index 0000000..8f7c330
--- /dev/null
+++ b/contrib/bind/lib/irs/irpmarshall.c
@@ -0,0 +1,2332 @@
+/*
+ * Copyright(c) 1989, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: irpmarshall.c,v 8.5 1999/10/13 17:11:19 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#if 0
+
+Check values are in approrpriate endian order.
+
+Double check memory allocations on unmarhsalling
+
+#endif
+
+
+/* Extern */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <utmp.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <irs.h>
+#include <isc/memcluster.h>
+#include <isc/irpmarshall.h>
+
+#include "port_after.h"
+
+
+static char *strndup(const char *str, size_t len);
+static char **splitarray(const char *buffer, const char *buffend, char delim);
+static int joinarray(char * const * argv, char *buffer, char delim);
+static char *getfield(char **res, size_t reslen, char **buffer, char delim);
+static size_t joinlength(char * const *argv);
+static void free_array(char **argv, size_t entries);
+
+#define ADDR_T_STR(x) (x == AF_INET ? "AF_INET" :\
+ (x == AF_INET6 ? "AF_INET6" : "UNKNOWN"))
+
+#define MAXPADDRSIZE (sizeof "255.255.255.255" + 1)
+
+static char COMMA = ',';
+
+static const char *COMMASTR = ",";
+static const char *COLONSTR = ":";
+
+
+
+/* See big comment at bottom of irpmarshall.h for description. */
+
+
+#ifdef WANT_IRS_PW
+/* +++++++++++++++++++++++++ struct passwd +++++++++++++++++++++++++ */
+
+
+/*
+ * int irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len)
+ *
+ * notes:
+ *
+ * See above
+ *
+ * return:
+ *
+ * 0 on sucess, -1 on failure.
+ *
+ */
+
+int
+irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len) {
+ size_t need = 1 ; /* for null byte */
+ char pwUid[24];
+ char pwGid[24];
+ char pwChange[24];
+ char pwExpire[24];
+ char *pwClass;
+ const char *fieldsep = COLONSTR;
+
+ if (pw == NULL || len == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ sprintf(pwUid, "%ld", (long)pw->pw_uid);
+ sprintf(pwGid, "%ld", (long)pw->pw_gid);
+
+#ifdef HAVE_PW_CHANGE
+ sprintf(pwChange, "%ld", (long)pw->pw_change);
+#else
+ pwChange[0] = '0';
+ pwChange[1] = '\0';
+#endif
+
+#ifdef HAVE_PW_EXPIRE
+ sprintf(pwExpire, "%ld", (long)pw->pw_expire);
+#else
+ pwExpire[0] = '0';
+ pwExpire[1] = '\0';
+#endif
+
+#ifdef HAVE_PW_CLASS
+ pwClass = pw->pw_class;
+#else
+ pwClass = "";
+#endif
+
+ need += strlen(pw->pw_name) + 1; /* one for fieldsep */
+ need += strlen(pw->pw_passwd) + 1;
+ need += strlen(pwUid) + 1;
+ need += strlen(pwGid) + 1;
+ need += strlen(pwClass) + 1;
+ need += strlen(pwChange) + 1;
+ need += strlen(pwExpire) + 1;
+ need += strlen(pw->pw_gecos) + 1;
+ need += strlen(pw->pw_dir) + 1;
+ need += strlen(pw->pw_shell) + 1;
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ }
+
+ if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ }
+
+ strcpy(*buffer, pw->pw_name); strcat(*buffer, fieldsep);
+ strcat(*buffer, pw->pw_passwd); strcat(*buffer, fieldsep);
+ strcat(*buffer, pwUid); strcat(*buffer, fieldsep);
+ strcat(*buffer, pwGid); strcat(*buffer, fieldsep);
+ strcat(*buffer, pwClass); strcat(*buffer, fieldsep);
+ strcat(*buffer, pwChange); strcat(*buffer, fieldsep);
+ strcat(*buffer, pwExpire); strcat(*buffer, fieldsep);
+ strcat(*buffer, pw->pw_gecos); strcat(*buffer, fieldsep);
+ strcat(*buffer, pw->pw_dir); strcat(*buffer, fieldsep);
+ strcat(*buffer, pw->pw_shell); strcat(*buffer, fieldsep);
+
+ return (0);
+}
+
+
+
+
+
+/*
+ * int irp_unmarshall_pw(struct passwd *pw, char *buffer)
+ *
+ * notes:
+ *
+ * see above
+ *
+ * return:
+ *
+ * 0 on success, -1 on failure
+ *
+ */
+
+int
+irp_unmarshall_pw(struct passwd *pw, char *buffer) {
+ char *name, *pass, *class, *gecos, *dir, *shell;
+ uid_t pwuid;
+ gid_t pwgid;
+ time_t pwchange;
+ time_t pwexpire;
+ char *p;
+ long t;
+ char tmpbuf[24];
+ char *tb = &tmpbuf[0];
+ char fieldsep = ':';
+ int myerrno = EINVAL;
+
+ name = pass = class = gecos = dir = shell = NULL;
+ p = buffer;
+
+ /* pw_name field */
+ name = NULL;
+ if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
+ goto error;
+ }
+
+ /* pw_passwd field */
+ pass = NULL;
+ if (getfield(&pass, 0, &p, fieldsep) == NULL) { /* field can be empty */
+ goto error;
+ }
+
+
+ /* pw_uid field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ pwuid = (uid_t)t;
+ if ((long) pwuid != t) { /* value must have been too big. */
+ goto error;
+ }
+
+
+
+ /* pw_gid field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ pwgid = (gid_t)t;
+ if ((long)pwgid != t) { /* value must have been too big. */
+ goto error;
+ }
+
+
+
+ /* pw_class field */
+ class = NULL;
+ if (getfield(&class, 0, &p, fieldsep) == NULL) {
+ goto error;
+ }
+
+
+
+ /* pw_change field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ pwchange = (time_t)t;
+ if ((long)pwchange != t) { /* value must have been too big. */
+ goto error;
+ }
+
+
+
+ /* pw_expire field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ pwexpire = (time_t)t;
+ if ((long) pwexpire != t) { /* value must have been too big. */
+ goto error;
+ }
+
+
+
+ /* pw_gecos field */
+ gecos = NULL;
+ if (getfield(&gecos, 0, &p, fieldsep) == NULL) {
+ goto error;
+ }
+
+
+
+ /* pw_dir field */
+ dir = NULL;
+ if (getfield(&dir, 0, &p, fieldsep) == NULL) {
+ goto error;
+ }
+
+
+
+ /* pw_shell field */
+ shell = NULL;
+ if (getfield(&shell, 0, &p, fieldsep) == NULL) {
+ goto error;
+ }
+
+
+
+ pw->pw_name = name;
+ pw->pw_passwd = pass;
+ pw->pw_uid = pwuid;
+ pw->pw_gid = pwgid;
+ pw->pw_gecos = gecos;
+ pw->pw_dir = dir;
+ pw->pw_shell = shell;
+
+#ifdef HAVE_PW_CHANGE
+ pw->pw_change = pwchange;
+#endif
+#ifdef HAVE_PW_CLASS
+ pw->pw_class = class;
+#endif
+#ifdef HAVE_PW_EXPIRE
+ pw->pw_expire = pwexpire;
+#endif
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (name != NULL) free(name);
+ if (pass != NULL) free(pass);
+ if (gecos != NULL) free(gecos);
+ if (dir != NULL) free(dir);
+ if (shell != NULL) free(shell);
+
+ return (-1);
+}
+
+/* ------------------------- struct passwd ------------------------- */
+#endif /* WANT_IRS_PW */
+
+
+
+/* +++++++++++++++++++++++++ struct group +++++++++++++++++++++++++ */
+
+
+
+/*
+ * int irp_marshall_gr(const struct group *gr, char **buffer, size_t *len)
+ *
+ * notes:
+ *
+ * see above.
+ *
+ * return:
+ *
+ * 0 on success, -1 on failure
+ */
+
+int
+irp_marshall_gr(const struct group *gr, char **buffer, size_t *len) {
+ size_t need = 1; /* for null byte */
+ char grGid[24];
+ const char *fieldsep = COLONSTR;
+
+ if (gr == NULL || len == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ sprintf(grGid, "%ld", (long)gr->gr_gid);
+
+ need += strlen(gr->gr_name) + 1;
+#ifndef MISSING_GR_PASSWD
+ need += strlen(gr->gr_passwd) + 1;
+#else
+ need++;
+#endif
+ need += strlen(grGid) + 1;
+ need += joinlength(gr->gr_mem) + 1;
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ }
+
+ if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ }
+
+ strcpy(*buffer, gr->gr_name); strcat(*buffer, fieldsep);
+#ifndef MISSING_GR_PASSWD
+ strcat(*buffer, gr->gr_passwd);
+#endif
+ strcat(*buffer, fieldsep);
+ strcat(*buffer, grGid); strcat(*buffer, fieldsep);
+ joinarray(gr->gr_mem, *buffer, COMMA) ; strcat(*buffer, fieldsep);
+
+ return (0);
+}
+
+
+
+
+/*
+ * int irp_unmarshall_gr(struct group *gr, char *buffer)
+ *
+ * notes:
+ *
+ * see above
+ *
+ * return:
+ *
+ * 0 on success and -1 on failure.
+ *
+ */
+
+int
+irp_unmarshall_gr(struct group *gr, char *buffer) {
+ char *p, *q;
+ gid_t grgid;
+ long t;
+ char *name = NULL;
+ char *pass = NULL;
+ char **members = NULL;
+ char tmpbuf[24];
+ char *tb;
+ char fieldsep = ':';
+ int myerrno = EINVAL;
+
+ if (gr == NULL || buffer == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ p = buffer;
+
+ /* gr_name field */
+ name = NULL;
+ if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
+ goto error;
+ }
+
+
+ /* gr_passwd field */
+ pass = NULL;
+ if (getfield(&pass, 0, &p, fieldsep) == NULL) {
+ goto error;
+ }
+
+
+ /* gr_gid field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ grgid = (gid_t)t;
+ if ((long) grgid != t) { /* value must have been too big. */
+ goto error;
+ }
+
+
+ /* gr_mem field. Member names are separated by commas */
+ q = strchr(p, fieldsep);
+ if (q == NULL) {
+ goto error;
+ }
+ members = splitarray(p, q, COMMA);
+ if (members == NULL) {
+ myerrno = errno;
+ goto error;
+ }
+ p = q + 1;
+
+
+ gr->gr_name = name;
+#ifndef MISSING_GR_PASSWD
+ gr->gr_passwd = pass;
+#endif
+ gr->gr_gid = grgid;
+ gr->gr_mem = members;
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (name != NULL) free(name);
+ if (pass != NULL) free(pass);
+
+ return (-1);
+}
+
+
+/* ------------------------- struct group ------------------------- */
+
+
+
+
+/* +++++++++++++++++++++++++ struct servent +++++++++++++++++++++++++ */
+
+
+
+/*
+ * int irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len)
+ *
+ * notes:
+ *
+ * see above
+ *
+ * return:
+ *
+ * 0 on success, -1 on failure.
+ *
+ */
+
+int
+irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len) {
+ size_t need = 1; /* for null byte */
+ char svPort[24];
+ const char *fieldsep = COLONSTR;
+ short realport;
+
+ if (sv == NULL || len == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* the int s_port field is actually a short in network order. We
+ want host order to make the marshalled data look correct */
+ realport = ntohs((short)sv->s_port);
+ sprintf(svPort, "%d", realport);
+
+ need += strlen(sv->s_name) + 1;
+ need += joinlength(sv->s_aliases) + 1;
+ need += strlen(svPort) + 1;
+ need += strlen(sv->s_proto) + 1;
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ }
+
+ if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ }
+
+ strcpy(*buffer, sv->s_name); strcat(*buffer, fieldsep);
+ joinarray(sv->s_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
+ strcat(*buffer, svPort); strcat(*buffer, fieldsep);
+ strcat(*buffer, sv->s_proto); strcat(*buffer, fieldsep);
+
+ return (0);
+}
+
+
+
+
+
+/*
+ * int irp_unmarshall_sv(struct servent *sv, char *buffer)
+ *
+ * notes:
+ *
+ * see above
+ *
+ * return:
+ *
+ * 0 on success, -1 on failure.
+ *
+ */
+
+int
+irp_unmarshall_sv(struct servent *sv, char *buffer) {
+ char *p, *q;
+ short svport;
+ long t;
+ char *name = NULL;
+ char *proto = NULL;
+ char **aliases = NULL;
+ char tmpbuf[24];
+ char *tb;
+ char fieldsep = ':';
+ int myerrno = EINVAL;
+
+ if (sv == NULL || buffer == NULL)
+ return (-1);
+
+ p = buffer;
+
+
+ /* s_name field */
+ name = NULL;
+ if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
+ goto error;
+ }
+
+
+ /* s_aliases field */
+ q = strchr(p, fieldsep);
+ if (q == NULL) {
+ goto error;
+ }
+ aliases = splitarray(p, q, COMMA);
+ if (aliases == NULL) {
+ myerrno = errno;
+ goto error;
+ }
+ p = q + 1;
+
+
+ /* s_port field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ svport = (short)t;
+ if ((long) svport != t) { /* value must have been too big. */
+ goto error;
+ }
+ svport = htons(svport);
+
+ /* s_proto field */
+ proto = NULL;
+ if (getfield(&proto, 0, &p, fieldsep) == NULL) {
+ goto error;
+ }
+
+ sv->s_name = name;
+ sv->s_aliases = aliases;
+ sv->s_port = svport;
+ sv->s_proto = proto;
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (name != NULL) free(name);
+ if (proto != NULL) free(proto);
+ free_array(aliases, 0);
+
+ return (-1);
+}
+
+
+/* ------------------------- struct servent ------------------------- */
+
+/* +++++++++++++++++++++++++ struct protoent +++++++++++++++++++++++++ */
+
+
+
+/*
+ * int irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len)
+ *
+ * notes:
+ *
+ * see above
+ *
+ * return:
+ *
+ * 0 on success and -1 on failure.
+ *
+ */
+
+int
+irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len) {
+ size_t need = 1; /* for null byte */
+ char prProto[24];
+ const char *fieldsep = COLONSTR;
+
+ if (pr == NULL || len == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ sprintf(prProto, "%d", (int)pr->p_proto);
+
+ need += strlen(pr->p_name) + 1;
+ need += joinlength(pr->p_aliases) + 1;
+ need += strlen(prProto) + 1;
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ }
+
+ if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ }
+
+ strcpy(*buffer, pr->p_name); strcat(*buffer, fieldsep);
+ joinarray(pr->p_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
+ strcat(*buffer, prProto); strcat(*buffer, fieldsep);
+
+ return (0);
+
+}
+
+
+
+/*
+ * int irp_unmarshall_pr(struct protoent *pr, char *buffer)
+ *
+ * notes:
+ *
+ * See above
+ *
+ * return:
+ *
+ * 0 on success, -1 on failure
+ *
+ */
+
+int irp_unmarshall_pr(struct protoent *pr, char *buffer) {
+ char *p, *q;
+ int prproto;
+ long t;
+ char *name = NULL;
+ char **aliases = NULL;
+ char tmpbuf[24];
+ char *tb;
+ char fieldsep = ':';
+ int myerrno = EINVAL;
+
+ if (pr == NULL || buffer == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ p = buffer;
+
+ /* p_name field */
+ name = NULL;
+ if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
+ goto error;
+ }
+
+
+ /* p_aliases field */
+ q = strchr(p, fieldsep);
+ if (q == NULL) {
+ goto error;
+ }
+ aliases = splitarray(p, q, COMMA);
+ if (aliases == NULL) {
+ myerrno = errno;
+ goto error;
+ }
+ p = q + 1;
+
+
+ /* p_proto field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ prproto = (int)t;
+ if ((long) prproto != t) { /* value must have been too big. */
+ goto error;
+ }
+
+ pr->p_name = name;
+ pr->p_aliases = aliases;
+ pr->p_proto = prproto;
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (name != NULL) free(name);
+ free_array(aliases, 0);
+
+ return (-1);
+}
+
+/* ------------------------- struct protoent ------------------------- */
+
+
+
+/* +++++++++++++++++++++++++ struct hostent +++++++++++++++++++++++++ */
+
+
+/*
+ * int irp_marshall_ho(struct hostent *ho, char **buffer, size_t *len)
+ *
+ * notes:
+ *
+ * see above.
+ *
+ * return:
+ *
+ * 0 on success, -1 on failure.
+ *
+ */
+
+int
+irp_marshall_ho(struct hostent *ho, char **buffer, size_t *len) {
+ size_t need = 1; /* for null byte */
+ char hoaddrtype[24];
+ char holength[24];
+ char **av;
+ char *p;
+ int addrlen;
+ int malloced = 0;
+ size_t remlen;
+ const char *fieldsep = "@";
+
+ if (ho == NULL || len == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ switch(ho->h_addrtype) {
+ case AF_INET:
+ strcpy(hoaddrtype, "AF_INET");
+ break;
+
+ case AF_INET6:
+ strcpy(hoaddrtype, "AF_INET6");
+ break;
+
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ sprintf(holength, "%d", ho->h_length);
+
+ need += strlen(ho->h_name) + 1;
+ need += joinlength(ho->h_aliases) + 1;
+ need += strlen(hoaddrtype) + 1;
+ need += strlen(holength) + 1;
+
+ /* we determine an upper bound on the string length needed, not an
+ exact length. */
+ addrlen = (ho->h_addrtype == AF_INET ? 16 : 46) ; /* XX other AF's?? */
+ for (av = ho->h_addr_list; av != NULL && *av != NULL ; av++)
+ need += addrlen;
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ }
+
+ if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ malloced = 1;
+ }
+
+ strcpy(*buffer, ho->h_name); strcat(*buffer, fieldsep);
+ joinarray(ho->h_aliases, *buffer, COMMA); strcat(*buffer, fieldsep);
+ strcat(*buffer, hoaddrtype); strcat(*buffer, fieldsep);
+ strcat(*buffer, holength); strcat(*buffer, fieldsep);
+
+ p = *buffer + strlen(*buffer);
+ remlen = need - strlen(*buffer);
+ for (av = ho->h_addr_list ; av != NULL && *av != NULL ; av++) {
+ if (inet_ntop(ho->h_addrtype, *av, p, remlen) == NULL) {
+ goto error;
+ }
+ if (*(av + 1) != NULL)
+ strcat(p, COMMASTR);
+ remlen -= strlen(p);
+ p += strlen(p);
+ }
+ strcat(*buffer, fieldsep);
+
+ return (0);
+
+ error:
+ if (malloced) {
+ memput(*buffer, need);
+ }
+
+ return (-1);
+}
+
+
+
+/*
+ * int irp_unmarshall_ho(struct hostent *ho, char *buffer)
+ *
+ * notes:
+ *
+ * See above.
+ *
+ * return:
+ *
+ * 0 on success, -1 on failure.
+ *
+ */
+
+int
+irp_unmarshall_ho(struct hostent *ho, char *buffer) {
+ char *p, *q, *r;
+ int hoaddrtype;
+ int holength;
+ long t;
+ char *name = NULL;
+ char **aliases = NULL;
+ char **hohaddrlist = NULL;
+ size_t hoaddrsize;
+ char tmpbuf[24];
+ char *tb;
+ char **alist;
+ int addrcount;
+ char fieldsep = '@';
+ int myerrno = EINVAL;
+
+ if (ho == NULL || buffer == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ p = buffer;
+
+ /* h_name field */
+ name = NULL;
+ if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
+ goto error;
+ }
+
+
+ /* h_aliases field */
+ q = strchr(p, fieldsep);
+ if (q == NULL) {
+ goto error;
+ }
+ aliases = splitarray(p, q, COMMA);
+ if (aliases == NULL) {
+ myerrno = errno;
+ goto error;
+ }
+ p = q + 1;
+
+
+ /* h_addrtype field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ if (strcmp(tmpbuf, "AF_INET") == 0)
+ hoaddrtype = AF_INET;
+ else if (strcmp(tmpbuf, "AF_INET6") == 0)
+ hoaddrtype = AF_INET6;
+ else
+ goto error;
+
+
+ /* h_length field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ t = strtol(tmpbuf, &tb, 10);
+ if (*tb) {
+ goto error; /* junk in value */
+ }
+ holength = (int)t;
+ if ((long) holength != t) { /* value must have been too big. */
+ goto error;
+ }
+
+
+ /* h_addr_list field */
+ q = strchr(p, fieldsep);
+ if (q == NULL)
+ goto error;
+
+ /* count how many addresss are in there */
+ if (q > p + 1) {
+ for (addrcount = 1, r = p ; r != q ; r++) {
+ if (*r == COMMA)
+ addrcount++;
+ }
+ } else {
+ addrcount = 0;
+ }
+
+ hoaddrsize = (addrcount + 1) * sizeof (char *);
+ hohaddrlist = malloc(hoaddrsize);
+ if (hohaddrlist == NULL) {
+ myerrno = ENOMEM;
+ goto error;
+ }
+
+ memset(hohaddrlist, 0x0, hoaddrsize);
+
+ alist = hohaddrlist;
+ for (t = 0, r = p ; r != q ; p = r + 1, t++) {
+ char saved;
+ while (r != q && *r != COMMA) r++;
+ saved = *r;
+ *r = 0x0;
+
+ alist[t] = malloc(hoaddrtype == AF_INET ? 4 : 16);
+ if (alist[t] == NULL) {
+ myerrno = ENOMEM;
+ goto error;
+ }
+
+ if (inet_pton(hoaddrtype, p, alist[t]) == -1)
+ goto error;
+ *r = saved;
+ }
+ alist[t] = NULL;
+
+ ho->h_name = name;
+ ho->h_aliases = aliases;
+ ho->h_addrtype = hoaddrtype;
+ ho->h_length = holength;
+ ho->h_addr_list = hohaddrlist;
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (name != NULL) free(name);
+ free_array(aliases, 0);
+
+ return (-1);
+}
+
+/* ------------------------- struct hostent------------------------- */
+
+
+
+/* +++++++++++++++++++++++++ struct netgrp +++++++++++++++++++++++++ */
+
+
+/*
+ * int irp_marshall_ng(const char *host, const char *user,
+ * const char *domain, char *buffer, size_t *len)
+ *
+ * notes:
+ *
+ * See note for irp_marshall_ng_start
+ *
+ * return:
+ *
+ * 0 on success, 0 on failure.
+ *
+ */
+
+int
+irp_marshall_ng(const char *host, const char *user, const char *domain,
+ char **buffer, size_t *len) {
+ size_t need = 1; /* for nul byte */
+ const char *fieldsep = ",";
+
+ if (len == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ need += 4; /* two parens and two commas */
+ need += (host == NULL ? 0 : strlen(host));
+ need += (user == NULL ? 0 : strlen(user));
+ need += (domain == NULL ? 0 : strlen(domain));
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ } else if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ }
+
+ (*buffer)[0] = '(';
+ (*buffer)[1] = '\0';
+
+ if (host != NULL)
+ strcat(*buffer, host);
+ strcat(*buffer, fieldsep);
+
+ if (user != NULL)
+ strcat(*buffer, user);
+ strcat(*buffer, fieldsep);
+
+ if (domain != NULL)
+ strcat(*buffer, domain);
+ strcat(*buffer, ")");
+
+ return (0);
+}
+
+
+
+/* ---------- */
+
+
+/*
+ * int irp_unmarshall_ng(char **host, char **user, char **domain,
+ * char *buffer)
+ *
+ * notes:
+ *
+ * Unpacks the BUFFER into 3 character arrays it allocates and assigns
+ * to *HOST, *USER and *DOMAIN. If any field of the value is empty,
+ * then the corresponding paramater value will be set to NULL.
+ *
+ * return:
+ *
+ * 0 on success and -1 on failure.
+ */
+
+int
+irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) {
+ char *p, *q;
+ char fieldsep = ',';
+ int myerrno = EINVAL;
+
+ if (user == NULL || host == NULL || domain == NULL || buffer == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ *host = *user = *domain = NULL;
+
+ p = buffer;
+ while (isspace(*p)) {
+ p++;
+ }
+ if (*p != '(') {
+ goto error;
+ }
+
+ q = p + 1;
+ while (*q && *q != fieldsep)
+ q++;
+ if (!*q) {
+ goto error;
+ } else if (q > p + 1) {
+ *host = strndup(p, q - p);
+ }
+
+ p = q + 1;
+ if (!*p) {
+ goto error;
+ } else if (*p != fieldsep) {
+ q = p + 1;
+ while (*q && *q != fieldsep)
+ q++;
+ if (!*q) {
+ goto error;
+ }
+ *user = strndup(p, q - p);
+ } else {
+ p++;
+ }
+
+ if (!*p) {
+ goto error;
+ } else if (*p != ')') {
+ q = p + 1;
+ while (*q && *q != ')')
+ q++;
+ if (!*q) {
+ goto error;
+ }
+ *domain = strndup(p, q - p);
+ }
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (*host != NULL) free(*host);
+ if (*user != NULL) free(*user);
+ if (*domain != NULL) free(*domain);
+
+ return (-1);
+}
+
+/* ------------------------- struct netgrp ------------------------- */
+
+
+
+
+/* +++++++++++++++++++++++++ struct nwent +++++++++++++++++++++++++ */
+
+
+/*
+ * int irp_marshall_nw(struct nwent *ne, char **buffer, size_t *len)
+ *
+ * notes:
+ *
+ * See at top.
+ *
+ * return:
+ *
+ * 0 on success and -1 on failure.
+ *
+ */
+
+int
+irp_marshall_nw(struct nwent *ne, char **buffer, size_t *len) {
+ size_t need = 1; /* for null byte */
+ char nAddrType[24];
+ char nNet[MAXPADDRSIZE];
+ const char *fieldsep = COLONSTR;
+
+ if (ne == NULL || len == NULL) {
+ return (-1);
+ }
+
+ strcpy(nAddrType, ADDR_T_STR(ne->n_addrtype));
+
+ if (inet_net_ntop(ne->n_addrtype, ne->n_addr, ne->n_length,
+ nNet, sizeof nNet) == NULL) {
+ return (-1);
+ }
+
+
+ need += strlen(ne->n_name) + 1;
+ need += joinlength(ne->n_aliases) + 1;
+ need += strlen(nAddrType) + 1;
+ need += strlen(nNet) + 1;
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ }
+
+ if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ }
+
+ strcpy(*buffer, ne->n_name); strcat(*buffer, fieldsep);
+ joinarray(ne->n_aliases, *buffer, COMMA) ; strcat(*buffer, fieldsep);
+ strcat(*buffer, nAddrType); strcat(*buffer, fieldsep);
+ strcat(*buffer, nNet); strcat(*buffer, fieldsep);
+
+ return (0);
+}
+
+
+
+/*
+ * int irp_unmarshall_nw(struct nwent *ne, char *buffer)
+ *
+ * notes:
+ *
+ * See note up top.
+ *
+ * return:
+ *
+ * 0 on success and -1 on failure.
+ *
+ */
+
+int
+irp_unmarshall_nw(struct nwent *ne, char *buffer) {
+ char *p, *q;
+ int naddrtype;
+ long nnet;
+ int bits;
+ char *name = NULL;
+ char **aliases = NULL;
+ char tmpbuf[24];
+ char *tb;
+ char fieldsep = ':';
+ int myerrno = EINVAL;
+
+ if (ne == NULL || buffer == NULL) {
+ goto error;
+ }
+
+ p = buffer;
+
+ /* n_name field */
+ name = NULL;
+ if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
+ goto error;
+ }
+
+
+ /* n_aliases field. Aliases are separated by commas */
+ q = strchr(p, fieldsep);
+ if (q == NULL) {
+ goto error;
+ }
+ aliases = splitarray(p, q, COMMA);
+ if (aliases == NULL) {
+ myerrno = errno;
+ goto error;
+ }
+ p = q + 1;
+
+
+ /* h_addrtype field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ if (strcmp(tmpbuf, "AF_INET") == 0)
+ naddrtype = AF_INET;
+ else if (strcmp(tmpbuf, "AF_INET6") == 0)
+ naddrtype = AF_INET6;
+ else
+ goto error;
+
+
+ /* n_net field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ nnet = 0;
+ bits = inet_net_pton(naddrtype, tmpbuf, &nnet, sizeof nnet);
+ if (bits < 0) {
+ goto error;
+ }
+
+ /* nnet = ntohl(nnet); */ /* keep in network order for nwent */
+
+ ne->n_name = name;
+ ne->n_aliases = aliases;
+ ne->n_addrtype = naddrtype;
+ ne->n_length = bits;
+ ne->n_addr = malloc(sizeof nnet);
+ if (ne->n_addr == NULL) {
+ goto error;
+ }
+
+ memcpy(ne->n_addr, &nnet, sizeof nnet);
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (name != NULL) free(name);
+ free_array(aliases, 0);
+
+ return (-1);
+}
+
+
+/* ------------------------- struct nwent ------------------------- */
+
+
+/* +++++++++++++++++++++++++ struct netent +++++++++++++++++++++++++ */
+
+
+/*
+ * int irp_marshall_ne(struct netent *ne, char **buffer, size_t *len)
+ *
+ * notes:
+ *
+ * See at top.
+ *
+ * return:
+ *
+ * 0 on success and -1 on failure.
+ *
+ */
+
+int
+irp_marshall_ne(struct netent *ne, char **buffer, size_t *len) {
+ size_t need = 1; /* for null byte */
+ char nAddrType[24];
+ char nNet[MAXPADDRSIZE];
+ const char *fieldsep = COLONSTR;
+ long nval;
+
+ if (ne == NULL || len == NULL) {
+ return (-1);
+ }
+
+ strcpy(nAddrType, ADDR_T_STR(ne->n_addrtype));
+
+ nval = htonl(ne->n_net);
+ if (inet_ntop(ne->n_addrtype, &nval, nNet, sizeof nNet) == NULL) {
+ return (-1);
+ }
+
+ need += strlen(ne->n_name) + 1;
+ need += joinlength(ne->n_aliases) + 1;
+ need += strlen(nAddrType) + 1;
+ need += strlen(nNet) + 1;
+
+ if (buffer == NULL) {
+ *len = need;
+ return (0);
+ }
+
+ if (*buffer != NULL && need > *len) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (*buffer == NULL) {
+ need += 2; /* for CRLF */
+ *buffer = memget(need);
+ if (*buffer == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ *len = need;
+ }
+
+ strcpy(*buffer, ne->n_name); strcat(*buffer, fieldsep);
+ joinarray(ne->n_aliases, *buffer, COMMA) ; strcat(*buffer, fieldsep);
+ strcat(*buffer, nAddrType); strcat(*buffer, fieldsep);
+ strcat(*buffer, nNet); strcat(*buffer, fieldsep);
+
+ return (0);
+}
+
+
+
+/*
+ * int irp_unmarshall_ne(struct netent *ne, char *buffer)
+ *
+ * notes:
+ *
+ * See note up top.
+ *
+ * return:
+ *
+ * 0 on success and -1 on failure.
+ *
+ */
+
+int
+irp_unmarshall_ne(struct netent *ne, char *buffer) {
+ char *p, *q;
+ int naddrtype;
+ long nnet;
+ int bits;
+ char *name = NULL;
+ char **aliases = NULL;
+ char tmpbuf[24];
+ char *tb;
+ char fieldsep = ':';
+ int myerrno = EINVAL;
+
+ if (ne == NULL || buffer == NULL) {
+ goto error;
+ }
+
+ p = buffer;
+
+ /* n_name field */
+ name = NULL;
+ if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) {
+ goto error;
+ }
+
+
+ /* n_aliases field. Aliases are separated by commas */
+ q = strchr(p, fieldsep);
+ if (q == NULL) {
+ goto error;
+ }
+ aliases = splitarray(p, q, COMMA);
+ if (aliases == NULL) {
+ myerrno = errno;
+ goto error;
+ }
+ p = q + 1;
+
+
+ /* h_addrtype field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ if (strcmp(tmpbuf, "AF_INET") == 0)
+ naddrtype = AF_INET;
+ else if (strcmp(tmpbuf, "AF_INET6") == 0)
+ naddrtype = AF_INET6;
+ else
+ goto error;
+
+
+ /* n_net field */
+ tb = tmpbuf;
+ if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL ||
+ strlen(tb) == 0) {
+ goto error;
+ }
+ bits = inet_net_pton(naddrtype, tmpbuf, &nnet, sizeof nnet);
+ if (bits < 0) {
+ goto error;
+ }
+ nnet = ntohl(nnet);
+
+ ne->n_name = name;
+ ne->n_aliases = aliases;
+ ne->n_addrtype = naddrtype;
+ ne->n_net = nnet;
+
+ return (0);
+
+ error:
+ errno = myerrno;
+
+ if (name != NULL) free(name);
+ free_array(aliases, 0);
+
+ return (-1);
+}
+
+
+/* ------------------------- struct netent ------------------------- */
+
+
+/* =========================================================================== */
+
+
+/*
+ * static char ** splitarray(const char *buffer, const char *buffend, char delim)
+ *
+ * notes:
+ *
+ * Split a delim separated astring. Not allowed
+ * to have two delims next to each other. BUFFER points to begining of
+ * string, BUFFEND points to one past the end of the string
+ * (i.e. points at where the null byte would be if null
+ * terminated).
+ *
+ * return:
+ *
+ * Returns a malloced array of pointers, each pointer pointing to a
+ * malloced string. If BUFEER is an empty string, then return values is
+ * array of 1 pointer that is NULL. Returns NULL on failure.
+ *
+ */
+
+static char **
+splitarray(const char *buffer, const char *buffend, char delim) {
+ const char *p, *q;
+ int count = 0;
+ char **arr = NULL;
+ char **aptr;
+
+ if (buffend < buffer)
+ return (NULL);
+ else if (buffend > buffer && *buffer == delim)
+ return (NULL);
+ else if (buffend > buffer && *(buffend - 1) == delim)
+ return (NULL);
+
+ /* count the number of field and make sure none are empty */
+ if (buffend > buffer + 1) {
+ for (count = 1, q = buffer ; q != buffend ; q++) {
+ if (*q == delim) {
+ if (q > buffer && (*(q - 1) == delim)) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ count++;
+ }
+ }
+ }
+
+ if (count > 0) {
+ count++ ; /* for NULL at end */
+ aptr = arr = malloc(count * sizeof (char *));
+ if (aptr == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+
+ memset(arr, 0x0, count * sizeof (char *));
+ for (p = buffer ; p < buffend ; p++) {
+ for (q = p ; *q != delim && q != buffend ; q++)
+ /* nothing */;
+ *aptr = strndup(p, q - p);
+
+ p = q;
+ aptr++;
+ }
+ *aptr = NULL;
+ } else {
+ arr = malloc(sizeof (char *));
+ if (arr == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+
+ *arr = NULL;
+ }
+
+ return (arr);
+}
+
+
+
+
+/*
+ * static size_t joinlength(char * const *argv)
+ *
+ * return:
+ *
+ * the number of bytes in all the arrays pointed at
+ * by argv, including their null bytes(which will usually be turned
+ * into commas).
+ *
+ *
+ */
+
+static size_t
+joinlength(char * const *argv) {
+ int len = 0;
+
+ while (argv && *argv) {
+ len += (strlen(*argv) + 1);
+ argv++;
+ }
+
+ return (len);
+}
+
+
+
+/*
+ * int joinarray(char * const *argv, char *buffer, char delim)
+ *
+ * notes:
+ *
+ * Copy all the ARGV strings into the end of BUFFER
+ * separating them with DELIM. BUFFER is assumed to have
+ * enough space to hold everything and to be already null-terminated.
+ *
+ * return:
+ *
+ * 0 unless argv or buffer is NULL.
+ *
+ *
+ */
+
+static int
+joinarray(char * const *argv, char *buffer, char delim) {
+ char * const *p;
+ char sep[2];
+
+ if (argv == NULL || buffer == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ sep[0] = delim;
+ sep[1] = 0x0;
+
+ for (p = argv ; *p != NULL ; p++) {
+ strcat(buffer, *p);
+ if (*(p + 1) != NULL) {
+ strcat(buffer, sep);
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+ * static char * getfield(char **res, size_t reslen, char **ptr, char delim)
+ *
+ * notes:
+ *
+ * Stores in *RES, which is a buffer of length RESLEN, a
+ * copy of the bytes from *PTR up to and including the first
+ * instance of DELIM. If *RES is NULL, then it will be
+ * assigned a malloced buffer to hold the copy. *PTR is
+ * modified to point at the found delimiter.
+ *
+ * return:
+ *
+ * If there was no delimiter, then NULL is returned,
+ * otherewise *RES is returned.
+ *
+ */
+
+static char *
+getfield(char **res, size_t reslen, char **ptr, char delim) {
+ char *q;
+
+ if (res == NULL || ptr == NULL || *ptr == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ q = strchr(*ptr, delim);
+
+ if (q == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ } else {
+ if (*res == NULL) {
+ *res = strndup(*ptr, q - *ptr);
+ } else {
+ if (q - *ptr + 1 > reslen) { /* to big for res */
+ errno = EINVAL;
+ return (NULL);
+ } else {
+ strncpy(*res, *ptr, q - *ptr);
+ (*res)[q - *ptr] = 0x0;
+ }
+ }
+ *ptr = q + 1;
+ }
+
+ return (*res);
+}
+
+
+
+
+
+/*
+ * static char * strndup(const char *str, size_t len)
+ *
+ * notes:
+ *
+ * like strdup, except do len bytes instead of the whole string. Always
+ * null-terminates.
+ *
+ * return:
+ *
+ * The newly malloced string.
+ *
+ */
+
+static char *
+strndup(const char *str, size_t len) {
+ char *p = malloc(len + 1);
+
+ if (p == NULL)
+ return (NULL);
+ strncpy(p, str, len);
+ p[len] = 0x0;
+ return (p);
+}
+
+#if WANT_MAIN
+
+/*
+ * static int strcmp_nws(const char *a, const char *b)
+ *
+ * notes:
+ *
+ * do a strcmp, except uneven lengths of whitespace compare the same
+ *
+ * return:
+ *
+ */
+
+static int
+strcmp_nws(const char *a, const char *b) {
+ while (*a && *b) {
+ if (isspace(*a) && isspace(*b)) {
+ do {
+ a++;
+ } while (isspace(*a));
+ do {
+ b++;
+ } while (isspace(*b));
+ }
+ if (*a < *b)
+ return (-1);
+ else if (*a > *b)
+ return (1);
+
+ a++;
+ b++;;
+ }
+
+ if (*a == *b)
+ return (0);
+ else if (*a > *b)
+ return (1);
+ else
+ return (-1);
+}
+
+#endif
+
+
+
+
+
+/*
+ * static void free_array(char **argv, size_t entries)
+ *
+ * notes:
+ *
+ * Free argv and each of the pointers inside it. The end of
+ * the array is when a NULL pointer is found inside. If
+ * entries is > 0, then NULL pointers inside the array do
+ * not indicate the end of the array.
+ *
+ */
+
+static void
+free_array(char **argv, size_t entries) {
+ char **p = argv;
+ int useEntries = (entries > 0);
+
+ if (argv == NULL)
+ return;
+
+ while ((useEntries && entries > 0) || *p) {
+ if (*p)
+ free(*p);
+ p++;
+ if (useEntries)
+ entries--;
+ }
+ free(argv);
+}
+
+
+
+
+
+/* ************************************************** */
+
+#if WANT_MAIN
+
+/* takes an option to indicate what sort of marshalling(read the code) and
+ an argument. If the argument looks like a marshalled buffer(has a ':'
+ embedded) then it's unmarshalled and the remarshalled and the new string
+ is compared to the old one.
+*/
+
+int
+main(int argc, char **argv) {
+ char buffer[1024];
+ char *b = &buffer[0];
+ size_t len = sizeof buffer;
+ char option;
+
+ if (argc < 2 || argv[1][0] != '-')
+ exit(1);
+
+ option = argv[1][1];
+ argv++;
+ argc--;
+
+
+#if 0
+ {
+ char buff[10];
+ char *p = argv[1], *q = &buff[0];
+
+ while (getfield(&q, sizeof buff, &p, ':') != NULL) {
+ printf("field: \"%s\"\n", q);
+ p++;
+ }
+ printf("p is now \"%s\"\n", p);
+ }
+#endif
+
+#if 0
+ {
+ char **x = splitarray(argv[1], argv[1] + strlen(argv[1]),
+ argv[2][0]);
+ char **p;
+
+ if (x == NULL)
+ printf("split failed\n");
+
+ for (p = x ; p != NULL && *p != NULL ; p++) {
+ printf("\"%s\"\n", *p);
+ }
+ }
+#endif
+
+#if 1
+ switch(option) {
+ case 'n': {
+ struct nwent ne;
+ int i;
+
+ if (strchr(argv[1], ':') != NULL) {
+ if (irp_unmarshall_nw(&ne, argv[1]) != 0) {
+ printf("Unmarhsalling failed\n");
+ exit(1);
+ }
+
+ printf("Name: \"%s\"\n", ne.n_name);
+ printf("Aliases:");
+ for (i = 0 ; ne.n_aliases[i] != NULL ; i++)
+ printf("\n\t\"%s\"", ne.n_aliases[i]);
+ printf("\nAddrtype: %s\n", ADDR_T_STR(ne.n_addrtype));
+ inet_net_ntop(ne.n_addrtype, ne.n_addr, ne.n_length,
+ buffer, sizeof buffer);
+ printf("Net: \"%s\"\n", buffer);
+ *((long*)ne.n_addr) = htonl(*((long*)ne.n_addr));
+ inet_net_ntop(ne.n_addrtype, ne.n_addr, ne.n_length,
+ buffer, sizeof buffer);
+ printf("Corrected Net: \"%s\"\n", buffer);
+ } else {
+ struct netent *np1 = getnetbyname(argv[1]);
+ ne.n_name = np1->n_name;
+ ne.n_aliases = np1->n_aliases;
+ ne.n_addrtype = np1->n_addrtype;
+ ne.n_addr = &np1->n_net;
+ ne.n_length = (IN_CLASSA(np1->n_net) ?
+ 8 :
+ (IN_CLASSB(np1->n_net) ?
+ 16 :
+ (IN_CLASSC(np1->n_net) ?
+ 24 : -1)));
+ np1->n_net = htonl(np1->n_net);
+ if (irp_marshall_nw(&ne, &b, &len) != 0) {
+ printf("Marshalling failed\n");
+ }
+ printf("%s\n", b);
+ }
+ break;
+ }
+
+
+ case 'r': {
+ char **hosts, **users, **domains;
+ size_t entries;
+ int i;
+ char *buff;
+ size_t size;
+ char *ngname;
+
+ if (strchr(argv[1], '(') != NULL) {
+ if (irp_unmarshall_ng(&ngname, &entries,
+ &hosts, &users, &domains,
+ argv[1]) != 0) {
+ printf("unmarshall failed\n");
+ exit(1);
+ }
+
+#define STRVAL(x) (x == NULL ? "*" : x)
+
+ printf("%s {\n", ngname);
+ for (i = 0 ; i < entries ; i++)
+ printf("\t\"%s\" : \"%s\" : \"%s\"\n",
+ STRVAL(hosts[i]),
+ STRVAL(users[i]),
+ STRVAL(domains[i]));
+ printf("}\n\n\n");
+
+
+ irp_marshall_ng_start(ngname, NULL, &size);
+ for (i = 0 ; i < entries ; i++)
+ irp_marshall_ng_next(hosts[i], users[i],
+ domains[i], NULL, &size);
+ irp_marshall_ng_end(NULL, &size);
+
+ buff = malloc(size);
+
+ irp_marshall_ng_start(ngname, buff, &size);
+ for (i = 0 ; i < entries ; i++) {
+ if (irp_marshall_ng_next(hosts[i], users[i],
+ domains[i], buff,
+ &size) != 0)
+ printf("next marshalling failed.\n");
+ }
+ irp_marshall_ng_end(buff, &size);
+
+ if (strcmp_nws(argv[1], buff) != 0) {
+ printf("compare failed:\n\t%s\n\t%s\n",
+ buffer, argv[1]);
+ } else {
+ printf("compare ok\n");
+ }
+ } else {
+ char *h, *u, *d, *buff;
+ size_t size;
+
+ /* run through two times. First to figure out how
+ much of a buffer we need. Second to do the
+ actual marshalling */
+
+ setnetgrent(argv[1]);
+ irp_marshall_ng_start(argv[1], NULL, &size);
+ while (getnetgrent(&h, &u, &d) == 1)
+ irp_marshall_ng_next(h, u, d, NULL, &size);
+ irp_marshall_ng_end(NULL, &size);
+ endnetgrent(argv[1]);
+
+ buff = malloc(size);
+
+ setnetgrent(argv[1]);
+ if (irp_marshall_ng_start(argv[1], buff, &size) != 0)
+ printf("Marshalling start failed\n");
+
+ while (getnetgrent(&h, &u, &d) == 1) {
+ if (irp_marshall_ng_next(h, u, d, buff, &size)
+ != 0) {
+ printf("Marshalling failed\n");
+ }
+ }
+
+ irp_marshall_ng_end(buff, &size);
+ endnetgrent();
+
+ printf("success: %s\n", buff);
+ }
+ break;
+ }
+
+
+
+ case 'h': {
+ struct hostent he, *hp;
+ int i;
+
+
+ if (strchr(argv[1], '@') != NULL) {
+ if (irp_unmarshall_ho(&he, argv[1]) != 0) {
+ printf("unmarshall failed\n");
+ exit(1);
+ }
+
+ printf("Host: \"%s\"\nAliases:", he.h_name);
+ for (i = 0 ; he.h_aliases[i] != NULL ; i++)
+ printf("\n\t\t\"%s\"", he.h_aliases[i]);
+ printf("\nAddr Type: \"%s\"\n",
+ ADDR_T_STR(he.h_addrtype));
+ printf("Length: %d\nAddresses:", he.h_length);
+ for (i = 0 ; he.h_addr_list[i] != 0 ; i++) {
+ inet_ntop(he.h_addrtype, he.h_addr_list[i],
+ buffer, sizeof buffer);
+ printf("\n\t\"%s\"\n", buffer);
+ }
+ printf("\n\n");
+
+ irp_marshall_ho(&he, &b, &len);
+ if (strcmp(argv[1], buffer) != 0) {
+ printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
+ buffer, argv[1]);
+ } else {
+ printf("compare ok\n");
+ }
+ } else {
+ if ((hp = gethostbyname(argv[1])) == NULL) {
+ perror("gethostbyname");
+ printf("\"%s\"\n", argv[1]);
+ exit(1);
+ }
+
+ if (irp_marshall_ho(hp, &b, &len) != 0) {
+ printf("irp_marshall_ho failed\n");
+ exit(1);
+ }
+
+ printf("success: \"%s\"\n", buffer);
+ }
+ break;
+ }
+
+
+ case 's': {
+ struct servent *sv;
+ struct servent sv1;
+
+ if (strchr(argv[1], ':') != NULL) {
+ sv = &sv1;
+ memset(sv, 0xef, sizeof (struct servent));
+ if (irp_unmarshall_sv(sv, argv[1]) != 0) {
+ printf("unmarshall failed\n");
+
+ }
+
+ irp_marshall_sv(sv, &b, &len);
+ if (strcmp(argv[1], buffer) != 0) {
+ printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
+ buffer, argv[1]);
+ } else {
+ printf("compare ok\n");
+ }
+ } else {
+ if ((sv = getservbyname(argv[1], argv[2])) == NULL) {
+ perror("getservent");
+ exit(1);
+ }
+
+ if (irp_marshall_sv(sv, &b, &len) != 0) {
+ printf("irp_marshall_sv failed\n");
+ exit(1);
+ }
+
+ printf("success: \"%s\"\n", buffer);
+ }
+ break;
+ }
+
+ case 'g': {
+ struct group *gr;
+ struct group gr1;
+
+ if (strchr(argv[1], ':') != NULL) {
+ gr = &gr1;
+ memset(gr, 0xef, sizeof (struct group));
+ if (irp_unmarshall_gr(gr, argv[1]) != 0) {
+ printf("unmarshall failed\n");
+
+ }
+
+ irp_marshall_gr(gr, &b, &len);
+ if (strcmp(argv[1], buffer) != 0) {
+ printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
+ buffer, argv[1]);
+ } else {
+ printf("compare ok\n");
+ }
+ } else {
+ if ((gr = getgrnam(argv[1])) == NULL) {
+ perror("getgrnam");
+ exit(1);
+ }
+
+ if (irp_marshall_gr(gr, &b, &len) != 0) {
+ printf("irp_marshall_gr failed\n");
+ exit(1);
+ }
+
+ printf("success: \"%s\"\n", buffer);
+ }
+ break;
+ }
+
+
+ case 'p': {
+ struct passwd *pw;
+ struct passwd pw1;
+
+ if (strchr(argv[1], ':') != NULL) {
+ pw = &pw1;
+ memset(pw, 0xef, sizeof (*pw));
+ if (irp_unmarshall_pw(pw, argv[1]) != 0) {
+ printf("unmarshall failed\n");
+ exit(1);
+ }
+
+ printf("User: \"%s\"\nPasswd: \"%s\"\nUid: %ld\nGid: %ld\n",
+ pw->pw_name, pw->pw_passwd, (long)pw->pw_uid,
+ (long)pw->pw_gid);
+ printf("Class: \"%s\"\nChange: %ld\nGecos: \"%s\"\n",
+ pw->pw_class, (long)pw->pw_change, pw->pw_gecos);
+ printf("Shell: \"%s\"\nDirectory: \"%s\"\n",
+ pw->pw_shell, pw->pw_dir);
+
+ pw = getpwnam(pw->pw_name);
+ irp_marshall_pw(pw, &b, &len);
+ if (strcmp(argv[1], buffer) != 0) {
+ printf("compare failed:\n\t\"%s\"\n\t\"%s\"\n",
+ buffer, argv[1]);
+ } else {
+ printf("compare ok\n");
+ }
+ } else {
+ if ((pw = getpwnam(argv[1])) == NULL) {
+ perror("getpwnam");
+ exit(1);
+ }
+
+ if (irp_marshall_pw(pw, &b, &len) != 0) {
+ printf("irp_marshall_pw failed\n");
+ exit(1);
+ }
+
+ printf("success: \"%s\"\n", buffer);
+ }
+ break;
+ }
+
+ default:
+ printf("Wrong option: %c\n", option);
+ break;
+ }
+
+#endif
+
+ return (0);
+}
+
+#endif
diff --git a/contrib/bind/lib/irs/irs_data.c b/contrib/bind/lib/irs/irs_data.c
index 7f23751..f31fe69 100644
--- a/contrib/bind/lib/irs/irs_data.c
+++ b/contrib/bind/lib/irs/irs_data.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,24 +16,179 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: irs_data.c,v 1.7 1997/12/04 04:57:54 halley Exp $";
+static const char rcsid[] = "$Id: irs_data.c,v 1.14 1999/10/13 16:39:31 vixie Exp $";
#endif
#include "port_before.h"
+#ifndef __BIND_NOSTATIC
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <resolv.h>
#include <stdio.h>
+#include <isc/memcluster.h>
+
+#ifdef DO_PTHREADS
+#include <pthread.h>
+#endif
#include <irs.h>
#include "port_after.h"
#include "irs_data.h"
+#undef _res
+#undef h_errno
+
+extern struct __res_state _res;
+extern int h_errno;
+
+#ifdef DO_PTHREADS
+static pthread_key_t key;
+static int once = 0;
+#else
+static struct net_data *net_data;
+#endif
+
+void
+irs_destroy() {
+#ifndef DO_PTHREADS
+ if (net_data != NULL)
+ net_data_destroy(net_data);
+ net_data = NULL;
+#endif
+}
+
+void
+net_data_destroy(void *p) {
+ struct net_data *net_data = p;
+
+
+ res_nclose(net_data->res);
+ if (net_data->gr != NULL) {
+ (*net_data->gr->close)(net_data->gr);
+ net_data->gr = NULL;
+ }
+ if (net_data->pw != NULL) {
+ (*net_data->pw->close)(net_data->pw);
+ net_data->pw = NULL;
+ }
+ if (net_data->sv != NULL) {
+ (*net_data->sv->close)(net_data->sv);
+ net_data->sv = NULL;
+ }
+ if (net_data->pr != NULL) {
+ (*net_data->pr->close)(net_data->pr);
+ net_data->pr = NULL;
+ }
+ if (net_data->ho != NULL) {
+ (*net_data->ho->close)(net_data->ho);
+ net_data->ho = NULL;
+ }
+ if (net_data->nw != NULL) {
+ (*net_data->nw->close)(net_data->nw);
+ net_data->nw = NULL;
+ }
+ if (net_data->ng != NULL) {
+ (*net_data->ng->close)(net_data->ng);
+ net_data->ng = NULL;
+ }
+
+ (*net_data->irs->close)(net_data->irs);
+ memput(net_data, sizeof *net_data);
+}
+
+/* applications that need a specific config file other than
+ * _PATH_IRS_CONF should call net_data_init directly rather than letting
+ * the various wrapper functions make the first call. - brister
+ */
+
+struct net_data *
+net_data_init(const char *conf_file) {
+#ifdef DO_PTHREADS
+ static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER;
+ struct net_data *net_data;
+
+ if (!once) {
+ pthread_mutex_lock(&keylock);
+ if (!once++)
+ pthread_key_create(&key, net_data_destroy);
+ pthread_mutex_unlock(&keylock);
+ }
+ net_data = pthread_getspecific(key);
+#endif
+
+ if (net_data == NULL) {
+ net_data = net_data_create(conf_file);
+ if (net_data == NULL)
+ return (NULL);
+#ifdef DO_PTHREADS
+ pthread_setspecific(key, net_data);
+#endif
+ }
+
+ return (net_data);
+}
-struct net_data net_data;
+struct net_data *
+net_data_create(const char *conf_file) {
+ struct net_data *net_data;
+
+ net_data = memget(sizeof (struct net_data));
+ if (net_data == NULL)
+ return (NULL);
+ memset(net_data, 0, sizeof (struct net_data));
+
+ if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL)
+ return (NULL);
+#ifndef DO_PTHREADS
+ (*net_data->irs->res_set)(net_data->irs, &_res, NULL);
+#endif
-int
-net_data_init() {
- if (!net_data.irs)
- net_data.irs = irs_gen_acc("");
- return (net_data.irs != NULL);
+ net_data->res = (*net_data->irs->res_get)(net_data->irs);
+ if (net_data->res == NULL)
+ return (NULL);
+
+ if (res_ninit(net_data->res) == -1)
+ return (NULL);
+
+ return (net_data);
}
+
+
+
+void
+net_data_minimize(struct net_data *net_data) {
+ res_nclose(net_data->res);
+}
+
+struct __res_state *
+__res_state(void) {
+ /* NULL param here means use the default config file. */
+ struct net_data *net_data = net_data_init(NULL);
+ if (net_data && net_data->res)
+ return (net_data->res);
+
+ return (&_res);
+}
+
+int *
+__h_errno(void) {
+ /* NULL param here means use the default config file. */
+ struct net_data *net_data = net_data_init(NULL);
+ if (net_data && net_data->res)
+ return (&net_data->res->res_h_errno);
+ return (&h_errno);
+}
+
+void
+__h_errno_set(struct __res_state *res, int err) {
+
+ h_errno = res->res_h_errno = err;
+}
+
+#endif /*__BIND_NOSTATIC*/
diff --git a/contrib/bind/lib/irs/irs_data.h b/contrib/bind/lib/irs/irs_data.h
index 4356b57..c82d767 100644
--- a/contrib/bind/lib/irs/irs_data.h
+++ b/contrib/bind/lib/irs/irs_data.h
@@ -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,10 +16,11 @@
*/
/*
- * $Id: irs_data.h,v 1.7 1997/12/04 04:57:55 halley Exp $
+ * $Id: irs_data.h,v 1.12 1999/01/18 07:46:55 vixie Exp $
*/
-#define net_data __net_data
+#ifndef __BIND_NOSTATIC
+
#define net_data_init __net_data_init
struct net_data {
@@ -37,7 +38,8 @@ struct net_data {
struct passwd * pw_last;
struct servent * sv_last;
struct protoent * pr_last;
- struct netent * nw_last;
+ struct netent * nw_last; /* should have been ne_last */
+ struct nwent * nww_last;
struct hostent * ho_last;
unsigned int gr_stayopen :1;
@@ -50,8 +52,11 @@ struct net_data {
void * nw_data;
void * ho_data;
- char fill[512 - 68]; /* 68 = sizeof(above) */
+ struct __res_state * res; /* for gethostent.c */
+
};
-extern struct net_data net_data;
-extern int net_data_init(void);
+extern struct net_data * net_data_init(const char *conf_file);
+extern void net_data_minimize(struct net_data *);
+
+#endif /*__BIND_NOSTATIC*/
diff --git a/contrib/bind/lib/irs/irs_p.h b/contrib/bind/lib/irs/irs_p.h
index bc49665..d14f7d1 100644
--- a/contrib/bind/lib/irs/irs_p.h
+++ b/contrib/bind/lib/irs/irs_p.h
@@ -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,21 +16,34 @@
*/
/*
- * $Id: irs_p.h,v 1.6 1997/12/04 04:57:55 halley Exp $
+ * $Id: irs_p.h,v 1.8 1999/01/08 19:24:42 vixie Exp $
*/
#ifndef _IRS_P_H_INCLUDED
#define _IRS_P_H_INCLUDED
+#include <stdio.h>
+
#include "pathnames.h"
+#define IRS_SV_MAXALIASES 35
+
+struct lcl_sv {
+ FILE * fp;
+ char line[BUFSIZ+1];
+ struct servent serv;
+ char * serv_aliases[IRS_SV_MAXALIASES];
+};
+
#define irs_nul_ng __irs_nul_ng
#define map_v4v6_address __map_v4v6_address
#define make_group_list __make_group_list
+#define irs_lclsv_fnxt __irs_lclsv_fnxt
extern void map_v4v6_address(const char *src, char *dst);
extern int make_group_list(struct irs_gr *, const char *,
gid_t, gid_t *, int *);
extern struct irs_ng * irs_nul_ng(struct irs_acc *);
+extern struct servent * irs_lclsv_fnxt(struct lcl_sv *);
#endif
diff --git a/contrib/bind/lib/irs/lcl.c b/contrib/bind/lib/irs/lcl.c
index badbdfe..46c7743 100644
--- a/contrib/bind/lib/irs/lcl.c
+++ b/contrib/bind/lib/irs/lcl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: lcl.c,v 1.11 1998/03/21 00:59:49 halley Exp $";
+static const char rcsid[] = "$Id: lcl.c,v 1.15 1999/10/13 16:39:32 vixie Exp $";
#endif
/* Imports */
@@ -27,6 +27,13 @@ static char rcsid[] = "$Id: lcl.c,v 1.11 1998/03/21 00:59:49 halley Exp $";
#include <errno.h>
#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
+
#include <irs.h>
#include "port_after.h"
@@ -37,6 +44,9 @@ static char rcsid[] = "$Id: lcl.c,v 1.11 1998/03/21 00:59:49 halley Exp $";
/* Forward. */
static void lcl_close(struct irs_acc *);
+static struct __res_state * lcl_res_get(struct irs_acc *);
+static void lcl_res_set(struct irs_acc *, struct __res_state *,
+ void (*)(void *));
/* Public */
@@ -45,17 +55,19 @@ irs_lcl_acc(const char *options) {
struct irs_acc *acc;
struct lcl_p *lcl;
- if (!(acc = malloc(sizeof *acc))) {
+ if (!(acc = memget(sizeof *acc))) {
errno = ENOMEM;
return (NULL);
}
memset(acc, 0x5e, sizeof *acc);
- if (!(lcl = malloc(sizeof *lcl))) {
+ if (!(lcl = memget(sizeof *lcl))) {
errno = ENOMEM;
free(acc);
return (NULL);
}
memset(lcl, 0x5e, sizeof *lcl);
+ lcl->res = NULL;
+ lcl->free_res = NULL;
acc->private = lcl;
#ifdef WANT_IRS_GR
acc->gr_map = irs_lcl_gr;
@@ -72,17 +84,55 @@ irs_lcl_acc(const char *options) {
acc->ho_map = irs_lcl_ho;
acc->nw_map = irs_lcl_nw;
acc->ng_map = irs_lcl_ng;
+ acc->res_get = lcl_res_get;
+ acc->res_set = lcl_res_set;
acc->close = lcl_close;
return (acc);
}
/* Methods */
+static struct __res_state *
+lcl_res_get(struct irs_acc *this) {
+ struct lcl_p *lcl = (struct lcl_p *)this->private;
+
+ if (lcl->res == NULL) {
+ struct __res_state *res;
+ res = (struct __res_state *)malloc(sizeof *res);
+ if (res == NULL)
+ return (NULL);
+ memset(res, 0, sizeof *res);
+ lcl_res_set(this, res, free);
+ }
+
+ if ((lcl->res->options | RES_INIT) == 0 &&
+ res_ninit(lcl->res) < 0)
+ return (NULL);
+
+ return (lcl->res);
+}
+
+static void
+lcl_res_set(struct irs_acc *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct lcl_p *lcl = (struct lcl_p *)this->private;
+
+ if (lcl->res && lcl->free_res) {
+ res_nclose(lcl->res);
+ (*lcl->free_res)(lcl->res);
+ }
+
+ lcl->res = res;
+ lcl->free_res = free_res;
+}
static void
lcl_close(struct irs_acc *this) {
struct lcl_p *lcl = (struct lcl_p *)this->private;
- if (lcl)
- free(lcl);
- free(this);
+ if (lcl) {
+ if (lcl->free_res)
+ (*lcl->free_res)(lcl->res);
+ memput(lcl, sizeof *lcl);
+ }
+ memput(this, sizeof *this);
}
diff --git a/contrib/bind/lib/irs/lcl_gr.c b/contrib/bind/lib/irs/lcl_gr.c
index 5a5d503..acb85ee 100644
--- a/contrib/bind/lib/irs/lcl_gr.c
+++ b/contrib/bind/lib/irs/lcl_gr.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996, 1998 by Internet Software Consortium.
+ * Portions 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
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_gr.c,v 1.20 1998/03/21 00:59:49 halley Exp $";
+static const char rcsid[] = "$Id: lcl_gr.c,v 1.25 1999/10/13 17:11:19 vixie Exp $";
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
#endif /* LIBC_SCCS and not lint */
@@ -64,6 +64,9 @@ static int __bind_irs_gr_unneeded;
#include <sys/param.h>
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <errno.h>
#include <fcntl.h>
@@ -74,11 +77,14 @@ static int __bind_irs_gr_unneeded;
#include <unistd.h>
#include <irs.h>
-
-#include "port_after.h"
+#include <isc/memcluster.h>
#include "irs_p.h"
#include "lcl_p.h"
+#include "irp_p.h"
+
+#include "port_after.h"
+
/* Types. */
@@ -123,13 +129,13 @@ irs_lcl_gr(struct irs_acc *this) {
struct irs_gr *gr;
struct pvt *pvt;
- if (!(gr = malloc(sizeof *gr))) {
+ if (!(gr = memget(sizeof *gr))) {
errno = ENOMEM;
return (NULL);
}
memset(gr, 0x5e, sizeof *gr);
- if (!(pvt = malloc(sizeof *pvt))) {
- free(gr);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(gr, sizeof *gr);
errno = ENOMEM;
return (NULL);
}
@@ -142,6 +148,8 @@ irs_lcl_gr(struct irs_acc *this) {
gr->rewind = gr_rewind;
gr->list = make_group_list;
gr->minimize = gr_minimize;
+ gr->res_get = NULL;
+ gr->res_set = NULL;
return (gr);
}
@@ -157,8 +165,8 @@ gr_close(struct irs_gr *this) {
free(pvt->group.gr_mem);
if (pvt->membuf)
free(pvt->membuf);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct group *
@@ -271,13 +279,12 @@ grnext(struct pvt *pvt) {
static struct group *
grscan(struct irs_gr *this, int search, gid_t gid, const char *name) {
struct pvt *pvt = (struct pvt *)this->private;
- size_t linelen, n;
+ size_t n;
char *bp, **m, *p;
/* Read lines until we find one that matches our search criteria. */
for (;;) {
- bp = grnext(pvt);
- if (bp == NULL)
+ if ((bp = grnext(pvt)) == NULL)
return (NULL);
/* Optimize the usual case of searching for a name. */
@@ -320,8 +327,10 @@ grscan(struct irs_gr *this, int search, gid_t gid, const char *name) {
* to account for the NULL terminator. As above, allocate
* largest of INITIAL_NMEMB, or 2*n.
*/
- for (n = 2, p = bp; (p = strpbrk(p, ", ")) != NULL; ++p, ++n)
- (void)NULL;
+ n = 1;
+ if (bp != NULL)
+ for (n = 2, p = bp; (p = strpbrk(p, ", ")) != NULL; ++n)
+ p += strspn(p, ", ");
if (n > pvt->nmemb || pvt->group.gr_mem == NULL) {
if ((n *= 2) < INITIAL_NMEMB)
n = INITIAL_NMEMB;
diff --git a/contrib/bind/lib/irs/lcl_ho.c b/contrib/bind/lib/irs/lcl_ho.c
index b285d1c..5939207 100644
--- a/contrib/bind/lib/irs/lcl_ho.c
+++ b/contrib/bind/lib/irs/lcl_ho.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996 by Internet Software Consortium.
+ * Portions 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
@@ -52,7 +52,7 @@
/* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$Id: lcl_ho.c,v 1.15 1997/12/04 04:57:56 halley Exp $";
+static const char rcsid[] = "$Id: lcl_ho.c,v 1.25 1999/10/13 17:11:19 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -77,6 +77,7 @@ static char rcsid[] = "$Id: lcl_ho.c,v 1.15 1997/12/04 04:57:56 halley Exp $";
#include <string.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
@@ -89,8 +90,6 @@ static char rcsid[] = "$Id: lcl_ho.c,v 1.15 1997/12/04 04:57:56 halley Exp $";
# define SPRINTF(x) sprintf x
#endif
-extern int h_errno;
-
/* Definitions. */
#define MAXALIASES 35
@@ -110,6 +109,8 @@ struct pvt {
char * host_aliases[MAXALIASES];
char hostbuf[8*1024];
u_char host_addr[16]; /* IPv4 or IPv6 */
+ struct __res_state *res;
+ void (*free_res)(void *);
};
typedef union {
@@ -131,8 +132,13 @@ static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
static struct hostent * ho_next(struct irs_ho *this);
static void ho_rewind(struct irs_ho *this);
static void ho_minimize(struct irs_ho *this);
+static struct __res_state * ho_res_get(struct irs_ho *this);
+static void ho_res_set(struct irs_ho *this,
+ struct __res_state *res,
+ void (*free_res)(void *));
static size_t ns_namelen(const char *);
+static int init(struct irs_ho *this);
/* Portability. */
@@ -147,12 +153,13 @@ irs_lcl_ho(struct irs_acc *this) {
struct irs_ho *ho;
struct pvt *pvt;
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
- if (!(ho = malloc(sizeof *ho))) {
+ if (!(ho = memget(sizeof *ho))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -165,6 +172,8 @@ irs_lcl_ho(struct irs_acc *this) {
ho->next = ho_next;
ho->rewind = ho_rewind;
ho->minimize = ho_minimize;
+ ho->res_get = ho_res_get;
+ ho->res_set = ho_res_set;
return (ho);
}
@@ -174,19 +183,24 @@ static void
ho_close(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ ho_minimize(this);
if (pvt->fp)
(void) fclose(pvt->fp);
- free(pvt);
- free(this);
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct hostent *
ho_byname(struct irs_ho *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
struct hostent *hp;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (init(this) == -1)
return (NULL);
- if (_res.options & RES_USE_INET6) {
+
+ if (pvt->res->options & RES_USE_INET6) {
hp = ho_byname2(this, name, AF_INET6);
if (hp)
return (hp);
@@ -196,12 +210,14 @@ ho_byname(struct irs_ho *this, const char *name) {
static struct hostent *
ho_byname2(struct irs_ho *this, const char *name, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
struct hostent *hp;
char **hap;
size_t n;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (init(this) == -1)
return (NULL);
+
ho_rewind(this);
n = ns_namelen(name);
while ((hp = ho_next(this)) != NULL) {
@@ -220,21 +236,23 @@ ho_byname2(struct irs_ho *this, const char *name, int af) {
}
found:
if (!hp) {
- h_errno = HOST_NOT_FOUND;
+ RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
return (NULL);
}
- h_errno = NETDB_SUCCESS;
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
return (hp);
}
static struct hostent *
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
const u_char *uaddr = addr;
struct hostent *hp;
int size;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (init(this) == -1)
return (NULL);
+
if (af == AF_INET6 && len == IN6ADDRSZ &&
(!memcmp(uaddr, mapped, sizeof mapped) ||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
@@ -253,12 +271,12 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
break;
default:
errno = EAFNOSUPPORT;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
if (size > len) {
errno = EINVAL;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
@@ -289,10 +307,10 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
}
found:
if (!hp) {
- h_errno = HOST_NOT_FOUND;
+ RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
return (NULL);
}
- h_errno = NETDB_SUCCESS;
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
return (hp);
}
@@ -300,33 +318,67 @@ static struct hostent *
ho_next(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
char *cp, **q, *p;
- int af, len;
+ char *bufp, *ndbuf, *dbuf = NULL;
+ int c, af, len, bufsiz, offset;
+
+ if (init(this) == -1)
+ return (NULL);
if (!pvt->fp)
ho_rewind(this);
if (!pvt->fp) {
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
+ bufp = pvt->hostbuf;
+ bufsiz = sizeof pvt->hostbuf;
+ offset = 0;
again:
- if (!(p = fgets(pvt->hostbuf, sizeof pvt->hostbuf, pvt->fp))) {
- h_errno = HOST_NOT_FOUND;
+ if (!(p = fgets(bufp + offset, bufsiz - offset, pvt->fp))) {
+ RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
+ if (dbuf)
+ free(dbuf);
return (NULL);
}
- if (*p == '#')
+ if (!strchr(p, '\n') && !feof(pvt->fp)) {
+#define GROWBUF 1024
+ /* allocate space for longer line */
+ if (dbuf == NULL) {
+ if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
+ strcpy(ndbuf, bufp);
+ } else
+ ndbuf = realloc(dbuf, bufsiz + GROWBUF);
+ if (ndbuf) {
+ dbuf = ndbuf;
+ bufp = dbuf;
+ bufsiz += GROWBUF;
+ offset = strlen(dbuf);
+ } else {
+ /* allocation failed; skip this long line */
+ while ((c = getc(pvt->fp)) != EOF)
+ if (c == '\n')
+ break;
+ if (c != EOF)
+ ungetc(c, pvt->fp);
+ }
goto again;
- if (!(cp = strpbrk(p, "#\n")))
+ }
+
+ p -= offset;
+ offset = 0;
+
+ if (*p == '#')
goto again;
- *cp = '\0';
+ if ((cp = strpbrk(p, "#\n")) != NULL)
+ *cp = '\0';
if (!(cp = strpbrk(p, " \t")))
goto again;
*cp++ = '\0';
- if ((_res.options & RES_USE_INET6) &&
- inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
+ if (inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
af = AF_INET6;
len = IN6ADDRSZ;
} else if (inet_aton(p, (struct in_addr *)pvt->host_addr) > 0) {
- if (_res.options & RES_USE_INET6) {
+ if (pvt->res->options & RES_USE_INET6) {
map_v4v6_address((char*)pvt->host_addr,
(char*)pvt->host_addr);
af = AF_INET6;
@@ -360,7 +412,9 @@ ho_next(struct irs_ho *this) {
*cp++ = '\0';
}
*q = NULL;
- h_errno = NETDB_SUCCESS;
+ if (dbuf)
+ free(dbuf);
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
return (&pvt->host);
}
@@ -389,6 +443,40 @@ ho_minimize(struct irs_ho *this) {
(void)fclose(pvt->fp);
pvt->fp = NULL;
}
+ if (pvt->res)
+ res_nclose(pvt->res);
+}
+
+static struct __res_state *
+ho_res_get(struct irs_ho *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);
+ ho_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+ho_res_set(struct irs_ho *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. */
@@ -401,3 +489,15 @@ ns_namelen(const char *s) {
(void)NULL;
return ((size_t) i);
}
+
+static int
+init(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res && !ho_res_get(this))
+ return (-1);
+ if (((pvt->res->options & RES_INIT) == 0) &&
+ res_ninit(pvt->res) == -1)
+ return (-1);
+ return (0);
+}
diff --git a/contrib/bind/lib/irs/lcl_ng.c b/contrib/bind/lib/irs/lcl_ng.c
index ca7e7e2..03acbf6 100644
--- a/contrib/bind/lib/irs/lcl_ng.c
+++ b/contrib/bind/lib/irs/lcl_ng.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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,13 +16,17 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static char rcsid[] = "$Id: lcl_ng.c,v 1.12 1998/02/13 01:10:41 halley Exp $";
+static const char rcsid[] = "$Id: lcl_ng.c,v 1.16 1999/10/13 16:39:32 vixie Exp $";
#endif
/* Imports */
#include "port_before.h"
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -30,6 +34,7 @@ static char rcsid[] = "$Id: lcl_ng.c,v 1.12 1998/02/13 01:10:41 halley Exp $";
#include <unistd.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
@@ -100,13 +105,13 @@ irs_lcl_ng(struct irs_acc *this) {
struct irs_ng *ng;
struct pvt *pvt;
- if (!(ng = malloc(sizeof *ng))) {
+ if (!(ng = memget(sizeof *ng))) {
errno = ENOMEM;
return (NULL);
}
memset(ng, 0x5e, sizeof *ng);
- if (!(pvt = malloc(sizeof *pvt))) {
- free(ng);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(ng, sizeof *ng);
errno = ENOMEM;
return (NULL);
}
@@ -129,8 +134,8 @@ ng_close(struct irs_ng *this) {
if (pvt->fp != NULL)
fclose(pvt->fp);
freelists(this);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
/*
diff --git a/contrib/bind/lib/irs/lcl_nw.c b/contrib/bind/lib/irs/lcl_nw.c
index 09a324c..0d41ec4 100644
--- a/contrib/bind/lib/irs/lcl_nw.c
+++ b/contrib/bind/lib/irs/lcl_nw.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996 by Internet Software Consortium.
+ * Portions 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
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_nw.c,v 1.13 1997/12/04 04:57:57 halley Exp $";
+static const char rcsid[] = "$Id: lcl_nw.c,v 1.21 1999/10/15 19:49:10 vixie Exp $";
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
#endif /* LIBC_SCCS and not lint */
@@ -59,18 +59,21 @@ static const char rcsid[] = "$Id: lcl_nw.c,v 1.13 1997/12/04 04:57:57 halley Exp
#include "port_before.h"
#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 <errno.h>
#include <fcntl.h>
+#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
@@ -87,6 +90,8 @@ struct pvt {
struct nwent net;
char * aliases[MAXALIASES];
char addr[MAXADDRSIZE];
+ struct __res_state * res;
+ void (*free_res)(void *);
};
/* Forward */
@@ -97,6 +102,12 @@ 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 int init(struct irs_nw *this);
/* Portability. */
@@ -111,17 +122,17 @@ irs_lcl_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);
nw->private = pvt;
nw->close = nw_close;
nw->byname = nw_byname;
@@ -129,6 +140,8 @@ irs_lcl_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);
}
@@ -138,16 +151,22 @@ 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->fp)
(void)fclose(pvt->fp);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct nwent *
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
struct nwent *p;
+ if (init(this) == -1)
+ return(NULL);
+
nw_rewind(this);
while ((p = nw_next(this)) != NULL)
if (p->n_addrtype == type && p->n_length == length)
@@ -161,13 +180,16 @@ nw_byname(struct irs_nw *this, const char *name, int type) {
struct nwent *p;
char **ap;
+ if (init(this) == -1)
+ return(NULL);
+
nw_rewind(this);
while ((p = nw_next(this)) != NULL) {
- if (strcasecmp(p->n_name, name) == 0 &&
+ if (ns_samename(p->n_name, name) == 1 &&
p->n_addrtype == type)
break;
for (ap = p->n_aliases; *ap; ap++)
- if ((strcasecmp(*ap, name) == 0) &&
+ if ((ns_samename(*ap, name) == 1) &&
(p->n_addrtype == type))
goto found;
}
@@ -195,24 +217,60 @@ nw_rewind(struct irs_nw *this) {
static struct nwent *
nw_next(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ struct nwent *ret = NULL;
char *p, *cp, **q;
+ char *bufp, *ndbuf, *dbuf = NULL;
+ int c, bufsiz, offset = 0;
+
+ if (init(this) == -1)
+ return(NULL);
if (pvt->fp == NULL)
nw_rewind(this);
if (pvt->fp == NULL) {
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
+ bufp = pvt->line;
+ bufsiz = sizeof(pvt->line);
+
again:
- p = fgets(pvt->line, BUFSIZ, pvt->fp);
+ p = fgets(bufp + offset, bufsiz - offset, pvt->fp);
if (p == NULL)
- return (NULL);
+ goto cleanup;
+ if (!strchr(p, '\n') && !feof(pvt->fp)) {
+#define GROWBUF 1024
+ /* allocate space for longer line */
+ if (dbuf == NULL) {
+ if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
+ strcpy(ndbuf, bufp);
+ } else
+ ndbuf = realloc(dbuf, bufsiz + GROWBUF);
+ if (ndbuf) {
+ dbuf = ndbuf;
+ bufp = dbuf;
+ bufsiz += GROWBUF;
+ offset = strlen(dbuf);
+ } else {
+ /* allocation failed; skip this long line */
+ while ((c = getc(pvt->fp)) != EOF)
+ if (c == '\n')
+ break;
+ if (c != EOF)
+ ungetc(c, pvt->fp);
+ }
+ goto again;
+ }
+
+ p -= offset;
+ offset = 0;
+
if (*p == '#')
goto again;
+
cp = strpbrk(p, "#\n");
- if (cp == NULL)
- goto again;
- *cp = '\0';
+ if (cp != NULL)
+ *cp = '\0';
pvt->net.n_name = p;
cp = strpbrk(p, " \t");
if (cp == NULL)
@@ -245,15 +303,67 @@ nw_next(struct irs_nw *this) {
}
}
*q = NULL;
- return (&pvt->net);
+ ret = &pvt->net;
+
+ cleanup:
+ if (dbuf)
+ free(dbuf);
+
+ return (ret);
}
static void
nw_minimize(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ if (pvt->res)
+ res_nclose(pvt->res);
if (pvt->fp != NULL) {
(void)fclose(pvt->fp);
pvt->fp = NULL;
}
}
+
+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;
+}
+
+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);
+}
diff --git a/contrib/bind/lib/irs/lcl_p.h b/contrib/bind/lib/irs/lcl_p.h
index 058aeaa..b9e3b3e 100644
--- a/contrib/bind/lib/irs/lcl_p.h
+++ b/contrib/bind/lib/irs/lcl_p.h
@@ -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 @@
*/
/*
- * $Id: lcl_p.h,v 1.5 1996/10/25 07:23:19 vixie Exp $
+ * $Id: lcl_p.h,v 1.7 1999/01/08 19:24:51 vixie Exp $
*/
/*
@@ -30,7 +30,8 @@
* Object state.
*/
struct lcl_p {
- void *placeholder;
+ struct __res_state * res;
+ void (*free_res) __P((void *));
};
/*
diff --git a/contrib/bind/lib/irs/lcl_pr.c b/contrib/bind/lib/irs/lcl_pr.c
index 101f99d..5162115 100644
--- a/contrib/bind/lib/irs/lcl_pr.c
+++ b/contrib/bind/lib/irs/lcl_pr.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996 by Internet Software Consortium.
+ * Portions 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
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_pr.c,v 1.11 1997/12/04 04:57:57 halley Exp $";
+static const char rcsid[] = "$Id: lcl_pr.c,v 1.18 1999/10/13 17:11:20 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* extern */
@@ -57,6 +57,9 @@ static const char rcsid[] = "$Id: lcl_pr.c,v 1.11 1997/12/04 04:57:57 halley Exp
#include "port_before.h"
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <errno.h>
#include <fcntl.h>
@@ -65,6 +68,7 @@ static const char rcsid[] = "$Id: lcl_pr.c,v 1.11 1997/12/04 04:57:57 halley Exp
#include <stdlib.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
@@ -79,10 +83,10 @@ static const char rcsid[] = "$Id: lcl_pr.c,v 1.11 1997/12/04 04:57:57 halley Exp
/* Types */
struct pvt {
- FILE *fp;
- char line[BUFSIZ+1];
- struct protoent proto;
- char *proto_aliases[MAXALIASES];
+ FILE * fp;
+ char line[BUFSIZ+1];
+ struct protoent proto;
+ char * proto_aliases[MAXALIASES];
};
/* Forward */
@@ -107,12 +111,12 @@ irs_lcl_pr(struct irs_acc *this) {
struct irs_pr *pr;
struct pvt *pvt;
- if (!(pr = (struct irs_pr *)malloc(sizeof *pr))) {
+ if (!(pr = memget(sizeof *pr))) {
errno = ENOMEM;
return (NULL);
}
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(pr);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(pr, sizeof *this);
errno = ENOMEM;
return (NULL);
}
@@ -124,6 +128,8 @@ irs_lcl_pr(struct irs_acc *this) {
pr->next = pr_next;
pr->rewind = pr_rewind;
pr->minimize = pr_minimize;
+ pr->res_get = NULL;
+ pr->res_set = NULL;
return (pr);
}
@@ -135,8 +141,8 @@ pr_close(struct irs_pr *this) {
if (pvt->fp)
(void) fclose(pvt->fp);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct protoent *
@@ -189,20 +195,54 @@ static struct protoent *
pr_next(struct irs_pr *this) {
struct pvt *pvt = (struct pvt *)this->private;
char *p, *cp, **q;
+ char *bufp, *ndbuf, *dbuf = NULL;
+ int c, bufsiz, offset;
if (!pvt->fp)
pr_rewind(this);
if (!pvt->fp)
return (NULL);
+ bufp = pvt->line;
+ bufsiz = BUFSIZ;
+ offset = 0;
again:
- if ((p = fgets(pvt->line, BUFSIZ, pvt->fp)) == NULL)
+ if ((p = fgets(bufp + offset, bufsiz - offset, pvt->fp)) == NULL) {
+ if (dbuf)
+ free(dbuf);
return (NULL);
+ }
+ if (!strchr(p, '\n') && !feof(pvt->fp)) {
+#define GROWBUF 1024
+ /* allocate space for longer line */
+ if (dbuf == NULL) {
+ if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
+ strcpy(ndbuf, bufp);
+ } else
+ ndbuf = realloc(dbuf, bufsiz + GROWBUF);
+ if (ndbuf) {
+ dbuf = ndbuf;
+ bufp = dbuf;
+ bufsiz += GROWBUF;
+ offset = strlen(dbuf);
+ } else {
+ /* allocation failed; skip this long line */
+ while ((c = getc(pvt->fp)) != EOF)
+ if (c == '\n')
+ break;
+ if (c != EOF)
+ ungetc(c, pvt->fp);
+ }
+ goto again;
+ }
+
+ p -= offset;
+ offset = 0;
+
if (*p == '#')
goto again;
cp = strpbrk(p, "#\n");
- if (cp == NULL)
- goto again;
- *cp = '\0';
+ if (cp != NULL)
+ *cp = '\0';
pvt->proto.p_name = p;
cp = strpbrk(p, " \t");
if (cp == NULL)
diff --git a/contrib/bind/lib/irs/lcl_pw.c b/contrib/bind/lib/irs/lcl_pw.c
index 1f3e870..2655677 100644
--- a/contrib/bind/lib/irs/lcl_pw.c
+++ b/contrib/bind/lib/irs/lcl_pw.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996 by Internet Software Consortium.
+ * Portions 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
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_pw.c,v 1.16 1998/02/13 01:10:42 halley Exp $";
+static const char rcsid[] = "$Id: lcl_pw.c,v 1.19 1999/01/18 07:46:57 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Extern */
@@ -61,6 +61,10 @@ static int __bind_irs_pw_unneeded;
#else
#include <sys/param.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <db.h>
#include <errno.h>
@@ -73,6 +77,7 @@ static int __bind_irs_pw_unneeded;
#include <utmp.h>
#include <unistd.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -115,12 +120,12 @@ irs_lcl_pw(struct irs_acc *this) {
struct irs_pw *pw;
struct pvt *pvt;
- if (!(pw = malloc(sizeof *pw))) {
+ if (!(pw = memget(sizeof *pw))) {
errno = ENOMEM;
return (NULL);
}
memset(pw, 0x5e, sizeof *pw);
- if (!(pvt = malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
free(pw);
errno = ENOMEM;
return (NULL);
@@ -133,6 +138,8 @@ irs_lcl_pw(struct irs_acc *this) {
pw->byuid = pw_byuid;
pw->rewind = pw_rewind;
pw->minimize = pw_minimize;
+ pw->res_get = NULL;
+ pw->res_set = NULL;
return (pw);
}
@@ -147,9 +154,9 @@ pw_close(struct irs_pw *this) {
pvt->pw_db = NULL;
}
if (pvt->line)
- free(pvt->line);
- free(pvt);
- free(this);
+ memput(pvt->line, pvt->max);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct passwd *
@@ -262,9 +269,20 @@ hashpw(struct irs_pw *this, DBT *key) {
if ((pvt->pw_db->get)(pvt->pw_db, key, &data, 0))
return (0);
p = (char *)data.data;
- if (data.size > pvt->max &&
- (pvt->line = realloc(pvt->line, pvt->max += 1024)) == NULL)
- return (0);
+ if (data.size > pvt->max) {
+ size_t newlen = pvt->max + 1024;
+ char *p = memget(newlen);
+ if (p == NULL) {
+ return (0);
+ }
+ if (pvt->line != NULL) {
+ memcpy(p, pvt->line, pvt->max);
+ memput(pvt->line, pvt->max);
+ }
+ pvt->max = newlen;
+ pvt->line = p;
+ }
+
/* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
t = pvt->line;
l = pvt->line + pvt->max;
diff --git a/contrib/bind/lib/irs/lcl_sv.c b/contrib/bind/lib/irs/lcl_sv.c
index 0da9984..7e5bec9 100644
--- a/contrib/bind/lib/irs/lcl_sv.c
+++ b/contrib/bind/lib/irs/lcl_sv.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996 by Internet Software Consortium.
+ * Portions 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
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_sv.c,v 1.11 1997/12/04 04:57:58 halley Exp $";
+static const char rcsid[] = "$Id: lcl_sv.c,v 1.20 1999/10/07 20:44:03 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* extern */
@@ -58,31 +58,42 @@ static const char rcsid[] = "$Id: lcl_sv.c,v 1.11 1997/12/04 04:57:58 halley Exp
#include <sys/types.h>
#include <sys/socket.h>
-
#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#ifdef IRS_LCL_SV_DB
+#include <db.h>
+#endif
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
#include "irs_p.h"
#include "lcl_p.h"
-#define MAXALIASES 35
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
/* Types */
struct pvt {
- FILE * fp;
- char line[BUFSIZ+1];
- struct servent serv;
- char * serv_aliases[MAXALIASES];
+#ifdef IRS_LCL_SV_DB
+ DB * dbh;
+ int dbf;
+#endif
+ struct lcl_sv sv;
};
/* Forward */
@@ -94,6 +105,10 @@ static struct servent * sv_byname(struct irs_sv *, const char *,
static struct servent * sv_byport(struct irs_sv *, int, const char *);
static void sv_rewind(struct irs_sv *);
static void sv_minimize(struct irs_sv *);
+/*global*/ struct servent * irs_lclsv_fnxt(struct lcl_sv *);
+#ifdef IRS_LCL_SV_DB
+static struct servent * sv_db_rec(struct lcl_sv *, DBT *, DBT *);
+#endif
/* Portability */
@@ -108,13 +123,13 @@ irs_lcl_sv(struct irs_acc *this) {
struct irs_sv *sv;
struct pvt *pvt;
- if (!(sv = (struct irs_sv *)malloc(sizeof *sv))) {
+ if ((sv = memget(sizeof *sv)) == NULL) {
errno = ENOMEM;
return (NULL);
}
memset(sv, 0x5e, sizeof *sv);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(sv);
+ if ((pvt = memget(sizeof *pvt)) == NULL) {
+ memput(sv, sizeof *sv);
errno = ENOMEM;
return (NULL);
}
@@ -126,6 +141,11 @@ irs_lcl_sv(struct irs_acc *this) {
sv->byport = sv_byport;
sv->rewind = sv_rewind;
sv->minimize = sv_minimize;
+ sv->res_get = NULL;
+ sv->res_set = NULL;
+#ifdef IRS_LCL_SV_DB
+ pvt->dbf = R_FIRST;
+#endif
return (sv);
}
@@ -135,120 +155,278 @@ static void
sv_close(struct irs_sv *this) {
struct pvt *pvt = (struct pvt *)this->private;
- if (pvt->fp)
- fclose(pvt->fp);
- free(pvt);
- free(this);
+#ifdef IRS_LCL_SV_DB
+ if (pvt->dbh != NULL)
+ (*pvt->dbh->close)(pvt->dbh);
+#endif
+ if (pvt->sv.fp)
+ fclose(pvt->sv.fp);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct servent *
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
- register struct servent *p;
- register char **cp;
-
- sv_rewind(this);
- while ((p = sv_next(this))) {
- if (strcmp(name, p->s_name) == 0)
- goto gotname;
- for (cp = p->s_aliases; *cp; cp++)
- if (strcmp(name, *cp) == 0)
- goto gotname;
- continue;
+#ifdef IRS_LCL_SV_DB
+ struct pvt *pvt = (struct pvt *)this->private;
+#endif
+ struct servent *p;
+ char **cp;
+
+ sv_rewind(this);
+#ifdef IRS_LCL_SV_DB
+ if (pvt->dbh != NULL) {
+ DBT key, data;
+
+ /* Note that (sizeof "/") == 2. */
+ if ((strlen(name) + sizeof "/" + proto ? strlen(proto) : 0)
+ > sizeof pvt->sv.line)
+ goto try_local;
+ key.data = pvt->sv.line;
+ key.size = SPRINTF((pvt->sv.line, "%s/%s", name,
+ proto ? proto : "")) + 1;
+ if (proto != NULL) {
+ if ((*pvt->dbh->get)(pvt->dbh, &key, &data, 0) != 0)
+ return (NULL);
+ } else if ((*pvt->dbh->seq)(pvt->dbh, &key, &data, R_CURSOR)
+ != 0)
+ return (NULL);
+ return (sv_db_rec(&pvt->sv, &key, &data));
+ }
+ try_local:
+#endif
+
+ while ((p = sv_next(this))) {
+ if (strcmp(name, p->s_name) == 0)
+ goto gotname;
+ for (cp = p->s_aliases; *cp; cp++)
+ if (strcmp(name, *cp) == 0)
+ goto gotname;
+ continue;
gotname:
- if (proto == NULL || strcmp(p->s_proto, proto) == 0)
- break;
+ if (proto == NULL || strcmp(p->s_proto, proto) == 0)
+ break;
}
return (p);
}
static struct servent *
sv_byport(struct irs_sv *this, int port, const char *proto) {
- register struct servent *p;
-
- sv_rewind(this);
- while ((p = sv_next(this))) {
- if (p->s_port != port)
- continue;
- if (proto == NULL || strcmp(p->s_proto, proto) == 0)
- break;
- }
- return (p);
+#ifdef IRS_LCL_SV_DB
+ struct pvt *pvt = (struct pvt *)this->private;
+#endif
+ struct servent *p;
+
+ sv_rewind(this);
+#ifdef IRS_LCL_SV_DB
+ if (pvt->dbh != NULL) {
+ DBT key, data;
+ u_short *ports;
+
+ ports = (u_short *)pvt->sv.line;
+ ports[0] = 0;
+ ports[1] = port;
+ key.data = ports;
+ key.size = sizeof(u_short) * 2;
+ if (proto && *proto) {
+ strncpy((char *)ports + key.size, proto,
+ BUFSIZ - key.size);
+ key.size += strlen((char *)ports + key.size) + 1;
+ if ((*pvt->dbh->get)(pvt->dbh, &key, &data, 0) != 0)
+ return (NULL);
+ } else {
+ if ((*pvt->dbh->seq)(pvt->dbh, &key, &data, R_CURSOR)
+ != 0)
+ return (NULL);
+ }
+ return (sv_db_rec(&pvt->sv, &key, &data));
+ }
+#endif
+ while ((p = sv_next(this))) {
+ if (p->s_port != port)
+ continue;
+ if (proto == NULL || strcmp(p->s_proto, proto) == 0)
+ break;
+ }
+ return (p);
}
static void
sv_rewind(struct irs_sv *this) {
struct pvt *pvt = (struct pvt *)this->private;
- if (pvt->fp) {
- if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
+ if (pvt->sv.fp) {
+ if (fseek(pvt->sv.fp, 0L, SEEK_SET) == 0)
return;
- (void)fclose(pvt->fp);
+ (void)fclose(pvt->sv.fp);
+ pvt->sv.fp = NULL;
}
- if (!(pvt->fp = fopen(_PATH_SERVICES, "r" )))
+#ifdef IRS_LCL_SV_DB
+ pvt->dbf = R_FIRST;
+ if (pvt->dbh != NULL)
+ return;
+ pvt->dbh = dbopen(_PATH_SERVICES_DB, O_RDONLY,O_RDONLY,DB_BTREE, NULL);
+ if (pvt->dbh != NULL) {
+ if (fcntl((*pvt->dbh->fd)(pvt->dbh), F_SETFD, 1) < 0) {
+ (*pvt->dbh->close)(pvt->dbh);
+ pvt->dbh = NULL;
+ }
return;
- if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
- (void)fclose(pvt->fp);
- pvt->fp = NULL;
+ }
+#endif
+ if ((pvt->sv.fp = fopen(_PATH_SERVICES, "r")) == NULL)
+ return;
+ if (fcntl(fileno(pvt->sv.fp), F_SETFD, 1) < 0) {
+ (void)fclose(pvt->sv.fp);
+ pvt->sv.fp = NULL;
}
}
static struct servent *
sv_next(struct irs_sv *this) {
struct pvt *pvt = (struct pvt *)this->private;
- char *p;
- register char *cp, **q;
- if (!pvt->fp)
+#ifdef IRS_LCL_SV_DB
+ if (pvt->dbh != NULL)
+ NULL;
+ else
+#endif
+ if (pvt->sv.fp != NULL)
+ NULL;
+ else
sv_rewind(this);
- if (!pvt->fp)
+
+#ifdef IRS_LCL_SV_DB
+ if (pvt->dbh != NULL) {
+ DBT key, data;
+
+ while ((*pvt->dbh->seq)(pvt->dbh, &key, &data, pvt->dbf) == 0){
+ pvt->dbf = R_NEXT;
+ if (((char *)key.data)[0])
+ continue;
+ return (sv_db_rec(&pvt->sv, &key, &data));
+ }
+ }
+#endif
+
+ if (pvt->sv.fp == NULL)
return (NULL);
+ return (irs_lclsv_fnxt(&pvt->sv));
+}
+
+static void
+sv_minimize(struct irs_sv *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+#ifdef IRS_LCL_SV_DB
+ if (pvt->dbh != NULL) {
+ (*pvt->dbh->close)(pvt->dbh);
+ pvt->dbh = NULL;
+ }
+#endif
+ if (pvt->sv.fp != NULL) {
+ (void)fclose(pvt->sv.fp);
+ pvt->sv.fp = NULL;
+ }
+}
+
+/* Quasipublic. */
+
+struct servent *
+irs_lclsv_fnxt(struct lcl_sv *sv) {
+ char *p, *cp, **q;
+
again:
- if ((p = fgets(pvt->line, BUFSIZ, pvt->fp)) == NULL)
+ if ((p = fgets(sv->line, BUFSIZ, sv->fp)) == NULL)
return (NULL);
if (*p == '#')
goto again;
- cp = strpbrk(p, "#\n");
- if (cp == NULL)
- goto again;
- *cp = '\0';
- pvt->serv.s_name = p;
- p = strpbrk(p, " \t");
- if (p == NULL)
+ sv->serv.s_name = p;
+ while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
+ ++p;
+ if (*p == '\0' || *p == '#' || *p == '\n')
goto again;
*p++ = '\0';
while (*p == ' ' || *p == '\t')
p++;
- cp = strpbrk(p, ",/");
- if (cp == NULL)
+ if (*p == '\0' || *p == '#' || *p == '\n')
goto again;
- *cp++ = '\0';
- pvt->serv.s_port = htons((u_short)atoi(p));
- pvt->serv.s_proto = cp;
- q = pvt->serv.s_aliases = pvt->serv_aliases;
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (q < &pvt->serv_aliases[MAXALIASES - 1])
- *q++ = cp;
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
+ sv->serv.s_port = htons((u_short)strtol(p, &cp, 10));
+ if (cp == p || (*cp != '/' && *cp != ','))
+ goto again;
+ p = cp + 1;
+ sv->serv.s_proto = p;
+
+ q = sv->serv.s_aliases = sv->serv_aliases;
+
+ while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
+ ++p;
+
+ while (*p == ' ' || *p == '\t') {
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ ++p;
+ if (*p == '\0' || *p == '#' || *p == '\n')
+ break;
+ if (q < &sv->serv_aliases[IRS_SV_MAXALIASES - 1])
+ *q++ = p;
+ while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
+ ++p;
}
+
+ *p = '\0';
*q = NULL;
- return (&pvt->serv);
+ return (&sv->serv);
}
-static void
-sv_minimize(struct irs_sv *this) {
- struct pvt *pvt = (struct pvt *)this->private;
+/* Private. */
- if (pvt->fp != NULL) {
- (void)fclose(pvt->fp);
- pvt->fp = NULL;
+#ifdef IRS_LCL_SV_DB
+static struct servent *
+sv_db_rec(struct lcl_sv *sv, DBT *key, DBT *data) {
+ char *p, **q;
+ int n;
+
+ p = data->data;
+ p[data->size - 1] = '\0'; /* should be, but we depend on it */
+
+ if (((char *)key->data)[0] == '\0') {
+ if (key->size < sizeof(u_short)*2 || data->size < 2)
+ return (NULL);
+ sv->serv.s_port = ((u_short *)key->data)[1];
+ n = strlen(p) + 1;
+ if (n > sizeof(sv->line)) {
+ n = sizeof(sv->line);
+ }
+ memcpy(sv->line, p, n);
+ sv->serv.s_name = sv->line;
+ if ((sv->serv.s_proto = strchr(sv->line, '/')) != NULL)
+ *(sv->serv.s_proto)++ = '\0';
+ p += n;
+ data->size -= n;
+ } else {
+ if (data->size < sizeof(u_short) + 1)
+ return (NULL);
+ if (key->size > sizeof(sv->line))
+ key->size = sizeof(sv->line);
+ ((char *)key->data)[key->size - 1] = '\0';
+ memcpy(sv->line, key->data, key->size);
+ sv->serv.s_name = sv->line;
+ if ((sv->serv.s_proto = strchr(sv->line, '/')) != NULL)
+ *(sv->serv.s_proto)++ = '\0';
+ sv->serv.s_port = *(u_short *)data->data;
+ p += sizeof(u_short);
+ data->size -= sizeof(u_short);
}
+ q = sv->serv.s_aliases = sv->serv_aliases;
+ while (data->size > 0 && q < &sv->serv_aliases[IRS_SV_MAXALIASES - 1]) {
+
+ *q++ = p;
+ n = strlen(p) + 1;
+ data->size -= n;
+ p += n;
+ }
+ *q = NULL;
+ return (&sv->serv);
}
+#endif
diff --git a/contrib/bind/lib/irs/nis.c b/contrib/bind/lib/irs/nis.c
index d53bde9..fcd9b79 100644
--- a/contrib/bind/lib/irs/nis.c
+++ b/contrib/bind/lib/irs/nis.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 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.c,v 1.10 1998/03/21 00:59:50 halley Exp $";
+static const char rcsid[] = "$Id: nis.c,v 1.13 1999/01/18 07:46:58 vixie Exp $";
#endif
/* Imports */
@@ -34,6 +34,12 @@ static const char rcsid[] = "$Id: nis.c,v 1.10 1998/03/21 00:59:50 halley Exp $"
#include <string.h>
#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -45,6 +51,9 @@ static const char rcsid[] = "$Id: nis.c,v 1.10 1998/03/21 00:59:50 halley Exp $"
/* Forward */
static void nis_close(struct irs_acc *);
+static struct __res_state * nis_res_get(struct irs_acc *);
+static void nis_res_set(struct irs_acc *, struct __res_state *,
+ void (*)(void *));
/* Public */
@@ -56,13 +65,13 @@ irs_nis_acc(const char *options) {
if (yp_get_default_domain(&domain) != 0)
return (NULL);
- if (!(nis = malloc(sizeof *nis))) {
+ if (!(nis = memget(sizeof *nis))) {
errno = ENOMEM;
return (NULL);
}
memset(nis, 0, sizeof *nis);
- if (!(acc = malloc(sizeof *acc))) {
- free(nis);
+ if (!(acc = memget(sizeof *acc))) {
+ memput(nis, sizeof *nis);
errno = ENOMEM;
return (NULL);
}
@@ -84,19 +93,57 @@ irs_nis_acc(const char *options) {
acc->ho_map = irs_nis_ho;
acc->nw_map = irs_nis_nw;
acc->ng_map = irs_nis_ng;
+ acc->res_get = nis_res_get;
+ acc->res_set = nis_res_set;
acc->close = nis_close;
return (acc);
}
/* Methods */
+static struct __res_state *
+nis_res_get(struct irs_acc *this) {
+ struct nis_p *nis = (struct nis_p *)this->private;
+
+ if (nis->res == NULL) {
+ struct __res_state *res;
+ res = (struct __res_state *)malloc(sizeof *res);
+ if (res == NULL)
+ return (NULL);
+ memset(res, 0, sizeof *res);
+ nis_res_set(this, res, free);
+ }
+
+ if ((nis->res->options | RES_INIT) == 0 &&
+ res_ninit(nis->res) < 0)
+ return (NULL);
+
+ return (nis->res);
+}
+
+static void
+nis_res_set(struct irs_acc *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct nis_p *nis = (struct nis_p *)this->private;
+
+ if (nis->res && nis->free_res) {
+ res_nclose(nis->res);
+ (*nis->free_res)(nis->res);
+ }
+
+ nis->res = res;
+ nis->free_res = free_res;
+}
+
static void
nis_close(struct irs_acc *this) {
struct nis_p *nis = (struct nis_p *)this->private;
+ if (nis->res && nis->free_res)
+ (*nis->free_res)(nis->res);
free(nis->domain);
- free(nis);
- free(this);
+ memput(nis, sizeof *nis);
+ memput(this, sizeof *this);
}
#endif /*WANT_IRS_NIS*/
diff --git a/contrib/bind/lib/irs/nis_gr.c b/contrib/bind/lib/irs/nis_gr.c
index aa2f30c..713437a 100644
--- a/contrib/bind/lib/irs/nis_gr.c
+++ b/contrib/bind/lib/irs/nis_gr.c
@@ -32,7 +32,7 @@
*/
/*
- * Portions Copyright (c) 1996, 1997, 1998 by Internet Software Consortium.
+ * Portions 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
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_gr.c,v 1.13 1998/03/21 00:59:50 halley Exp $";
+static const char rcsid[] = "$Id: nis_gr.c,v 1.20 1999/01/30 00:53:16 vixie Exp $";
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
#endif /* LIBC_SCCS and not lint */
@@ -64,6 +64,10 @@ static int __bind_irs_gr_unneeded;
#include <sys/param.h>
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <isc/memcluster.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
@@ -77,6 +81,8 @@ static int __bind_irs_gr_unneeded;
#include <string.h>
#include <unistd.h>
+#include <isc/memcluster.h>
+
#include <irs.h>
#include "port_after.h"
@@ -130,13 +136,13 @@ irs_nis_gr(struct irs_acc *this) {
struct irs_gr *gr;
struct pvt *pvt;
- if (!(gr = malloc(sizeof *gr))) {
+ if (!(gr = memget(sizeof *gr))) {
errno = ENOMEM;
return (NULL);
}
memset(gr, 0x5e, sizeof *gr);
- if (!(pvt = malloc(sizeof *pvt))) {
- free(gr);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(gr, sizeof *gr);
errno = ENOMEM;
return (NULL);
}
@@ -151,6 +157,8 @@ irs_nis_gr(struct irs_acc *this) {
gr->rewind = gr_rewind;
gr->list = make_group_list;
gr->minimize = gr_minimize;
+ gr->res_get = NULL;
+ gr->res_set = NULL;
return (gr);
}
@@ -164,8 +172,8 @@ gr_close(struct irs_gr *this) {
free(pvt->group.gr_mem);
if (pvt->membuf)
free(pvt->membuf);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct group *
@@ -286,6 +294,9 @@ makegroupent(struct irs_gr *this) {
goto cleanup;
cp++;
+ if (*cp && cp[strlen(cp)-1] == '\n')
+ cp[strlen(cp)-1] = '\0';
+
/*
* Parse the members out.
*/
diff --git a/contrib/bind/lib/irs/nis_ho.c b/contrib/bind/lib/irs/nis_ho.c
index 65bdb4b..07d2274 100644
--- a/contrib/bind/lib/irs/nis_ho.c
+++ b/contrib/bind/lib/irs/nis_ho.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 char rcsid[] = "$Id: nis_ho.c,v 1.10 1997/12/04 04:57:59 halley Exp $";
+static const char rcsid[] = "$Id: nis_ho.c,v 1.16 1999/10/13 16:39:32 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -46,6 +46,7 @@ static int __bind_irs_nis_unneeded;
#include <stdio.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -53,8 +54,6 @@ static int __bind_irs_nis_unneeded;
#include "irs_p.h"
#include "nis_p.h"
-extern int h_errno;
-
/* Definitions */
#define MAXALIASES 35
@@ -78,6 +77,8 @@ struct pvt {
char * host_aliases[MAXALIASES + 1];
char hostbuf[8*1024];
u_char host_addr[16]; /* IPv4 or IPv6 */
+ struct __res_state *res;
+ void (*free_res)(void *);
};
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
@@ -98,9 +99,14 @@ static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
static struct hostent * ho_next(struct irs_ho *this);
static void ho_rewind(struct irs_ho *this);
static void ho_minimize(struct irs_ho *this);
+static struct __res_state * ho_res_get(struct irs_ho *this);
+static void ho_res_set(struct irs_ho *this,
+ struct __res_state *res,
+ void (*free_res)(void *));
static struct hostent * makehostent(struct irs_ho *this);
static void nisfree(struct pvt *, enum do_what);
+static int init(struct irs_ho *this);
/* Public */
@@ -109,17 +115,17 @@ irs_nis_ho(struct irs_acc *this) {
struct irs_ho *ho;
struct pvt *pvt;
- if (!(ho = malloc(sizeof *ho))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
- memset(ho, 0x5e, sizeof *ho);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(ho);
+ memset(pvt, 0, sizeof *pvt);
+ if (!(ho = memget(sizeof *ho))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
- memset(pvt, 0, sizeof *pvt);
+ memset(ho, 0x5e, sizeof *ho);
pvt->needrewind = 1;
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
ho->private = pvt;
@@ -130,6 +136,8 @@ irs_nis_ho(struct irs_acc *this) {
ho->next = ho_next;
ho->rewind = ho_rewind;
ho->minimize = ho_minimize;
+ ho->res_set = ho_res_set;
+ ho->res_get = ho_res_get;
return (ho);
}
@@ -139,18 +147,23 @@ static void
ho_close(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
+ ho_minimize(this);
nisfree(pvt, do_all);
- free(pvt);
- free(this);
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct hostent *
ho_byname(struct irs_ho *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
struct hostent *hp;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if (init(this) == -1)
return (NULL);
- if (_res.options & RES_USE_INET6) {
+
+ if (pvt->res->options & RES_USE_INET6) {
hp = ho_byname2(this, name, AF_INET6);
if (hp)
return (hp);
@@ -163,11 +176,14 @@ ho_byname2(struct irs_ho *this, const char *name, int af) {
struct pvt *pvt = (struct pvt *)this->private;
int r;
+ if (init(this) == -1)
+ return (NULL);
+
nisfree(pvt, do_val);
r = yp_match(pvt->nis_domain, hosts_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 (makehostent(this));
@@ -180,6 +196,9 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
const u_char *uaddr = addr;
int r;
+ if (init(this) == -1)
+ return (NULL);
+
if (af == AF_INET6 && len == IN6ADDRSZ &&
(!memcmp(uaddr, mapped, sizeof mapped) ||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
@@ -190,14 +209,14 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
len = INADDRSZ;
}
if (inet_ntop(af, uaddr, tmp, sizeof tmp) == NULL) {
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
nisfree(pvt, do_val);
r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp),
&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 (makehostent(this));
@@ -209,6 +228,9 @@ ho_next(struct irs_ho *this) {
struct hostent *rval;
int r;
+ if (init(this) == -1)
+ return (NULL);
+
do {
if (pvt->needrewind) {
nisfree(pvt, do_all);
@@ -230,7 +252,7 @@ ho_next(struct irs_ho *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 = makehostent(this);
@@ -247,7 +269,42 @@ ho_rewind(struct irs_ho *this) {
static void
ho_minimize(struct irs_ho *this) {
- /* NOOP */
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (pvt->res)
+ res_nclose(pvt->res);
+}
+
+static struct __res_state *
+ho_res_get(struct irs_ho *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);
+ ho_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+ho_res_set(struct irs_ho *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 */
@@ -260,17 +317,17 @@ makehostent(struct irs_ho *this) {
int af, len;
p = pvt->curval_data;
- if ((cp = strchr(p, '#')) != NULL)
+ if ((cp = strpbrk(p, "#\n")) != NULL)
*cp = '\0';
if (!(cp = strpbrk(p, spaces)))
return (NULL);
*cp++ = '\0';
- if ((_res.options & RES_USE_INET6) &&
+ if ((pvt->res->options & RES_USE_INET6) &&
inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
af = AF_INET6;
len = IN6ADDRSZ;
} else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) {
- if (_res.options & RES_USE_INET6) {
+ if (pvt->res->options & RES_USE_INET6) {
map_v4v6_address((char*)pvt->host_addr,
(char*)pvt->host_addr);
af = AF_INET6;
@@ -303,7 +360,7 @@ makehostent(struct irs_ho *this) {
*cp++ = '\0';
}
*q = NULL;
- h_errno = NETDB_SUCCESS;
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
return (&pvt->host);
}
@@ -319,4 +376,15 @@ nisfree(struct pvt *pvt, enum do_what do_what) {
}
}
+static int
+init(struct irs_ho *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res && !ho_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*/
diff --git a/contrib/bind/lib/irs/nis_ng.c b/contrib/bind/lib/irs/nis_ng.c
index 1667ca6..88d97ff 100644
--- a/contrib/bind/lib/irs/nis_ng.c
+++ b/contrib/bind/lib/irs/nis_ng.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_ng.c,v 1.10 1997/12/04 04:58:00 halley Exp $";
+static const char rcsid[] = "$Id: nis_ng.c,v 1.16 1999/01/18 07:46:58 vixie Exp $";
#endif
/* Imports */
@@ -34,7 +34,7 @@ static int __bind_irs_nis_unneeded;
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
-#include <assert.h>
+#include <isc/assertions.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
@@ -42,6 +42,11 @@ static int __bind_irs_nis_unneeded;
#include <stdlib.h>
#include <string.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -91,13 +96,13 @@ irs_nis_ng(struct irs_acc *this) {
struct irs_ng *ng;
struct pvt *pvt;
- if (!(ng = malloc(sizeof *ng))) {
+ if (!(ng = memget(sizeof *ng))) {
errno = ENOMEM;
return (NULL);
}
memset(ng, 0x5e, sizeof *ng);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(ng);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(ng, sizeof *ng);
errno = ENOMEM;
return (NULL);
}
@@ -119,14 +124,13 @@ ng_close(struct irs_ng *this) {
struct pvt *pvt = (struct pvt *)this->private;
tmpfree(pvt);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static int
ng_next(struct irs_ng *this, char **host, char **user, char **domain) {
struct pvt *pvt = (struct pvt *)this->private;
- struct netgrp *rval;
if (!pvt->cur)
return (0);
@@ -159,7 +163,6 @@ ng_test(struct irs_ng *this, const char *name,
static void
ng_rewind(struct irs_ng *this, const char *name) {
struct pvt *pvt = (struct pvt *)this->private;
- struct netgrp *rval;
/* Either hand back or free the existing list. */
if (pvt->tmpgroup) {
@@ -194,7 +197,10 @@ add_group_to_list(struct pvt *pvt, const char *name, int len) {
r = yp_match(pvt->nis_domain, netgroup_map, (char *)name, len,
&vdata, &vlen);
if (r == 0) {
- for (cp = vdata; cp; cp = np) {
+ cp = vdata;
+ if (*cp && cp[strlen(cp)-1] == '\n')
+ cp[strlen(cp)-1] = '\0';
+ for ( ; cp; cp = np) {
np = strchr(cp, ' ');
if (np)
*np++ = '\0';
@@ -212,7 +218,7 @@ add_tuple_to_list(struct pvt *pvt, const char *name, char *cp) {
struct tmpgrp *tmp;
char *tp, *np;
- assert(*cp++ == '(');
+ INSIST(*cp++ == '(');
tmp = malloc(sizeof *tmp + strlen(name) + sizeof '\0' +
strlen(cp) - sizeof ')');
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*/
diff --git a/contrib/bind/lib/irs/nis_p.h b/contrib/bind/lib/irs/nis_p.h
index 92d2647..d3dc126 100644
--- a/contrib/bind/lib/irs/nis_p.h
+++ b/contrib/bind/lib/irs/nis_p.h
@@ -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 @@
*/
/*
- * $Id: nis_p.h,v 1.4 1996/10/25 07:23:24 vixie Exp $
+ * $Id: nis_p.h,v 1.6 1999/01/08 19:25:03 vixie Exp $
*/
/*
@@ -27,7 +27,9 @@
* Object state.
*/
struct nis_p {
- char * domain;
+ char * domain;
+ struct __res_state * res;
+ void (*free_res) __P((void *));
};
diff --git a/contrib/bind/lib/irs/nis_pr.c b/contrib/bind/lib/irs/nis_pr.c
index 1653692..8dff084 100644
--- a/contrib/bind/lib/irs/nis_pr.c
+++ b/contrib/bind/lib/irs/nis_pr.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_pr.c,v 1.9 1997/12/04 04:58:00 halley Exp $";
+static const char rcsid[] = "$Id: nis_pr.c,v 1.13 1999/01/18 07:46:59 vixie Exp $";
#endif
/* Imports */
@@ -29,6 +29,8 @@ static int __bind_irs_nis_unneeded;
#include <sys/types.h>
#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
#include <rpcsvc/yp_prot.h>
@@ -41,6 +43,7 @@ static int __bind_irs_nis_unneeded;
#include <stdlib.h>
#include <errno.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -85,13 +88,13 @@ irs_nis_pr(struct irs_acc *this) {
struct irs_pr *pr;
struct pvt *pvt;
- if (!(pr = malloc(sizeof *pr))) {
+ if (!(pr = memget(sizeof *pr))) {
errno = ENOMEM;
return (NULL);
}
memset(pr, 0x5e, sizeof *pr);
- if (!(pvt = malloc(sizeof *pvt))) {
- free(pr);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(pr, sizeof *pr);
errno = ENOMEM;
return (NULL);
}
@@ -105,6 +108,8 @@ irs_nis_pr(struct irs_acc *this) {
pr->rewind = pr_rewind;
pr->close = pr_close;
pr->minimize = pr_minimize;
+ pr->res_get = NULL;
+ pr->res_set = NULL;
return (pr);
}
@@ -119,8 +124,8 @@ pr_close(struct irs_pr *this) {
free(pvt->proto.p_aliases);
if (pvt->prbuf)
free(pvt->prbuf);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct protoent *
@@ -182,7 +187,7 @@ pr_next(struct irs_pr *this) {
pvt->curkey_len = newkey_len;
}
if (r != 0) {
- h_errno = HOST_NOT_FOUND;
+ errno = ENOENT;
return (NULL);
}
rval = makeprotoent(this);
diff --git a/contrib/bind/lib/irs/nis_pw.c b/contrib/bind/lib/irs/nis_pw.c
index f06f796..ce90f20 100644
--- a/contrib/bind/lib/irs/nis_pw.c
+++ b/contrib/bind/lib/irs/nis_pw.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_pw.c,v 1.10 1997/12/04 04:58:01 halley Exp $";
+static const char rcsid[] = "$Id: nis_pw.c,v 1.16 1999/01/30 00:53:16 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -28,6 +28,11 @@ static int __bind_irs_pw_unneeded;
#else
#include <sys/param.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <isc/memcluster.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
#include <rpcsvc/yp_prot.h>
@@ -41,6 +46,8 @@ static int __bind_irs_pw_unneeded;
#include <string.h>
#include <unistd.h>
+#include <isc/memcluster.h>
+
#include <irs.h>
#include "port_after.h"
@@ -85,13 +92,13 @@ irs_nis_pw(struct irs_acc *this) {
struct irs_pw *pw;
struct pvt *pvt;
- if (!(pw = malloc(sizeof *pw))) {
+ if (!(pw = memget(sizeof *pw))) {
errno = ENOMEM;
return (NULL);
}
memset(pw, 0x5e, sizeof *pw);
- if (!(pvt = malloc(sizeof *pvt))) {
- free(pw);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(pw, sizeof *pw);
errno = ENOMEM;
return (NULL);
}
@@ -99,13 +106,15 @@ irs_nis_pw(struct irs_acc *this) {
pvt->needrewind = 1;
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
pw->private = pvt;
- pw->close = pw_close;
- pw->next = pw_next;
- pw->byname = pw_byname;
- pw->byuid = pw_byuid;
- pw->rewind = pw_rewind;
+ pw->close = pw_close;
+ pw->next = pw_next;
+ pw->byname = pw_byname;
+ pw->byuid = pw_byuid;
+ pw->rewind = pw_rewind;
pw->minimize = pw_minimize;
- return (pw);
+ pw->res_get = NULL;
+ pw->res_set = NULL;
+ return (pw);
}
/* Methods */
@@ -117,8 +126,8 @@ pw_close(struct irs_pw *this) {
if (pvt->pwbuf)
free(pvt->pwbuf);
nisfree(pvt, do_all);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct passwd *
@@ -155,7 +164,7 @@ pw_next(struct irs_pw *this) {
} while (rval == NULL);
return (rval);
}
-
+
static struct passwd *
pw_byname(struct irs_pw *this, const char *name) {
struct pvt *pvt = (struct pvt *)this->private;
@@ -170,7 +179,7 @@ pw_byname(struct irs_pw *this, const char *name) {
}
return (makepasswdent(this));
}
-
+
static struct passwd *
pw_byuid(struct irs_pw *this, uid_t uid) {
struct pvt *pvt = (struct pvt *)this->private;
@@ -246,6 +255,10 @@ makepasswdent(struct irs_pw *this) {
*cp++ = '\0';
pvt->passwd.pw_shell = cp;
+
+ if ((cp = strchr(cp, '\n')) != NULL)
+ *cp = '\0';
+
return (&pvt->passwd);
cleanup:
diff --git a/contrib/bind/lib/irs/nis_sv.c b/contrib/bind/lib/irs/nis_sv.c
index 1dacc2f..8810fd2 100644
--- a/contrib/bind/lib/irs/nis_sv.c
+++ b/contrib/bind/lib/irs/nis_sv.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_sv.c,v 1.10 1997/12/04 04:58:01 halley Exp $";
+static const char rcsid[] = "$Id: nis_sv.c,v 1.14 1999/01/18 07:46:59 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -28,6 +28,9 @@ static int __bind_irs_nis_unneeded;
#else
#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <sys/socket.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
@@ -40,6 +43,7 @@ static int __bind_irs_nis_unneeded;
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -85,13 +89,13 @@ irs_nis_sv(struct irs_acc *this) {
struct irs_sv *sv;
struct pvt *pvt;
- if (!(sv = (struct irs_sv *)malloc(sizeof *sv))) {
+ if (!(sv = memget(sizeof *sv))) {
errno = ENOMEM;
return (NULL);
}
memset(sv, 0x5e, sizeof *sv);
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
- free(sv);
+ if (!(pvt = memget(sizeof *pvt))) {
+ memput(sv, sizeof *sv);
errno = ENOMEM;
return (NULL);
}
@@ -105,6 +109,8 @@ irs_nis_sv(struct irs_acc *this) {
sv->byport = sv_byport;
sv->rewind = sv_rewind;
sv->minimize = sv_minimize;
+ sv->res_get = NULL;
+ sv->res_set = NULL;
return (sv);
}
@@ -119,8 +125,8 @@ sv_close(struct irs_sv *this) {
free(pvt->serv.s_aliases);
if (pvt->svbuf)
free(pvt->svbuf);
- free(pvt);
- free(this);
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct servent *
@@ -221,7 +227,7 @@ makeservent(struct irs_sv *this) {
pvt->serv.s_aliases = NULL;
}
- if ((p = strchr(pvt->svbuf, '#')))
+ if ((p = strpbrk(pvt->svbuf, "#\n")))
*p = '\0';
p = pvt->svbuf;
diff --git a/contrib/bind/lib/irs/nul_ng.c b/contrib/bind/lib/irs/nul_ng.c
index 0910d57..cc5c801 100644
--- a/contrib/bind/lib/irs/nul_ng.c
+++ b/contrib/bind/lib/irs/nul_ng.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: nul_ng.c,v 1.7 1997/12/04 04:58:01 halley Exp $";
+static const char rcsid[] = "$Id: nul_ng.c,v 1.10 1999/01/18 07:46:59 vixie Exp $";
#endif
/*
@@ -27,6 +27,8 @@ static const char rcsid[] = "$Id: nul_ng.c,v 1.7 1997/12/04 04:58:01 halley Exp
#include <sys/types.h>
#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <stdio.h>
#include <string.h>
@@ -36,6 +38,7 @@ static const char rcsid[] = "$Id: nul_ng.c,v 1.7 1997/12/04 04:58:01 halley Exp
#include <errno.h>
#include <irs.h>
+#include <isc/memcluster.h>
#include "port_after.h"
@@ -59,7 +62,7 @@ struct irs_ng *
irs_nul_ng(struct irs_acc *this) {
struct irs_ng *ng;
- if (!(ng = malloc(sizeof *ng))) {
+ if (!(ng = memget(sizeof *ng))) {
errno = ENOMEM;
return (NULL);
}
@@ -77,7 +80,7 @@ irs_nul_ng(struct irs_acc *this) {
static void
ng_close(struct irs_ng *this) {
- free(this);
+ memput(this, sizeof *this);
}
/* ARGSUSED */
diff --git a/contrib/bind/lib/irs/pathnames.h b/contrib/bind/lib/irs/pathnames.h
index 40a0472..1a225e5 100644
--- a/contrib/bind/lib/irs/pathnames.h
+++ b/contrib/bind/lib/irs/pathnames.h
@@ -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 @@
*/
/*
- * $Id: pathnames.h,v 1.5 1996/10/25 07:23:28 vixie Exp $
+ * $Id: pathnames.h,v 1.7 1999/01/08 19:25:10 vixie Exp $
*/
#ifndef _PATH_IRS_CONF
@@ -39,6 +39,12 @@
#define _PATH_SERVICES "/etc/services"
#endif
+#ifdef IRS_LCL_SV_DB
+#ifndef _PATH_SERVICES_DB
+#define _PATH_SERVICES_DB _PATH_SERVICES ".db"
+#endif
+#endif
+
#ifndef _PATH_HESIOD_CONF
#define _PATH_HESIOD_CONF "/etc/hesiod.conf"
#endif
diff --git a/contrib/bind/lib/irs/util.c b/contrib/bind/lib/irs/util.c
index f58f5ca2..8965af5 100644
--- a/contrib/bind/lib/irs/util.c
+++ b/contrib/bind/lib/irs/util.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: util.c,v 1.7 1997/12/04 04:58:02 halley Exp $";
+static const char rcsid[] = "$Id: util.c,v 1.10 1999/01/08 19:25:11 vixie Exp $";
#endif
#include "port_before.h"
@@ -25,8 +25,8 @@ static const char rcsid[] = "$Id: util.c,v 1.7 1997/12/04 04:58:02 halley Exp $"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
+#include <resolv.h>
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
OpenPOWER on IntegriCloud