diff options
Diffstat (limited to 'contrib/bind/lib/irs')
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> |