summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/irs
diff options
context:
space:
mode:
authornectar <nectar@FreeBSD.org>2002-02-04 19:12:46 +0000
committernectar <nectar@FreeBSD.org>2002-02-04 19:12:46 +0000
commitebeabb1ba32f14e308ae9aff9a2a7151265259cf (patch)
tree71ba64d0a82be4894e23f6d65f36b61203ec3875 /contrib/bind/lib/irs
parent1385a0dca8f9199ece158336f4c6a9f1e2e03c3e (diff)
downloadFreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.zip
FreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.tar.gz
Import of ISC BIND 8.3.1-REL.
Diffstat (limited to 'contrib/bind/lib/irs')
-rw-r--r--contrib/bind/lib/irs/Makefile4
-rw-r--r--contrib/bind/lib/irs/dns.c4
-rw-r--r--contrib/bind/lib/irs/dns_gr.c15
-rw-r--r--contrib/bind/lib/irs/dns_ho.c1083
-rw-r--r--contrib/bind/lib/irs/dns_nw.c16
-rw-r--r--contrib/bind/lib/irs/dns_pr.c13
-rw-r--r--contrib/bind/lib/irs/dns_pw.c5
-rw-r--r--contrib/bind/lib/irs/dns_sv.c26
-rw-r--r--contrib/bind/lib/irs/gai_strerror.c117
-rw-r--r--contrib/bind/lib/irs/gen.c7
-rw-r--r--contrib/bind/lib/irs/gen_gr.c33
-rw-r--r--contrib/bind/lib/irs/gen_ho.c50
-rw-r--r--contrib/bind/lib/irs/gen_ng.c9
-rw-r--r--contrib/bind/lib/irs/gen_p.h4
-rw-r--r--contrib/bind/lib/irs/getaddrinfo.c1516
-rw-r--r--contrib/bind/lib/irs/getgrent.c14
-rw-r--r--contrib/bind/lib/irs/getgrent_r.c24
-rw-r--r--contrib/bind/lib/irs/gethostent.c30
-rw-r--r--contrib/bind/lib/irs/gethostent_r.c43
-rw-r--r--contrib/bind/lib/irs/getnameinfo.c240
-rw-r--r--contrib/bind/lib/irs/getnetent.c7
-rw-r--r--contrib/bind/lib/irs/getnetent_r.c42
-rw-r--r--contrib/bind/lib/irs/getnetgrent.c6
-rw-r--r--contrib/bind/lib/irs/getnetgrent_r.c43
-rw-r--r--contrib/bind/lib/irs/getprotoent.c3
-rw-r--r--contrib/bind/lib/irs/getprotoent_r.c37
-rw-r--r--contrib/bind/lib/irs/getpwent_r.c40
-rw-r--r--contrib/bind/lib/irs/getservent.c3
-rw-r--r--contrib/bind/lib/irs/getservent_r.c37
-rw-r--r--contrib/bind/lib/irs/hesiod.c4
-rw-r--r--contrib/bind/lib/irs/irp.c14
-rw-r--r--contrib/bind/lib/irs/irp_gr.c7
-rw-r--r--contrib/bind/lib/irs/irp_ho.c15
-rw-r--r--contrib/bind/lib/irs/irp_ng.c14
-rw-r--r--contrib/bind/lib/irs/irp_p.h4
-rw-r--r--contrib/bind/lib/irs/irp_pw.c4
-rw-r--r--contrib/bind/lib/irs/irpmarshall.c37
-rw-r--r--contrib/bind/lib/irs/irs_data.c10
-rw-r--r--contrib/bind/lib/irs/lcl.c4
-rw-r--r--contrib/bind/lib/irs/lcl_gr.c6
-rw-r--r--contrib/bind/lib/irs/lcl_ho.c77
-rw-r--r--contrib/bind/lib/irs/lcl_ng.c16
-rw-r--r--contrib/bind/lib/irs/lcl_nw.c4
-rw-r--r--contrib/bind/lib/irs/lcl_pw.c4
-rw-r--r--contrib/bind/lib/irs/lcl_sv.c15
-rw-r--r--contrib/bind/lib/irs/nis.c4
-rw-r--r--contrib/bind/lib/irs/nis_gr.c7
-rw-r--r--contrib/bind/lib/irs/nis_ho.c81
-rw-r--r--contrib/bind/lib/irs/nis_ng.c18
-rw-r--r--contrib/bind/lib/irs/nis_nw.c8
-rw-r--r--contrib/bind/lib/irs/nis_pr.c23
-rw-r--r--contrib/bind/lib/irs/nis_pw.c9
-rw-r--r--contrib/bind/lib/irs/nis_sv.c5
-rw-r--r--contrib/bind/lib/irs/nul_ng.c23
-rw-r--r--contrib/bind/lib/irs/util.c4
55 files changed, 3083 insertions, 805 deletions
diff --git a/contrib/bind/lib/irs/Makefile b/contrib/bind/lib/irs/Makefile
index 4784ccf..0c4e46d 100644
--- a/contrib/bind/lib/irs/Makefile
+++ b/contrib/bind/lib/irs/Makefile
@@ -13,7 +13,7 @@
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
-# $Id: Makefile,v 8.21 2000/12/23 08:02:59 vixie Exp $
+# $Id: Makefile,v 8.24 2001/08/14 05:58:07 marka 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
@@ -83,7 +83,7 @@ ${LIBBIND}: ${OBJS}
${RANLIB} ${LIBBIND}
.c.${O}:
- if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi
+ mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED}
-(${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \
-o ${THREADED}/$*.${O} ; \
${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \
diff --git a/contrib/bind/lib/irs/dns.c b/contrib/bind/lib/irs/dns.c
index 66bdbf5..3feed26 100644
--- a/contrib/bind/lib/irs/dns.c
+++ b/contrib/bind/lib/irs/dns.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: dns.c,v 1.15 2000/02/28 07:52:16 vixie Exp $";
+static const char rcsid[] = "$Id: dns.c,v 1.16 2001/05/29 05:48:26 marka Exp $";
#endif
/*
@@ -59,6 +59,8 @@ irs_dns_acc(const char *options) {
struct irs_acc *acc;
struct dns_p *dns;
+ UNUSED(options);
+
if (!(acc = memget(sizeof *acc))) {
errno = ENOMEM;
return (NULL);
diff --git a/contrib/bind/lib/irs/dns_gr.c b/contrib/bind/lib/irs/dns_gr.c
index 64cbe9b..a622345 100644
--- a/contrib/bind/lib/irs/dns_gr.c
+++ b/contrib/bind/lib/irs/dns_gr.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: dns_gr.c,v 1.19 1999/01/18 07:46:48 vixie Exp $";
+static const char rcsid[] = "$Id: dns_gr.c,v 1.20 2001/05/29 05:48:27 marka Exp $";
#endif
/*
@@ -146,6 +146,9 @@ gr_close(struct irs_gr *this) {
static struct group *
gr_next(struct irs_gr *this) {
+
+ UNUSED(this);
+
return (NULL);
}
@@ -164,6 +167,9 @@ gr_bygid(struct irs_gr *this, gid_t gid) {
static void
gr_rewind(struct irs_gr *this) {
+
+ UNUSED(this);
+
/* NOOP */
}
@@ -171,6 +177,11 @@ static int
gr_list(struct irs_gr *this, const char *name,
gid_t basegid, gid_t *groups, int *ngroups)
{
+ UNUSED(this);
+ UNUSED(name);
+ UNUSED(basegid);
+ UNUSED(groups);
+
*ngroups = 0;
/* There's some way to do this in Hesiod. */
return (-1);
@@ -178,6 +189,8 @@ gr_list(struct irs_gr *this, const char *name,
static void
gr_minimize(struct irs_gr *this) {
+
+ UNUSED(this);
/* NOOP */
}
diff --git a/contrib/bind/lib/irs/dns_ho.c b/contrib/bind/lib/irs/dns_ho.c
index 8b2df77..e340f02 100644
--- a/contrib/bind/lib/irs/dns_ho.c
+++ b/contrib/bind/lib/irs/dns_ho.c
@@ -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 const char rcsid[] = "$Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp $";
+static const char rcsid[] = "$Id: dns_ho.c,v 1.33 2001/10/05 04:30:21 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -94,11 +94,7 @@ static const char rcsid[] = "$Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp
#define MAXALIASES 35
#define MAXADDRS 35
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
+#define MAXPACKET (1024*64)
#define BOUNDS_CHECK(ptr, count) \
if ((ptr) + (count) > eom) { \
@@ -106,6 +102,26 @@ static const char rcsid[] = "$Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp
continue; \
} else (void)0
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+struct dns_res_target {
+ struct dns_res_target *next;
+ querybuf qbuf; /* query buffer */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer buffer */
+ int qclass, qtype; /* class and type of query */
+ int action; /* condition whether query is really issued */
+ char qname[MAXDNAME +1]; /* domain name */
+#if 0
+ int n; /* result length */
+#endif
+};
+enum {RESTGT_DOALWAYS, RESTGT_AFTERFAILURE, RESTGT_IGNORE};
+enum {RESQRY_SUCCESS, RESQRY_FAIL};
+
struct pvt {
struct hostent host;
char * h_addr_ptrs[MAXADDRS + 1];
@@ -141,6 +157,8 @@ 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 addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
+ const struct addrinfo *pai);
static void map_v4v6_hostent(struct hostent *hp, char **bp,
int *len);
@@ -148,7 +166,20 @@ 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);
+ int af, int size,
+ struct addrinfo **ret_aip,
+ const struct addrinfo *pai);
+static int add_hostent(struct pvt *pvt, char *bp, char **hap,
+ struct addrinfo *ai);
+static const u_char * ar_head(const u_char *, int, const u_char *,
+ const u_char *, struct pvt *,
+ int (*)(const char *));
+static struct addrinfo * a6_expand(const u_char *, const u_char *, int,
+ const u_char *, const u_char *,
+ const struct in6_addr *, int,
+ const struct addrinfo *,
+ struct pvt *, int (*)(const char *), int *);
+static const char *dname_subst(const char *, const char *, const char *);
static int init(struct irs_ho *this);
/* Exports. */
@@ -158,6 +189,8 @@ irs_dns_ho(struct irs_acc *this) {
struct irs_ho *ho;
struct pvt *pvt;
+ UNUSED(this);
+
if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
@@ -180,6 +213,7 @@ irs_dns_ho(struct irs_acc *this) {
ho->minimize = ho_minimize;
ho->res_get = ho_res_get;
ho->res_set = ho_res_set;
+ ho->addrinfo = ho_addrinfo;
return (ho);
}
@@ -214,24 +248,50 @@ ho_byname(struct irs_ho *this, const char *name) {
}
static struct hostent *
-ho_byname2(struct irs_ho *this, const char *name, int af) {
+ho_byname2(struct irs_ho *this, const char *name, int af)
+{
struct pvt *pvt = (struct pvt *)this->private;
- int n, size, type;
- u_char buf[MAXPACKET];
+ struct hostent *hp = NULL;
+ int n, size;
char tmp[NS_MAXDNAME];
const char *cp;
+ struct addrinfo ai;
+ struct dns_res_target q, q2, *p;
+ int querystate = RESQRY_FAIL;
if (init(this) == -1)
return (NULL);
+ memset(&q, 0, sizeof(q2));
+ memset(&q2, 0, sizeof(q2));
+
switch (af) {
case AF_INET:
size = INADDRSZ;
- type = T_A;
+ q.qclass = C_IN;
+ q.qtype = T_A;
+ q.answer = q.qbuf.buf;
+ q.anslen = sizeof(q.qbuf);
+ q.action = RESTGT_DOALWAYS;
break;
case AF_INET6:
size = IN6ADDRSZ;
- type = T_AAAA;
+ q.qclass = C_IN;
+ q.qtype = ns_t_a6;
+ q.answer = q.qbuf.buf;
+ q.anslen = sizeof(q.qbuf);
+ q.next = &q2;
+#ifdef RES_USE_A6
+ if ((pvt->res->options & RES_USE_A6) == 0)
+ q.action = RESTGT_IGNORE;
+ else
+#endif
+ q.action = RESTGT_DOALWAYS;
+ q2.qclass = C_IN;
+ q2.qtype = T_AAAA;
+ q2.answer = q2.qbuf.buf;
+ q2.anslen = sizeof(q2.qbuf);
+ q2.action = RESTGT_AFTERFAILURE;
break;
default:
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
@@ -248,30 +308,62 @@ ho_byname2(struct irs_ho *this, const char *name, int af) {
tmp, sizeof tmp)))
name = cp;
- 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));
+ for (p = &q; p; p = p->next) {
+ switch(p->action) {
+ case RESTGT_DOALWAYS:
+ break;
+ case RESTGT_AFTERFAILURE:
+ if (querystate == RESQRY_SUCCESS)
+ continue;
+ break;
+ case RESTGT_IGNORE:
+ continue;
+ }
+
+ if ((n = res_nsearch(pvt->res, name, p->qclass, p->qtype,
+ p->answer, p->anslen)) < 0) {
+ querystate = RESQRY_FAIL;
+ continue;
+ }
+
+ memset(&ai, 0, sizeof(ai));
+ ai.ai_family = af;
+ if ((hp = gethostans(this, p->answer, n, name, p->qtype,
+ af, size, NULL,
+ (const struct addrinfo *)&ai)) != NULL)
+ return(hp); /* no more loop is necessary */
+
+ querystate = RESQRY_FAIL;
+ continue;
+ }
+
+ return(hp); /* should be NULL */
}
static struct hostent *
-ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
+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;
- char qbuf[MAXDNAME+1], *qp;
- u_char buf[MAXPACKET];
+ char *qp;
struct hostent *hp;
+ struct addrinfo ai;
+ struct dns_res_target q, q2, *p;
int n, size;
+ int querystate = RESQRY_FAIL;
if (init(this) == -1)
return (NULL);
+ memset(&q, 0, sizeof(q2));
+ memset(&q2, 0, sizeof(q2));
+
if (af == AF_INET6 && len == IN6ADDRSZ &&
(!memcmp(uaddr, mapped, sizeof mapped) ||
(!memcmp(uaddr, tunnelled, sizeof tunnelled) &&
memcmp(&uaddr[sizeof tunnelled], v6local, sizeof(v6local))))) {
/* Unmap. */
- addr = (char *)addr + sizeof mapped;
+ addr = (const char *)addr + sizeof mapped;
uaddr += sizeof mapped;
af = AF_INET;
len = INADDRSZ;
@@ -279,9 +371,31 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
switch (af) {
case AF_INET:
size = INADDRSZ;
+ q.qclass = C_IN;
+ q.qtype = T_PTR;
+ q.answer = q.qbuf.buf;
+ q.anslen = sizeof(q.qbuf);
+ q.action = RESTGT_DOALWAYS;
break;
case AF_INET6:
size = IN6ADDRSZ;
+ q.qclass = C_IN;
+ q.qtype = T_PTR;
+ q.answer = q.qbuf.buf;
+ q.anslen = sizeof(q.qbuf);
+ q.next = &q2;
+ if ((pvt->res->options & RES_NO_BITSTRING) != 0)
+ q.action = RESTGT_IGNORE;
+ else
+ q.action = RESTGT_DOALWAYS;
+ q2.qclass = C_IN;
+ q2.qtype = T_PTR;
+ q2.answer = q2.qbuf.buf;
+ q2.anslen = sizeof(q2.qbuf);
+ if ((pvt->res->options & RES_NO_NIBBLE) != 0)
+ q2.action = RESTGT_IGNORE;
+ else
+ q2.action = RESTGT_AFTERFAILURE;
break;
default:
errno = EAFNOSUPPORT;
@@ -295,49 +409,93 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
}
switch (af) {
case AF_INET:
- (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+ qp = q.qname;
+ (void) sprintf(qp, "%u.%u.%u.%u.in-addr.arpa",
(uaddr[3] & 0xff),
(uaddr[2] & 0xff),
(uaddr[1] & 0xff),
(uaddr[0] & 0xff));
break;
case AF_INET6:
- qp = qbuf;
- for (n = IN6ADDRSZ - 1; n >= 0; n--) {
- qp += SPRINTF((qp, "%x.%x.",
- uaddr[n] & 0xf,
- (uaddr[n] >> 4) & 0xf));
+ if (q.action != RESTGT_IGNORE) {
+ qp = q.qname;
+ qp += SPRINTF((qp, "\\[x"));
+ for (n = 0; n < IN6ADDRSZ; n++)
+ qp += SPRINTF((qp, "%02x", uaddr[n]));
+ SPRINTF((qp, "/128].%s",
+ res_get_bitstringsuffix(pvt->res)));
+ }
+ if (q2.action != RESTGT_IGNORE) {
+ qp = q2.qname;
+ for (n = IN6ADDRSZ - 1; n >= 0; n--) {
+ qp += SPRINTF((qp, "%x.%x.",
+ uaddr[n] & 0xf,
+ (uaddr[n] >> 4) & 0xf));
+ }
+ strcpy(qp, res_get_nibblesuffix(pvt->res));
}
- strcpy(qp, "ip6.int");
break;
default:
abort();
}
- 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() */
- 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 && (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;
- }
- RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
- return (hp);
+
+ for (p = &q; p; p = p->next) {
+ switch(p->action) {
+ case RESTGT_DOALWAYS:
+ break;
+ case RESTGT_AFTERFAILURE:
+ if (querystate == RESQRY_SUCCESS)
+ continue;
+ break;
+ case RESTGT_IGNORE:
+ continue;
+ }
+
+ if ((n = res_nquery(pvt->res, p->qname, p->qclass, p->qtype,
+ p->answer, p->anslen)) < 0) {
+ querystate = RESQRY_FAIL;
+ continue;
+ }
+
+ memset(&ai, 0, sizeof(ai));
+ ai.ai_family = af;
+ hp = gethostans(this, p->answer, n, p->qname, T_PTR, af, size,
+ NULL, (const struct addrinfo *)&ai);
+ if (!hp) {
+ querystate = RESQRY_FAIL;
+ continue;
+ }
+
+ 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 && (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;
+ }
+
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
+ return (hp); /* no more loop is necessary. */
+ }
+
+ return(NULL); /* H_ERRNO was set by subroutines */
}
static struct hostent *
ho_next(struct irs_ho *this) {
+
+ UNUSED(this);
+
return (NULL);
}
static void
ho_rewind(struct irs_ho *this) {
+
+ UNUSED(this);
+
/* NOOP */
}
@@ -367,6 +525,495 @@ ho_res_get(struct irs_ho *this) {
return (pvt->res);
}
+/* XXX */
+extern struct addrinfo *addr2addrinfo __P((const struct addrinfo *,
+ const char *));
+
+static struct addrinfo *
+ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
+{
+ struct pvt *pvt = (struct pvt *)this->private;
+ int n;
+ char tmp[NS_MAXDNAME];
+ const char *cp;
+ struct dns_res_target q, q2, q3, *p;
+ struct addrinfo sentinel, *cur;
+ int querystate = RESQRY_FAIL;
+
+ if (init(this) == -1)
+ return (NULL);
+
+ memset(&q, 0, sizeof(q2));
+ memset(&q2, 0, sizeof(q2));
+ memset(&q3, 0, sizeof(q3));
+ memset(&sentinel, 0, sizeof(sentinel));
+ cur = &sentinel;
+
+ switch (pai->ai_family) {
+ case AF_UNSPEC:
+ /* prefer IPv6 */
+ q.qclass = C_IN;
+ q.qtype = ns_t_a6;
+ q.answer = q.qbuf.buf;
+ q.anslen = sizeof(q.qbuf);
+ q.next = &q2;
+#ifdef RES_USE_A6
+ if ((pvt->res->options & RES_USE_A6) == 0)
+ q.action = RESTGT_IGNORE;
+ else
+#endif
+ q.action = RESTGT_DOALWAYS;
+ q2.qclass = C_IN;
+ q2.qtype = T_AAAA;
+ q2.answer = q2.qbuf.buf;
+ q2.anslen = sizeof(q2.qbuf);
+ q2.next = &q3;
+ /* try AAAA only when A6 query fails */
+ q2.action = RESTGT_AFTERFAILURE;
+ q3.qclass = C_IN;
+ q3.qtype = T_A;
+ q3.answer = q3.qbuf.buf;
+ q3.anslen = sizeof(q3.qbuf);
+ q3.action = RESTGT_DOALWAYS;
+ break;
+ case AF_INET:
+ q.qclass = C_IN;
+ q.qtype = T_A;
+ q.answer = q.qbuf.buf;
+ q.anslen = sizeof(q.qbuf);
+ q.action = RESTGT_DOALWAYS;
+ break;
+ case AF_INET6:
+ q.qclass = C_IN;
+ q.qtype = ns_t_a6;
+ q.answer = q.qbuf.buf;
+ q.anslen = sizeof(q.qbuf);
+ q.next = &q2;
+#ifdef RES_USE_A6
+ if ((pvt->res->options & RES_USE_A6) == 0)
+ q.action = RESTGT_IGNORE;
+ else
+#endif
+ q.action = RESTGT_DOALWAYS;
+ q2.qclass = C_IN;
+ q2.qtype = T_AAAA;
+ q2.answer = q2.qbuf.buf;
+ q2.anslen = sizeof(q2.qbuf);
+ q2.action = RESTGT_AFTERFAILURE;
+ break;
+ default:
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* better error? */
+ return(NULL);
+ }
+
+ /*
+ * if there aren't any dots, it could be a user-level alias.
+ * this is also done in res_nquery() since we are not the only
+ * function that looks up host names.
+ */
+ if (!strchr(name, '.') && (cp = res_hostalias(pvt->res, name,
+ tmp, sizeof tmp)))
+ name = cp;
+
+ for (p = &q; p; p = p->next) {
+ struct addrinfo *ai;
+
+ switch(p->action) {
+ case RESTGT_DOALWAYS:
+ break;
+ case RESTGT_AFTERFAILURE:
+ if (querystate == RESQRY_SUCCESS)
+ continue;
+ break;
+ case RESTGT_IGNORE:
+ continue;
+ }
+
+ if ((n = res_nsearch(pvt->res, name, p->qclass, p->qtype,
+ p->answer, p->anslen)) < 0) {
+ querystate = RESQRY_FAIL;
+ continue;
+ }
+ (void)gethostans(this, p->answer, n, name, p->qtype,
+ pai->ai_family, /* XXX: meaningless */
+ 0, &ai, pai);
+ if (ai) {
+ querystate = RESQRY_SUCCESS;
+ cur->ai_next = ai;
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ }
+ else
+ querystate = RESQRY_FAIL;
+ }
+
+ return(sentinel.ai_next);
+}
+
+static const u_char *
+ar_head(cp, count, msg, eom, pvt, name_ok)
+ const u_char *cp, *msg, *eom;
+ int count;
+ struct pvt *pvt;
+ int (*name_ok)(const char *);
+{
+ int n;
+ char buf[1024]; /* XXX */
+
+ while (count-- > 0 && cp < eom) {
+ n = dn_expand(msg, eom, cp, buf, sizeof(buf));
+ if (n < 0 || !maybe_ok(pvt->res, buf, name_ok))
+ goto end;
+ cp += n; /* name */
+ if (cp + 3 * INT16SZ + INT32SZ >= eom)
+ goto end;
+ cp += INT16SZ; /* type */
+ cp += INT16SZ + INT32SZ; /* class, TTL */
+ n = ns_get16(cp);
+ cp += n + INT16SZ; /* len */
+ }
+ return(cp);
+
+ end:
+ return(eom); /* XXX */
+}
+
+/* XXX: too many arguments */
+static struct addrinfo *
+a6_expand(const u_char *ansbuf, const u_char *a6p,
+ int a6len, const u_char *arp, const u_char *eom,
+ const struct in6_addr *in6, int plen, const struct addrinfo *pai,
+ struct pvt *pvt, int (*name_ok)(const char *), int *errorp)
+{
+ struct in6_addr a;
+ int n, pbyte, plen1, pbyte1, error = 0;
+ const u_char *cp;
+ struct addrinfo sentinel, *cur;
+ char pname[1024], buf[1024]; /* XXX */
+
+ *errorp = NETDB_SUCCESS;
+ memset(&sentinel, 0, sizeof(sentinel));
+ cur = &sentinel;
+
+ /*
+ * Validate A6 parameters.
+ */
+ if (a6len == 0) { /* an A6 record must contain at least 1 byte. */
+ error = NO_RECOVERY;
+ goto bad;
+ }
+ /* prefix length check. */
+ if ((plen1 = *a6p) > 128) {
+ error = NO_RECOVERY;
+ goto bad;
+ }
+ if (plen1 > plen) {
+ /*
+ * New length must not be greater than old one.
+ * Ignore the record as specified in RFC 2874
+ * Section 3.1.2.
+ */
+ return(NULL); /* just ignore. */
+ }
+ /* boundary check for new plen and prefix addr */
+ pbyte1 = (plen1 & ~7) / 8;
+ if ((int)sizeof(struct in6_addr) - pbyte1 > a6len - 1) {
+ error = NO_RECOVERY;
+ goto bad;
+ }
+
+ /*
+ * merge the new prefix portion.
+ * <--- plen(bits) --->
+ * <--- pbyte ---><-b->
+ * 000000000000000pppppxxxxxxxxxxx(= in6, 0: unknown, x: known, p: pad)
+ * PP++++++++(+ should be merged. P: padding, must be 0)
+ * <-- plen1-->
+ * <-pbyte1->
+ * ^a6p+1
+ * The result should be:
+ * 0000000000PP++++++++xxxxxxxxxxx(= a)
+ */
+ pbyte = (plen & ~7) / 8;
+ a = *in6;
+ if (pbyte > pbyte1) {
+ /* N.B. the case of "pbyte1 == 128" is implicitly excluded. */
+ int b = plen % 8; /* = the length of "pp..." above */
+ u_char c_hi, c_lo;
+
+ memcpy(&a.s6_addr[pbyte1], a6p + 1, pbyte - pbyte1);
+ if (b > 0) {
+ c_hi = a6p[pbyte - pbyte1 + 1];
+ c_lo = in6->s6_addr[pbyte];
+ a.s6_addr[pbyte] =
+ (c_hi & (0xff << (8 - b))) |
+ ((0x00ff >> b) & c_lo);
+ }
+ }
+
+#if 0 /* for debug */
+ if ((pvt->res->options & RES_DEBUG) != 0) {
+ u_char ntopbuf[INET6_ADDRSTRLEN];
+
+ inet_ntop(AF_INET6, &a, ntopbuf, sizeof(ntopbuf));
+ printf("a6_expand: %s\\%d\n", ntopbuf, plen1);
+ }
+#endif
+
+ if (plen1 == 0) {
+ /* Here is the end of A6 chain. make addrinfo, then return. */
+ return(addr2addrinfo(pai, (const char *)&a));
+ }
+
+ /*
+ * Expand the new prefix name. Since the prefix name must not be
+ * compressed (RFC 2874 Section 3.1.1), we could use ns_name_ntop()
+ * here if it had a stricter boundary check.
+ */
+ cp = a6p + 1 + (sizeof(*in6) - pbyte1);
+ n = dn_expand(ansbuf, eom, cp, pname, sizeof(pname));
+ if (n < 0 || !maybe_ok(pvt->res, pname, name_ok)) {
+ error = NO_RECOVERY;
+ goto bad;
+ }
+ if (cp + n != a6p + a6len) { /* length mismatch */
+ error = NO_RECOVERY;
+ goto bad;
+ }
+
+ /*
+ * we need (more) additional section records, but no one is
+ * available, which possibly means a malformed answer.
+ */
+ if (arp == NULL) {
+ error = NO_RECOVERY; /* we can't resolve the chain. */
+ goto bad;
+ }
+
+ /*
+ * Loop thru the rest of the buffer, searching for the next A6 record
+ * that has the same owner name as the prefix name. If found, then
+ * recursively call this function to expand the whole A6 chain.
+ */
+ plen = plen1;
+ for (cp = arp; cp != NULL && cp < eom; cp += n) {
+ int class, type;
+
+ n = dn_expand(ansbuf, eom, cp, buf, sizeof(buf));
+ if (n < 0 || !maybe_ok(pvt->res, buf, name_ok)) {
+ error = NO_RECOVERY;
+ goto bad;
+ }
+ cp += n; /* name */
+ if (cp + 3 * INT16SZ + INT32SZ > eom) {
+ error = NO_RECOVERY;
+ goto bad;
+ }
+ type = ns_get16(cp);
+ cp += INT16SZ; /* type */
+ class = ns_get16(cp);
+ cp += INT16SZ + INT32SZ; /* class, TTL */
+ n = ns_get16(cp);
+ cp += INT16SZ; /* len */
+ if (cp + n > eom) {
+ error = NO_RECOVERY;
+ goto bad;
+ }
+ if (class != C_IN || type != ns_t_a6) {
+ /* we are only interested in A6 records. skip others */
+ continue;
+ }
+
+ if (ns_samename(buf, pname) != 1) {
+ continue;
+ }
+
+ /* Proceed to the next record in the chain. */
+ cur->ai_next = a6_expand(ansbuf, cp, n, cp + n, eom,
+ (const struct in6_addr *)&a,
+ plen, pai, pvt, name_ok, &error);
+ if (error != NETDB_SUCCESS)
+ goto bad;
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ }
+
+ return(sentinel.ai_next);
+
+ bad:
+ *errorp = error;
+ if (sentinel.ai_next)
+ freeaddrinfo(sentinel.ai_next);
+ return(NULL);
+}
+
+static const char *
+dname_subst(const char *qname0, const char *owner0, const char *target) {
+ char owner[MAXDNAME];
+ static char qname[MAXDNAME];
+ const char blabelhead[] = "\\[x"; /* we can assume hex strings */
+ int qlen, olen;
+ int bufsiz = sizeof(qname);
+
+ /* make local copies, which are canonicalized. */
+ if (ns_makecanon(qname0, qname, sizeof(qname)) < 0 ||
+ ns_makecanon(owner0, owner, sizeof(owner)) < 0)
+ return(NULL);
+ qlen = strlen(qname);
+ olen = strlen(owner);
+ /* from now on, do not refer to qname0 nor owner0. */
+
+ /*
+ * check if QNAME is a subdomain of OWNER.
+ * XXX: currently, we only handle the following two cases:
+ * (A) none of the labels are bitlabels, or
+ * (B) both of the head labels are bitlabels (and the following
+ * labels are NOT bitlabels).
+ * If we pass the check, then subtract the remaining part from QNAME.
+ * ex. (A) qname=www.foo.com,owner=foo.com => new qname=www.
+ * (B) qname=\[x3ffe0501/32].foo.com,owner=\[x3ffe/16].foo.com
+ * => new qname=\[x0501/16].
+ */
+ if (ns_samedomain(qname, owner)) { /* check (A) */
+ /* at this point, qlen must not be smaller than olen */
+ qname[qlen - olen] = 0;
+ bufsiz -= (qlen - olen);
+ } else { /* check (B) */
+ char *parent0, *parent1;
+ /* the following 3 have enough size to store 1 bitlabel */
+ u_char qlabel[64], olabel[64], newlabel[64];
+ int qlabellen, olabellen;
+
+ if (strncmp(qname, blabelhead, 3) != 0 ||
+ strncmp(owner, blabelhead, 3) != 0)
+ return(NULL);
+ /*
+ * Both two begin with bitlabels. The succeeding parts
+ * must exact match.
+ */
+ if ((parent0 = strchr(qname, '.')) == NULL ||
+ (parent1 = strchr(owner, '.')) == NULL)
+ return(NULL);
+
+ /* ns_samename allows names to begin with '.' */
+ if (ns_samename(parent0, parent1) != 1)
+ return(NULL);
+
+ /* cut the upper domain parts off. */
+ *(parent0 + 1) = 0;
+ *(parent1 + 1) = 0;
+ /* convert the textual form into binary one. */
+ if (ns_name_pton(qname, qlabel, sizeof(qlabel)) < 0 ||
+ ns_name_pton(owner, olabel, sizeof(olabel)) < 0)
+ return(NULL);
+ if ((qlabellen = *(qlabel + 1)) == 0)
+ qlabellen = 256;
+ if ((olabellen = *(olabel + 1)) == 0)
+ olabellen = 256;
+ if (olabellen > qlabellen)
+ return(NULL); /* owner does not contain qname. */
+ else {
+ int qplen = (qlabellen + 7) / 8;
+ int oplen = (olabellen + 7) / 8;
+ int sft = olabellen % 8;
+ int nllen, n;
+ u_char *qp, *op, *np;
+
+ /* skip ELT and Count. */
+ qp = qlabel + 2;
+ op = olabel + 2;
+
+ /* check if olabel is a "subdomain" of qlabel. */
+ if (memcmp(qp, op, oplen - 1) != 0)
+ return(NULL);
+ if (sft > 0) {
+ /* compare trailing bits (between 1 and 7) */
+ if ((qp[qplen - 1] & (0xff << sft)) !=
+ op[qplen - 1])
+ return(NULL);
+ }
+
+ /* OK, get remaining bits from qlabel. */
+ np = newlabel;
+ if (olabellen == qlabellen) {
+ /*
+ * Two names (including bitlabels) are exactly
+ * same. Discard the whole names.
+ * XXX: ns_samename() above should exclude
+ * this case...
+ */
+ qname[0] = 0;
+ goto maketarget;
+ }
+ *np++ = 0x41; /* XXX hardcoding */
+ *np++ = nllen = (qlabellen - olabellen);
+ if (sft == 0) {
+ /*
+ * No alignment issue. can just use memcpy.
+ * Note that the "else" part below contains
+ * this case. We separate the two cases just
+ * for efficiency.
+ * We assume that ns_name_pton above ensures
+ * QP does not contain trailing garbages.
+ */
+ memcpy(np, qp + oplen, qplen - oplen);
+ np += qplen - oplen;
+ *np = 0;
+ } else {
+ /*
+ * copy the lower (8-SFT) bits of QP to the
+ * upper (8-SFT) bits of NP, then copy the
+ * upper SFT bits of QP+1 to the lower SFT bits
+ * of NP, and so on...
+ * if QP is xxxyyyyy zzzwww..., then
+ * NP would be yyyyyzzz ...
+ * Again, we assume QP does not contain
+ * trailing garbages.
+ */
+ qp += (oplen - 1);
+ while (nllen > 0) {
+ *np = (*qp << sft) & 0xff;
+ if ((nllen -= (8 - sft)) <= 0)
+ break; /* done */
+ qp++;
+ *np |= ((*qp >> sft) & 0xff);
+ np++;
+ nllen -= sft;
+ }
+ *++np = 0;
+ }
+
+ /*
+ * make a new bitlabel with the remaining bits.
+ * Note that there's no buffer boundary issue, since
+ * qlabel, olabel, and newlabel all have the same size.
+ * ns_name_ntop() must not return 0, since we have
+ * a non-empty bitlabel.
+ */
+ if ((n = ns_name_ntop(newlabel, qname, sizeof(qname)))
+ <= 0)
+ return(NULL);
+ bufsiz -= n;
+ if (qname[n - 1] != '.') { /* XXX no trailing dot */
+ qname[n - 1] = '.';
+ qname[n] = 0;
+ bufsiz--;
+ }
+
+ }
+ }
+
+ maketarget:
+ /*
+ * Finally, append the remaining part (maybe empty) to the new target.
+ */
+ if (bufsiz < (int)strlen(target)) /* bufsiz takes care of the \0. */
+ return(NULL);
+ strcat(qname, target);
+
+ return((const char *)qname);
+}
+
static void
ho_res_set(struct irs_ho *this, struct __res_state *res,
void (*free_res)(void *)) {
@@ -386,23 +1033,37 @@ ho_res_set(struct irs_ho *this, struct __res_state *res,
static struct hostent *
gethostans(struct irs_ho *this,
const u_char *ansbuf, int anslen, const char *qname, int qtype,
- int af, int size)
+ int af, int size, /* meaningless for addrinfo cases */
+ struct addrinfo **ret_aip, const struct addrinfo *pai)
{
struct pvt *pvt = (struct pvt *)this->private;
int type, class, buflen, ancount, qdcount, n, haveanswer, had_error;
+ int error = NETDB_SUCCESS, arcount;
int (*name_ok)(const char *);
const HEADER *hp;
const u_char *eom;
+ const u_char *eor;
const u_char *cp;
- const char *tname, **tap;
+ const char *tname;
+ const char *hname;
char *bp, **ap, **hap;
char tbuf[MAXDNAME+1];
+ struct addrinfo sentinel, *cur, ai;
+ const u_char *arp = NULL;
+
+ if (pai == NULL) abort();
+ if (ret_aip != NULL)
+ *ret_aip = NULL;
+ memset(&sentinel, 0, sizeof(sentinel));
+ cur = &sentinel;
tname = qname;
eom = ansbuf + anslen;
switch (qtype) {
+ case ns_t_a6:
case T_A:
case T_AAAA:
+ case T_ANY: /* use T_ANY only for T_A/T_AAAA lookup */
name_ok = res_hnok;
break;
case T_PTR:
@@ -414,7 +1075,7 @@ gethostans(struct irs_ho *this,
pvt->host.h_addrtype = af;
pvt->host.h_length = size;
- pvt->host.h_name = NULL;
+ hname = pvt->host.h_name = NULL;
/*
* Find first satisfactory answer.
@@ -423,9 +1084,10 @@ gethostans(struct irs_ho *this,
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
- hp = (HEADER *)ansbuf;
+ hp = (const HEADER *)ansbuf;
ancount = ntohs(hp->ancount);
qdcount = ntohs(hp->qdcount);
+ arcount = ntohs(hp->arcount);
bp = pvt->hostbuf;
buflen = sizeof pvt->hostbuf;
cp = ansbuf + HFIXEDSZ;
@@ -443,7 +1105,8 @@ gethostans(struct irs_ho *this,
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
- if (qtype == T_A || qtype == T_AAAA) {
+ if (qtype == T_A || qtype == T_AAAA ||
+ qtype == ns_t_a6 || qtype == T_ANY) {
/* 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).
@@ -454,9 +1117,10 @@ gethostans(struct irs_ho *this,
return (NULL);
}
pvt->host.h_name = bp;
+ hname = bp;
bp += n;
buflen -= n;
- /* The qname can be abbreviated, but h_name is now absolute. */
+ /* The qname can be abbreviated, but hname is now absolute. */
qname = pvt->host.h_name;
}
ap = pvt->host_aliases;
@@ -486,10 +1150,12 @@ gethostans(struct irs_ho *this,
cp += n;
continue;
}
- if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
+ eor = cp + n;
+ if ((qtype == T_A || qtype == T_AAAA || qtype == ns_t_a6 ||
+ qtype == T_ANY) && type == T_CNAME) {
if (ap >= &pvt->host_aliases[MAXALIASES-1])
continue;
- n = dn_expand(ansbuf, eom, cp, tbuf, sizeof tbuf);
+ n = dn_expand(ansbuf, eor, cp, tbuf, sizeof tbuf);
if (n < 0 || !maybe_ok(pvt->res, tbuf, name_ok)) {
had_error++;
continue;
@@ -508,17 +1174,78 @@ gethostans(struct irs_ho *this,
}
strcpy(bp, tbuf);
pvt->host.h_name = bp;
+ hname = bp;
bp += n;
buflen -= n;
continue;
}
+ if (type == ns_t_dname) {
+ const char *t0, *t;
+
+ /*
+ * just replace the query target; do not update the
+ * alias list. (Or should we?)
+ */
+ t0 = (qtype == T_PTR) ? tname : hname;
+
+ n = dn_expand(ansbuf, eor, cp, tbuf, sizeof(tbuf));
+ if (n < 0 || !maybe_dnok(pvt->res, tbuf)) {
+ had_error++;
+ continue;
+ }
+#ifdef RES_USE_DNAME
+ if ((pvt ->res->options & RES_USE_DNAME) == 0) {
+ cp += n;
+ continue;
+ }
+#endif
+ if ((t = dname_subst(t0, bp, tbuf)) == NULL) {
+ cp += n;
+ continue;
+ }
+#if 0 /* for debug */
+ if ((pvt->res->options & RES_DEBUG) != 0) {
+ printf("DNAME owner=%s, target=%s, next=%s\n",
+ bp, tbuf, t);
+ }
+#endif
+ cp += n;
+
+ n = strlen(t) + 1; /* for the \0 */
+ if (n > buflen) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, t);
+ if (qtype == T_PTR)
+ tname = bp;
+ else
+ hname = bp;
+ bp += n;
+ buflen -= n;
+
+ continue;
+ }
if (qtype == T_PTR && type == T_CNAME) {
- n = dn_expand(ansbuf, eom, cp, tbuf, sizeof tbuf);
+ n = dn_expand(ansbuf, eor, cp, tbuf, sizeof tbuf);
if (n < 0 || !maybe_dnok(pvt->res, tbuf)) {
had_error++;
continue;
}
cp += n;
+#ifdef RES_USE_DNAME
+ if ((pvt->res->options & RES_USE_DNAME) != 0)
+#endif
+ {
+ /*
+ * We may be able to check this regardless
+ * of the USE_DNAME bit, but we add the check
+ * for now since the DNAME support is
+ * experimental.
+ */
+ if (ns_samename(tname, bp) != 1)
+ continue;
+ }
/* Get canonical name. */
n = strlen(tbuf) + 1; /* for the \0 */
if (n > buflen) {
@@ -531,25 +1258,38 @@ gethostans(struct irs_ho *this,
buflen -= n;
continue;
}
- if (type != qtype) {
+ if (qtype == T_ANY) {
+ if (!(type == T_A || type == T_AAAA ||
+ type == ns_t_a6)) {
+ cp += n;
+ continue;
+ }
+ } else if (type != qtype) {
cp += n;
continue;
}
switch (type) {
case T_PTR:
+ if (ret_aip != NULL) {
+ /* addrinfo never needs T_PTR */
+ cp += n;
+ continue;
+ }
if (ns_samename(tname, bp) != 1) {
cp += n;
continue;
}
- n = dn_expand(ansbuf, eom, cp, bp, buflen);
+ n = dn_expand(ansbuf, eor, cp, bp, buflen);
if (n < 0 || !maybe_hnok(pvt->res, bp) ||
n >= MAXHOSTNAMELEN) {
had_error++;
break;
}
cp += n;
- if (!haveanswer)
+ if (!haveanswer) {
pvt->host.h_name = bp;
+ hname = bp;
+ }
else if (ap < &pvt->host_aliases[MAXALIASES-1])
*ap++ = bp;
else
@@ -560,16 +1300,91 @@ gethostans(struct irs_ho *this,
buflen -= n;
}
break;
+ case ns_t_a6: {
+ struct in6_addr in6;
+ struct addrinfo ai;
+
+#ifdef RES_USE_A6
+ if ((pvt->res->options & RES_USE_A6) == 0) {
+ cp += n;
+ continue;
+ }
+#endif
+
+ if (ns_samename(hname, bp) != 1) {
+ cp += n;
+ continue;
+ }
+
+ /*
+ * search for the top of the additional section.
+ * once found, keep it for the case where we have
+ * more than one A6 record.
+ * XXX: however, we may not need this part.
+ */
+ if (arp == NULL && arcount > 0) {
+ int nscount = ntohs(hp->nscount);
+
+ arp = ar_head(cp + n, nscount + ancount - 1,
+ ansbuf, eom, pvt, name_ok);
+ }
+
+ /* recursively collect the whole A6 chain */
+ ai = *pai; /* XXX: we can't override constant pai */
+ ai.ai_family = AF_INET6;
+ memset(&in6, 0, sizeof(in6)); /* just for safety */
+ cur->ai_next = a6_expand(ansbuf, cp, n, arp, eom,
+ &in6, 128,
+ (const struct addrinfo *)&ai,
+ pvt, name_ok, &error);
+ if (error != NETDB_SUCCESS) {
+#ifdef DEBUG
+ /* in this case, cur->ai_next must be NULL. */
+ if (cur->ai_next != NULL)
+ abort();
+#endif
+ had_error++;
+ continue;
+ }
+
+ /*
+ * We don't bother even if cur->ai_next is NULL unless
+ * the expansion failed by a fatal error. The list
+ * can be NULL if the given A6 is incomplete, but we
+ * may have another complete A6 chain in this answer.
+ * See the last paragraph of RFC 2874 Section 3.1.4.
+ */
+ if (cur->ai_next == NULL) {
+ cp += n;
+ continue; /* no error, no answer */
+ }
+ goto convertinfo;
+ } /* FALLTHROUGH */
case T_A:
case T_AAAA:
- if (ns_samename(pvt->host.h_name, bp) != 1) {
+ if (ns_samename(hname, bp) != 1) {
+ cp += n;
+ continue;
+ }
+ if (type == T_A && n != INADDRSZ) {
cp += n;
continue;
}
- if (n != pvt->host.h_length) {
+ if (type == T_AAAA && n != IN6ADDRSZ) {
cp += n;
continue;
}
+
+ /* make addrinfo. don't overwrite constant PAI */
+ ai = *pai;
+ ai.ai_family = (type == T_AAAA) ? AF_INET6 : AF_INET;
+ cur->ai_next = addr2addrinfo(
+ (const struct addrinfo *)&ai,
+ (const char *)cp);
+ if (cur->ai_next == NULL)
+ had_error++;
+
+ convertinfo: /* convert addrinfo into hostent form */
if (!haveanswer) {
int nn;
@@ -580,34 +1395,44 @@ gethostans(struct irs_ho *this,
continue;
}
pvt->host.h_name = bp;
+ hname = bp;
bp += nn;
buflen -= nn;
}
/* Ensure alignment. */
- bp += sizeof(align) - ((u_long)bp % sizeof(align));
+ bp = (char *)(((u_long)bp + (sizeof(align) - 1)) &
+ ~(sizeof(align) - 1));
/* Avoid overflows. */
if (bp + n >= &pvt->hostbuf[sizeof pvt->hostbuf]) {
had_error++;
continue;
}
- if (hap >= &pvt->h_addr_ptrs[MAXADDRS-1]) {
- cp += n;
- continue;
- }
- /* Suppress duplicates. */
- for (tap = (const char **)pvt->h_addr_ptrs;
- *tap != NULL;
- tap++)
- if (memcmp(*tap, cp, n) == 0)
- break;
- if (*tap != NULL) {
- cp += n;
- continue;
+ if (ret_aip) { /* need addrinfo. keep it. */
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ } else if (cur->ai_next) { /* need hostent */
+ struct addrinfo *aip = cur->ai_next;
+
+ for (aip = cur->ai_next; aip;
+ aip = aip->ai_next) {
+ int m;
+
+ m = add_hostent(pvt, bp, hap, aip);
+ if (m < 0) {
+ had_error++;
+ break;
+ }
+ if (m == 0)
+ continue;
+ if (hap < &pvt->h_addr_ptrs[MAXADDRS-1])
+ hap++;
+
+ bp += m;
+ }
+
+ freeaddrinfo(cur->ai_next);
+ cur->ai_next = NULL;
}
- /* Store address. */
- memcpy(*hap++ = bp, cp, n);
- *hap = NULL;
- bp += n;
cp += n;
break;
default:
@@ -617,27 +1442,94 @@ gethostans(struct irs_ho *this,
haveanswer++;
}
if (haveanswer) {
- *ap = NULL;
-
- 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)
- goto no_recovery;
- strcpy(bp, qname);
- pvt->host.h_name = bp;
- bp += n;
- buflen -= n;
+ if (ret_aip == NULL) {
+ *ap = NULL;
+ *hap = NULL;
+
+ if (pvt->res->nsort && haveanswer > 1 && qtype == T_A)
+ addrsort(pvt->res, pvt->h_addr_ptrs,
+ haveanswer);
+ if (pvt->host.h_name == NULL) {
+ n = strlen(qname) + 1; /* for the \0 */
+ if (n > buflen || n >= MAXHOSTNAMELEN)
+ goto no_recovery;
+ strcpy(bp, qname);
+ pvt->host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ }
+ if (pvt->res->options & RES_USE_INET6)
+ map_v4v6_hostent(&pvt->host, &bp, &buflen);
+ RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
+ return (&pvt->host);
+ } else {
+ if ((pai->ai_flags & AI_CANONNAME) != 0) {
+ if (pvt->host.h_name == NULL) {
+ sentinel.ai_next->ai_canonname =
+ strdup(qname);
+ }
+ else {
+ sentinel.ai_next->ai_canonname =
+ strdup(pvt->host.h_name);
+ }
+ }
+ *ret_aip = sentinel.ai_next;
+ return(NULL);
}
- if (pvt->res->options & RES_USE_INET6)
- map_v4v6_hostent(&pvt->host, &bp, &buflen);
- RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
- return (&pvt->host);
}
no_recovery:
- RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
- return (NULL);
+ if (sentinel.ai_next) {
+ /* this should be impossible, but check it for safety */
+ freeaddrinfo(sentinel.ai_next);
+ }
+ if (error == NETDB_SUCCESS)
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
+ else
+ RES_SET_H_ERRNO(pvt->res, error);
+ return(NULL);
+}
+
+static int
+add_hostent(struct pvt *pvt, char *bp, char **hap, struct addrinfo *ai)
+{
+ int addrlen;
+ char *addrp;
+ const char **tap;
+ char *obp = bp;
+
+ switch(ai->ai_addr->sa_family) {
+ case AF_INET6:
+ addrlen = IN6ADDRSZ;
+ addrp = (char *)&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
+ break;
+ case AF_INET:
+ addrlen = INADDRSZ;
+ addrp = (char *)&((struct sockaddr_in *)ai->ai_addr)->sin_addr;
+ break;
+ default:
+ return(-1); /* abort? */
+ }
+
+ /* Ensure alignment. */
+ bp = (char *)(((u_long)bp + (sizeof(align) - 1)) &
+ ~(sizeof(align) - 1));
+ /* Avoid overflows. */
+ if (bp + addrlen >= &pvt->hostbuf[sizeof pvt->hostbuf])
+ return(-1);
+ if (hap >= &pvt->h_addr_ptrs[MAXADDRS-1])
+ return(0); /* fail, but not treat it as an error. */
+
+ /* Suppress duplicates. */
+ for (tap = (const char **)pvt->h_addr_ptrs;
+ *tap != NULL;
+ tap++)
+ if (memcmp(*tap, addrp, addrlen) == 0)
+ break;
+ if (*tap != NULL)
+ return (0);
+
+ memcpy(*hap = bp, addrp, addrlen);
+ return((bp + addrlen) - obp);
}
static void
@@ -649,7 +1541,10 @@ map_v4v6_hostent(struct hostent *hp, char **bpp, int *lenp) {
hp->h_addrtype = AF_INET6;
hp->h_length = IN6ADDRSZ;
for (ap = hp->h_addr_list; *ap; ap++) {
- int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
+ int i = (u_long)*bpp % sizeof(align);
+
+ if (i != 0)
+ i = sizeof(align) - i;
if (*lenp < (i + IN6ADDRSZ)) {
/* Out of memory. Truncate address list here. */
diff --git a/contrib/bind/lib/irs/dns_nw.c b/contrib/bind/lib/irs/dns_nw.c
index 66ef664..8e0e965 100644
--- a/contrib/bind/lib/irs/dns_nw.c
+++ b/contrib/bind/lib/irs/dns_nw.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: dns_nw.c,v 1.19 1999/10/15 19:49:10 vixie Exp $";
+static const char rcsid[] = "$Id: dns_nw.c,v 1.21 2001/11/30 00:36:53 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -56,11 +56,7 @@ static const char rcsid[] = "$Id: dns_nw.c,v 1.19 1999/10/15 19:49:10 vixie Exp
#define MAXALIASES 35
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
+#define MAXPACKET (64*1024)
struct pvt {
struct nwent net;
@@ -109,6 +105,8 @@ irs_dns_nw(struct irs_acc *this) {
struct irs_nw *nw;
struct pvt *pvt;
+ UNUSED(this);
+
if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
@@ -185,11 +183,15 @@ nw_byaddr(struct irs_nw *this, void *net, int len, int af) {
static struct nwent *
nw_next(struct irs_nw *this) {
+
+ UNUSED(this);
+
return (NULL);
}
static void
nw_rewind(struct irs_nw *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -539,7 +541,7 @@ normalize_name(char *name) {
/* Make lower case. */
for (t = name; *t; t++)
- if (isascii(*t) && isupper(*t))
+ if (isascii((unsigned char)*t) && isupper((unsigned char)*t))
*t = tolower(*t);
/* Remove trailing dots. */
diff --git a/contrib/bind/lib/irs/dns_pr.c b/contrib/bind/lib/irs/dns_pr.c
index 77c6a93..64de35a 100644
--- a/contrib/bind/lib/irs/dns_pr.c
+++ b/contrib/bind/lib/irs/dns_pr.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: dns_pr.c,v 1.14 1999/09/04 22:06:14 vixie Exp $";
+static const char rcsid[] = "$Id: dns_pr.c,v 1.15 2001/05/29 05:48:31 marka Exp $";
#endif
/* Imports */
@@ -152,17 +152,20 @@ pr_bynumber(struct irs_pr *this, int num) {
static struct protoent *
pr_next(struct irs_pr *this) {
+ UNUSED(this);
errno = ENODEV;
return (NULL);
}
static void
pr_rewind(struct irs_pr *this) {
+ UNUSED(this);
/* NOOP */
}
static void
pr_minimize(struct irs_pr *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -201,7 +204,7 @@ parse_hes_list(struct irs_pr *this, char **hes_list) {
/* Skip blank lines. */
p = cp;
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
if (!*p)
continue;
@@ -213,14 +216,14 @@ parse_hes_list(struct irs_pr *this, char **hes_list) {
p = pvt->prbuf;
pvt->proto.p_name = p;
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
if (!*p)
continue;
*p++ = '\0';
pvt->proto.p_proto = atoi(p);
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
if (*p)
*p++ = '\0';
@@ -237,7 +240,7 @@ parse_hes_list(struct irs_pr *this, char **hes_list) {
pvt->proto.p_aliases = new;
}
pvt->proto.p_aliases[num++] = p;
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
if (*p)
*p++ = '\0';
diff --git a/contrib/bind/lib/irs/dns_pw.c b/contrib/bind/lib/irs/dns_pw.c
index 5344c6e..b3f7e05 100644
--- a/contrib/bind/lib/irs/dns_pw.c
+++ b/contrib/bind/lib/irs/dns_pw.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: dns_pw.c,v 1.18 1999/09/04 22:06:14 vixie Exp $";
+static const char rcsid[] = "$Id: dns_pw.c,v 1.19 2001/05/29 05:48:32 marka Exp $";
#endif
#include "port_before.h"
@@ -133,17 +133,20 @@ pw_byuid(struct irs_pw *this, uid_t uid) {
static struct passwd *
pw_next(struct irs_pw *this) {
+ UNUSED(this);
errno = ENODEV;
return (NULL);
}
static void
pw_rewind(struct irs_pw *this) {
+ UNUSED(this);
/* NOOP */
}
static void
pw_minimize(struct irs_pw *this) {
+ UNUSED(this);
/* NOOP */
}
diff --git a/contrib/bind/lib/irs/dns_sv.c b/contrib/bind/lib/irs/dns_sv.c
index e6cb2df..b3244a7 100644
--- a/contrib/bind/lib/irs/dns_sv.c
+++ b/contrib/bind/lib/irs/dns_sv.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: dns_sv.c,v 1.19 2000/03/30 22:53:56 vixie Exp $";
+static const char rcsid[] = "$Id: dns_sv.c,v 1.20 2001/05/29 05:48:33 marka Exp $";
#endif
/* Imports */
@@ -66,10 +66,12 @@ 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 *);
+#ifdef SV_RES_SETGET
static struct __res_state * sv_res_get(struct irs_sv *);
static void sv_res_set(struct irs_sv *,
struct __res_state *,
void (*)(void *));
+#endif
static struct servent * parse_hes_list(struct irs_sv *,
char **, const char *);
@@ -105,8 +107,13 @@ irs_dns_sv(struct irs_acc *this) {
sv->rewind = sv_rewind;
sv->close = sv_close;
sv->minimize = sv_minimize;
+#ifdef SV_RES_SETGET
+ sv->res_get = sv_res_get;
+ sv->res_set = sv_res_set;
+#else
sv->res_get = NULL; /* sv_res_get; */
sv->res_set = NULL; /* sv_res_set; */
+#endif
return (sv);
}
@@ -161,12 +168,14 @@ sv_byport(struct irs_sv *this, int port, const char *proto) {
static struct servent *
sv_next(struct irs_sv *this) {
+ UNUSED(this);
errno = ENODEV;
return (NULL);
}
static void
sv_rewind(struct irs_sv *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -189,7 +198,7 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) {
/* Check to make sure the protocol matches. */
p = cp;
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
if (!*p)
continue;
@@ -197,7 +206,7 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) {
proto_len = strlen(proto);
if (strncasecmp(++p, proto, proto_len) != 0)
continue;
- if (p[proto_len] && !isspace(p[proto_len]))
+ if (p[proto_len] && !isspace(p[proto_len]&0xff))
continue;
}
/* OK, we've got a live one. Let's parse it for real. */
@@ -207,21 +216,21 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) {
p = pvt->svbuf;
pvt->serv.s_name = p;
- while (*p && !isspace(*p))
+ while (*p && !isspace(*p&0xff))
p++;
if (!*p)
continue;
*p++ = '\0';
pvt->serv.s_proto = p;
- while (*p && !isspace(*p))
+ while (*p && !isspace(*p&0xff))
p++;
if (!*p)
continue;
*p++ = '\0';
pvt->serv.s_port = htons((u_short) atoi(p));
- while (*p && !isspace(*p))
+ while (*p && !isspace(*p&0xff))
p++;
if (*p)
*p++ = '\0';
@@ -238,7 +247,7 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) {
pvt->serv.s_aliases = new;
}
pvt->serv.s_aliases[num++] = p;
- while (*p && !isspace(*p))
+ while (*p && !isspace(*p&0xff))
p++;
if (*p)
*p++ = '\0';
@@ -265,9 +274,11 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) {
static void
sv_minimize(struct irs_sv *this) {
+ UNUSED(this);
/* NOOP */
}
+#ifdef SV_RES_SETGET
static struct __res_state *
sv_res_get(struct irs_sv *this) {
struct pvt *pvt = (struct pvt *)this->private;
@@ -284,3 +295,4 @@ sv_res_set(struct irs_sv *this, struct __res_state * res,
__hesiod_res_set(dns->hes_ctx, res, free_res);
}
+#endif
diff --git a/contrib/bind/lib/irs/gai_strerror.c b/contrib/bind/lib/irs/gai_strerror.c
index f56c6f5..c487e68 100644
--- a/contrib/bind/lib/irs/gai_strerror.c
+++ b/contrib/bind/lib/irs/gai_strerror.c
@@ -1,45 +1,86 @@
/*
-%%% 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>.
-
-*/
+ * Copyright (c) 2001 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.
+ */
#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";
- };
+#ifdef DO_PTHREADS
+#include <pthread.h>
+#include <stdlib.h>
+#endif
+
+static const char *gai_errlist[] = {
+ "no error",
+ "address family not supported for name",/* EAI_ADDRFAMILY */
+ "temporary failure", /* EAI_AGAIN */
+ "invalid flags", /* EAI_BADFLAGS */
+ "permanent failure", /* EAI_FAIL */
+ "address family not supported", /* EAI_FAMILY */
+ "memory failure", /* EAI_MEMORY */
+ "no address", /* EAI_NODATA */
+ "unknown name or service", /* EAI_NONAME */
+ "service not supported for socktype", /* EAI_SERVICE */
+ "socktype not supported", /* EAI_SOCKTYPE */
+ "system failure", /* EAI_SYSTEM */
+ "bad hints", /* EAI_BADHINTS */
+ "bad protocol", /* EAI_PROTOCOL */
+
+ "unknown error" /* Must be last. */
+};
+
+static const int gai_nerr = (sizeof(gai_errlist)/sizeof(*gai_errlist));
+
+#define EAI_BUFSIZE 128
+
+const char *
+gai_strerror(int ecode) {
+#ifndef DO_PTHREADS
+ static char buf[EAI_BUFSIZE];
+#else /* DO_PTHREADS */
+ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_key_t key;
+ static int once = 0;
+ char *buf;
+#endif
+
+ if (ecode >= 0 && ecode < (gai_nerr - 1))
+ return (gai_errlist[ecode]);
+
+#ifdef DO_PTHREADS
+ if (!once) {
+ pthread_mutex_lock(&lock);
+ if (!once++)
+ pthread_key_create(&key, free);
+ pthread_mutex_unlock(&lock);
+ }
+
+ buf = pthread_getspecific(key);
+ if (buf == NULL) {
+ buf = malloc(EAI_BUFSIZE);
+ if (buf == NULL)
+ return ("unknown error");
+ pthread_setspecific(key, buf);
+ }
+#endif
+ /*
+ * XXX This really should be snprintf(buf, EAI_BUFSIZE, ...).
+ * It is safe until message catalogs are used.
+ */
+ sprintf(buf, "%s: %d", gai_errlist[gai_nerr - 1], ecode);
+ return (buf);
}
diff --git a/contrib/bind/lib/irs/gen.c b/contrib/bind/lib/irs/gen.c
index fe41088..5ba7d52 100644
--- a/contrib/bind/lib/irs/gen.c
+++ b/contrib/bind/lib/irs/gen.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: gen.c,v 1.25 1999/10/13 16:39:29 vixie Exp $";
+static const char rcsid[] = "$Id: gen.c,v 1.26 2001/05/29 05:48:35 marka Exp $";
#endif
/*
@@ -399,7 +399,10 @@ init_map_rules(struct gen_p *irs, const char *conf_file) {
char *tmp;
int n;
- for (tmp = line; isascii(*tmp) && isspace(*tmp); tmp++)
+ for (tmp = line;
+ isascii((unsigned char)*tmp) &&
+ isspace((unsigned char)*tmp);
+ tmp++)
(void)NULL;
if (*tmp == '#' || *tmp == '\n' || *tmp == '\0')
continue;
diff --git a/contrib/bind/lib/irs/gen_gr.c b/contrib/bind/lib/irs/gen_gr.c
index 14dfa2d..4b1b282 100644
--- a/contrib/bind/lib/irs/gen_gr.c
+++ b/contrib/bind/lib/irs/gen_gr.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: gen_gr.c,v 1.22 2000/07/11 05:51:56 vixie Exp $";
+static const char rcsid[] = "$Id: gen_gr.c,v 1.25 2001/06/07 02:12:26 marka Exp $";
#endif
/* Imports */
@@ -324,8 +324,9 @@ gr_res_set(struct irs_gr *this, struct __res_state *res,
static void
grmerge(struct irs_gr *this, const struct group *src, int preserve) {
struct pvt *pvt = (struct pvt *)this->private;
- char *cp, **m, **p;
- int n, ndst, nnew, memadj;
+ char *cp, **m, **p, *oldmembuf;
+ int n, ndst, nnew;
+ size_t used;
if (!preserve) {
pvt->group.gr_gid = src->gr_gid;
@@ -372,15 +373,25 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) {
/* No work to do. */
return;
}
- cp = realloc(pvt->membuf, pvt->membufsize + n);
+ used = preserve ? pvt->membufsize : 0;
+ cp = malloc(used + n);
if (!cp) {
/* No harm done, no work done. */
return;
}
- memadj = cp - pvt->membuf;
+ if (used != 0)
+ memcpy(cp, pvt->membuf, used);
+ oldmembuf = pvt->membuf;
pvt->membuf = cp;
- cp += pvt->membufsize;
- pvt->membufsize += n;
+ pvt->membufsize = used + n;
+ cp += used;
+
+ /*
+ * Adjust group.gr_mem.
+ */
+ if (pvt->membuf != oldmembuf)
+ for (m = pvt->group.gr_mem; *m; m++)
+ *m = pvt->membuf + (*m - oldmembuf);
/*
* Add new elements.
@@ -393,8 +404,10 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) {
cp += strlen(cp) + 1;
}
if (preserve) {
- pvt->group.gr_name += memadj;
- pvt->group.gr_passwd += memadj;
+ pvt->group.gr_name = pvt->membuf +
+ (pvt->group.gr_name - oldmembuf);
+ pvt->group.gr_passwd = pvt->membuf +
+ (pvt->group.gr_passwd - oldmembuf);
} else {
pvt->group.gr_name = cp;
strcpy(cp, src->gr_name);
@@ -403,6 +416,8 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) {
strcpy(cp, src->gr_passwd);
cp += strlen(src->gr_passwd) + 1;
}
+ if (oldmembuf != NULL)
+ free(oldmembuf);
INSIST(cp >= pvt->membuf && cp <= &pvt->membuf[pvt->membufsize]);
}
diff --git a/contrib/bind/lib/irs/gen_ho.c b/contrib/bind/lib/irs/gen_ho.c
index 9e7a429..12ed7cd 100644
--- a/contrib/bind/lib/irs/gen_ho.c
+++ b/contrib/bind/lib/irs/gen_ho.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: gen_ho.c,v 1.15 1999/10/13 16:39:29 vixie Exp $";
+static const char rcsid[] = "$Id: gen_ho.c,v 1.16 2001/05/29 05:48:36 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -68,6 +68,8 @@ 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 addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
+ const struct addrinfo *pai);
static int init(struct irs_ho *this);
@@ -102,6 +104,7 @@ irs_gen_ho(struct irs_acc *this) {
ho->minimize = ho_minimize;
ho->res_get = ho_res_get;
ho->res_set = ho_res_set;
+ ho->addrinfo = ho_addrinfo;
return (ho);
}
@@ -328,6 +331,51 @@ ho_res_set(struct irs_ho *this, struct __res_state *res,
}
}
+static struct addrinfo *
+ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
+{
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct irs_rule *rule;
+ struct addrinfo *rval = NULL;
+ 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;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
+ errno = 0;
+ if (ho->addrinfo == NULL) /* for safety */
+ continue;
+ rval = (*ho->addrinfo)(ho, name, pai);
+ 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 (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);
+ if (rval)
+ freeaddrinfo(rval);
+ return (NULL);
+}
+
static int
init(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
diff --git a/contrib/bind/lib/irs/gen_ng.c b/contrib/bind/lib/irs/gen_ng.c
index 064d616..c28b510 100644
--- a/contrib/bind/lib/irs/gen_ng.c
+++ b/contrib/bind/lib/irs/gen_ng.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: gen_ng.c,v 1.14 1999/10/13 16:39:29 vixie Exp $";
+static const char rcsid[] = "$Id: gen_ng.c,v 1.15 2001/05/29 05:48:38 marka Exp $";
#endif
/* Imports */
@@ -52,7 +52,8 @@ struct pvt {
/* Forward */
static void ng_close(struct irs_ng *);
-static int ng_next(struct irs_ng *, char **, char **, char **);
+static int ng_next(struct irs_ng *, const char **,
+ const char **, const char **);
static int ng_test(struct irs_ng *, const char *,
const char *, const char *,
const char *);
@@ -103,7 +104,9 @@ ng_close(struct irs_ng *this) {
}
static int
-ng_next(struct irs_ng *this, char **host, char **user, char **domain) {
+ng_next(struct irs_ng *this, const char **host, const char **user,
+ const char **domain)
+{
struct pvt *pvt = (struct pvt *)this->private;
struct irs_ng *ng;
diff --git a/contrib/bind/lib/irs/gen_p.h b/contrib/bind/lib/irs/gen_p.h
index b8210b0..35ef439 100644
--- a/contrib/bind/lib/irs/gen_p.h
+++ b/contrib/bind/lib/irs/gen_p.h
@@ -16,7 +16,7 @@
*/
/*
- * $Id: gen_p.h,v 1.10 1999/01/18 07:46:50 vixie Exp $
+ * $Id: gen_p.h,v 1.11 2001/05/29 05:48:39 marka Exp $
*/
/* Notes:
@@ -90,7 +90,7 @@ struct irs_rule {
* This is the private data for a search access class.
*/
struct gen_p {
- const char * options;
+ char * options;
struct irs_rule * map_rules[(int)irs_nmap];
struct irs_inst accessors[(int)irs_nacc];
struct __res_state * res;
diff --git a/contrib/bind/lib/irs/getaddrinfo.c b/contrib/bind/lib/irs/getaddrinfo.c
index f95a681..f2c533d 100644
--- a/contrib/bind/lib/irs/getaddrinfo.c
+++ b/contrib/bind/lib/irs/getaddrinfo.c
@@ -1,505 +1,1225 @@
-/*-
- * 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.
+/* $KAME: getaddrinfo.c,v 1.14 2001/01/06 09:41:15 jinmei Exp $ */
+
+/*
+ * 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. 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.
*
- * BSDI $Id: getaddrinfo.c,v 8.3 1999/06/11 01:25:58 vixie Exp $
+ * 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>
+/*
+ * Issues to be discussed:
+ * - Thread safe-ness must be checked.
+ * - Return values. There are nonstandard return values defined and used
+ * in the source code. This is because RFC2553 is silent about which error
+ * code must be returned for which situation.
+ * - IPv4 classful (shortened) form. RFC2553 is silent about it. XNET 5.2
+ * says to use inet_aton() to convert IPv4 numeric to binary (allows
+ * classful form as a result).
+ * current code - disallow classful form for IPv4 (due to use of inet_pton).
+ * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is
+ * invalid.
+ * current code - SEGV on freeaddrinfo(NULL)
+ * Note:
+ * - We use getipnodebyname() just for thread-safeness. There's no intent
+ * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
+ * getipnodebyname().
+ * - The code filters out AFs that are not supported by the kernel,
+ * when globbing NULL hostname (to loopback, or wildcard). Is it the right
+ * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG
+ * in ai_flags?
+ * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
+ * (1) what should we do against numeric hostname (2) what should we do
+ * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready?
+ * non-loopback address configured? global address configured?
+ * - To avoid search order issue, we have a big amount of code duplicate
+ * from gethnamaddr.c and some other places. The issues that there's no
+ * lower layer function to lookup "IPv4 or IPv6" record. Calling
+ * gethostbyname2 from getaddrinfo will end up in wrong search order, as
+ * follows:
+ * - The code makes use of following calls when asked to resolver with
+ * ai_family = PF_UNSPEC:
+ * getipnodebyname(host, AF_INET6);
+ * getipnodebyname(host, AF_INET);
+ * This will result in the following queries if the node is configure to
+ * prefer /etc/hosts than DNS:
+ * lookup /etc/hosts for IPv6 address
+ * lookup DNS for IPv6 address
+ * lookup /etc/hosts for IPv4 address
+ * lookup DNS for IPv4 address
+ * which may not meet people's requirement.
+ * The right thing to happen is to have underlying layer which does
+ * PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
+ * This would result in a bit of code duplicate with _dns_ghbyname() and
+ * friends.
+ */
+
+#include "port_before.h"
+
+#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
-#include <sys/un.h>
+
+#include <net/if.h>
#include <netinet/in.h>
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
#include <netdb.h>
-#include <errno.h>
+#include <resolv.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);
+#include <stddef.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <stdarg.h>
+
+#include <irs.h>
+
+#include "port_after.h"
+
+#include "irs_data.h"
+
+/*
+ * if we enable it, we will see duplicated addrinfo entries on reply if both
+ * AAAA and A6 records are found. disable it for default installation.
+ */
+#undef T_A6
+
+#define SUCCESS 0
+#define ANY 0
+#define YES 1
+#define NO 0
+
+static const char in_addrany[] = { 0, 0, 0, 0 };
+static const char in6_addrany[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static const char in_loopback[] = { 127, 0, 0, 1 };
+static const char in6_loopback[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+};
+
+static const struct afd {
+ int a_af;
+ int a_addrlen;
+ int a_socklen;
+ int a_off;
+ const char *a_addrany;
+ const char *a_loopback;
+ int a_scoped;
+} afdl [] = {
+ {PF_INET6, sizeof(struct in6_addr),
+ sizeof(struct sockaddr_in6),
+ offsetof(struct sockaddr_in6, sin6_addr),
+ in6_addrany, in6_loopback, 1},
+ {PF_INET, sizeof(struct in_addr),
+ sizeof(struct sockaddr_in),
+ offsetof(struct sockaddr_in, sin_addr),
+ in_addrany, in_loopback, 0},
+ {0, 0, 0, 0, NULL, NULL, 0},
+};
+
+struct explore {
+ int e_af;
+ int e_socktype;
+ int e_protocol;
+ const char *e_protostr;
+ int e_wild;
+#define WILD_AF(ex) ((ex)->e_wild & 0x01)
+#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
+#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
+};
+
+static const struct explore explore[] = {
+#if 0
+ { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
#endif
+ { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
+ { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
+ { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
+ { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
+ { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
+ { PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
+ { -1, 0, 0, NULL, 0 },
+};
+
+#define PTON_MAX 16
+
+#define MAXPACKET (1024*64)
-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 (**)());
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+static int str_isnumber __P((const char *));
+static int explore_fqdn __P((const struct addrinfo *, const char *,
+ const char *, struct addrinfo **));
+static int explore_copy __P((const struct addrinfo *, const struct addrinfo *,
+ struct addrinfo **));
+static int explore_null __P((const struct addrinfo *,
+ const char *, struct addrinfo **));
+static int explore_numeric __P((const struct addrinfo *, const char *,
+ const char *, struct addrinfo **));
+static int explore_numeric_scope __P((const struct addrinfo *, const char *,
+ const char *, struct addrinfo **));
+static int get_canonname __P((const struct addrinfo *,
+ struct addrinfo *, const char *));
+static struct addrinfo *get_ai __P((const struct addrinfo *,
+ const struct afd *, const char *));
+static struct addrinfo *copy_ai __P((const struct addrinfo *));
+static int get_portmatch __P((const struct addrinfo *, const char *));
+static int get_port __P((const struct addrinfo *, const char *, int));
+static const struct afd *find_afd __P((int));
+static int addrconfig __P((int));
+static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *));
+static struct net_data *init __P((void));
+
+struct addrinfo *hostent2addrinfo __P((struct hostent *,
+ const struct addrinfo *));
+struct addrinfo *addr2addrinfo __P((const struct addrinfo *,
+ const char *));
+
+#if 0
+static const char *ai_errlist[] = {
+ "Success",
+ "Address family for hostname not supported", /* EAI_ADDRFAMILY */
+ "Temporary failure in name resolution", /* EAI_AGAIN */
+ "Invalid value for ai_flags", /* EAI_BADFLAGS */
+ "Non-recoverable failure in name resolution", /* EAI_FAIL */
+ "ai_family not supported", /* EAI_FAMILY */
+ "Memory allocation failure", /* EAI_MEMORY */
+ "No address associated with hostname", /* EAI_NODATA */
+ "hostname nor servname provided, or not known", /* EAI_NONAME */
+ "servname not supported for ai_socktype", /* EAI_SERVICE */
+ "ai_socktype not supported", /* EAI_SOCKTYPE */
+ "System error returned in errno", /* EAI_SYSTEM */
+ "Invalid value for hints", /* EAI_BADHINTS */
+ "Resolved protocol is unknown", /* EAI_PROTOCOL */
+ "Unknown error", /* EAI_MAX */
+};
+#endif
-#define FOUND_IPV4 0x1
-#define FOUND_IPV6 0x2
-#define FOUND_MAX 2
+/* XXX macros that make external reference is BAD. */
+
+#define GET_AI(ai, afd, addr) \
+do { \
+ /* external reference: pai, error, and label free */ \
+ (ai) = get_ai(pai, (afd), (addr)); \
+ if ((ai) == NULL) { \
+ error = EAI_MEMORY; \
+ goto free; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define GET_PORT(ai, serv) \
+do { \
+ /* external reference: error and label free */ \
+ error = get_port((ai), (serv), 0); \
+ if (error != 0) \
+ goto free; \
+} while (/*CONSTCOND*/0)
+
+#define GET_CANONNAME(ai, str) \
+do { \
+ /* external reference: pai, error and label free */ \
+ error = get_canonname(pai, (ai), (str)); \
+ if (error != 0) \
+ goto free; \
+} while (/*CONSTCOND*/0)
+
+#define ERR(err) \
+do { \
+ /* external reference: error, and label bad */ \
+ error = (err); \
+ goto bad; \
+ /*NOTREACHED*/ \
+} while (/*CONSTCOND*/0)
+
+#define MATCH_FAMILY(x, y, w) \
+ ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
+#define MATCH(x, y, w) \
+ ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
+
+#if 0 /* bind8 has its own version */
+char *
+gai_strerror(ecode)
+ int ecode;
+{
+ if (ecode < 0 || ecode > EAI_MAX)
+ ecode = EAI_MAX;
+ return ai_errlist[ecode];
+}
+#endif
+
+void
+freeaddrinfo(ai)
+ struct addrinfo *ai;
+{
+ struct addrinfo *next;
+
+ do {
+ next = ai->ai_next;
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
+ /* no need to free(ai->ai_addr) */
+ free(ai);
+ ai = next;
+ } while (ai);
+}
+
+static int
+str_isnumber(p)
+ const char *p;
+{
+ char *ep;
+
+ if (*p == '\0')
+ return NO;
+ ep = NULL;
+ (void)strtoul(p, &ep, 10);
+ if (ep && *ep == '\0')
+ return YES;
+ else
+ return NO;
+}
int
-getaddrinfo(const char *hostname, const char *servname,
- const struct addrinfo *hints, struct addrinfo **res)
+getaddrinfo(hostname, servname, hints, res)
+ const char *hostname, *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])();
+ struct addrinfo sentinel;
+ struct addrinfo *cur;
+ int error = 0;
+ struct addrinfo ai, ai0, *afai;
+ struct addrinfo *pai;
+ const struct explore *ex;
- if (hostname == NULL && servname == NULL)
- return (EAI_NONAME);
+ memset(&sentinel, 0, sizeof(sentinel));
+ cur = &sentinel;
+ pai = &ai;
+ pai->ai_flags = 0;
+ pai->ai_family = PF_UNSPEC;
+ pai->ai_socktype = ANY;
+ pai->ai_protocol = ANY;
+ pai->ai_addrlen = 0;
+ pai->ai_canonname = NULL;
+ pai->ai_addr = NULL;
+ pai->ai_next = NULL;
- proto = NULL;
- if (hints != NULL) {
- if (hints->ai_flags & ~(AI_MASK))
- return (EAI_BADFLAGS);
+ if (hostname == NULL && servname == NULL)
+ return EAI_NONAME;
+ if (hints) {
+ /* error check for hints */
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);
- }
+ hints->ai_addr || hints->ai_next)
+ ERR(EAI_BADHINTS); /* xxx */
+ if (hints->ai_flags & ~AI_MASK)
+ ERR(EAI_BADFLAGS);
+ switch (hints->ai_family) {
+ case PF_UNSPEC:
+ case PF_INET:
+ case PF_INET6:
break;
-#endif
default:
- return (EAI_FAMILY);
+ ERR(EAI_FAMILY);
+ }
+ memcpy(pai, hints, sizeof(*pai));
+
+ /*
+ * if both socktype/protocol are specified, check if they
+ * are meaningful combination.
+ */
+ if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
+ for (ex = explore; ex->e_af >= 0; ex++) {
+ if (pai->ai_family != ex->e_af)
+ continue;
+ if (ex->e_socktype == ANY)
+ continue;
+ if (ex->e_protocol == ANY)
+ continue;
+ if (pai->ai_socktype == ex->e_socktype &&
+ pai->ai_protocol != ex->e_protocol) {
+ ERR(EAI_BADHINTS);
+ }
+ }
}
- } 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 '/'.
+ * post-2553: AI_ALL and AI_V4MAPPED are effective only against
+ * AF_INET6 query. They needs to be ignored if specified in other
+ * occassions.
*/
+ switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
+ case AI_V4MAPPED:
+ case AI_ALL | AI_V4MAPPED:
+ if (pai->ai_family != AF_INET6)
+ pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
+ break;
+ case AI_ALL:
+#if 1
+ /* illegal */
+ ERR(EAI_BADFLAGS);
+#else
+ pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
+ break;
+#endif
+ }
- if (hostname &&
- (family == AF_LOCAL || (family == 0 && *hostname == '/')))
- return (get_local(hostname, socktype, res));
+ /*
+ * check for special cases. (1) numeric servname is disallowed if
+ * socktype/protocol are left unspecified. (2) servname is disallowed
+ * for raw and other inet{,6} sockets.
+ */
+ if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
+#ifdef PF_INET6
+ || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
+#endif
+ ) {
+ ai0 = *pai; /* backup *pai */
- if (servname &&
- (family == AF_LOCAL || (family == 0 && *servname == '/')))
- return (get_local(servname, socktype, res));
+ if (pai->ai_family == PF_UNSPEC) {
+#ifdef PF_INET6
+ pai->ai_family = PF_INET6;
+#else
+ pai->ai_family = PF_INET;
#endif
+ }
+ error = get_portmatch(pai, servname);
+ if (error)
+ ERR(error);
+
+ *pai = ai0;
+ }
+
+ ai0 = *pai;
+
+ /* NULL hostname, or numeric hostname */
+ for (ex = explore; ex->e_af >= 0; ex++) {
+ *pai = ai0;
+
+ if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
+ continue;
+ if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
+ continue;
+ if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
+ continue;
+
+ if (pai->ai_family == PF_UNSPEC)
+ pai->ai_family = ex->e_af;
+ if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
+ pai->ai_socktype = ex->e_socktype;
+ if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
+ pai->ai_protocol = ex->e_protocol;
+
+ /*
+ * if the servname does not match socktype/protocol, ignore it.
+ */
+ if (get_portmatch(pai, servname) != 0)
+ continue;
+
+ if (hostname == NULL) {
+ /*
+ * filter out AFs that are not supported by the kernel
+ * XXX errno?
+ */
+ if (!addrconfig(pai->ai_family))
+ continue;
+ error = explore_null(pai, servname, &cur->ai_next);
+ } else
+ error = explore_numeric_scope(pai, hostname, servname,
+ &cur->ai_next);
+
+ if (error)
+ goto free;
+
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ }
/*
- * Ok, only AF_INET and AF_INET6 left.
+ * XXX
+ * If numreic representation of AF1 can be interpreted as FQDN
+ * representation of AF2, we need to think again about the code below.
*/
- ai_list = NULL;
+ if (sentinel.ai_next)
+ goto good;
+
+ if (pai->ai_flags & AI_NUMERICHOST)
+ ERR(EAI_NONAME);
+ if (hostname == NULL)
+ ERR(EAI_NONAME);
/*
- * First, look up the service name (port) if it was
- * requested. If the socket type wasn't specified, then
- * try and figure it out.
+ * hostname as alphabetical name.
+ * We'll make sure that
+ * - if returning addrinfo list is empty, return non-zero error
+ * value (already known one or EAI_NONAME).
+ * - otherwise,
+ * + if we haven't had any errors, return 0 (i.e. success).
+ * + if we've had an error, free the list and return the error.
+ * without any assumption on the behavior of explore_fqdn().
*/
- 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;
+
+ /* first, try to query DNS for all possible address families. */
+ *pai = ai0;
+ error = explore_fqdn(pai, hostname, servname, &afai);
+ if (error) {
+ if (afai != NULL)
+ freeaddrinfo(afai);
+ goto free;
+ }
+ if (afai == NULL) {
+ error = EAI_NONAME; /* we've had no errors. */
+ goto free;
+ }
/*
- * Next, deal with just a service name, and no hostname.
- * (we verified that one of them was non-null up above).
+ * we would like to prefer AF_INET6 than AF_INET, so we'll make an
+ * outer loop by AFs.
*/
- 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;
+ for (ex = explore; ex->e_af >= 0; ex++) {
+ *pai = ai0;
+
+ if (pai->ai_family == PF_UNSPEC)
+ pai->ai_family = ex->e_af;
+
+ if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
+ continue;
+ if (!MATCH(pai->ai_socktype, ex->e_socktype,
+ WILD_SOCKTYPE(ex))) {
+ continue;
+ }
+ if (!MATCH(pai->ai_protocol, ex->e_protocol,
+ WILD_PROTOCOL(ex))) {
+ continue;
}
- 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;
+#ifdef AI_ADDRCONFIG
+ /*
+ * If AI_ADDRCONFIG is specified, check if we are
+ * expected to return the address family or not.
+ */
+ if ((pai->ai_flags & AI_ADDRCONFIG) != 0 &&
+ !addrconfig(pai->ai_family))
+ continue;
+#endif
+
+ if (pai->ai_family == PF_UNSPEC)
+ pai->ai_family = ex->e_af;
+ if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
+ pai->ai_socktype = ex->e_socktype;
+ if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
+ pai->ai_protocol = ex->e_protocol;
+
+ /*
+ * if the servname does not match socktype/protocol, ignore it.
+ */
+ if (get_portmatch(pai, servname) != 0)
+ continue;
+
+ if ((error = explore_copy(pai, afai, &cur->ai_next)) != 0) {
+ freeaddrinfo(afai);
+ goto free;
}
- *res = ai_list;
- return (0);
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
}
+ freeaddrinfo(afai); /* afai must not be NULL at this point. */
+
+ /* we must not have got any errors. */
+ if (error != 0) /* just for diagnosis */
+ abort();
+
+ if (sentinel.ai_next) {
+good:
+ *res = sentinel.ai_next;
+ return(SUCCESS);
+ } else {
+ /*
+ * All the process succeeded, but we've had an empty list.
+ * This can happen if the given hints do not match our
+ * candidates.
+ */
+ error = EAI_NONAME;
+ }
+
+free:
+bad:
+ if (sentinel.ai_next)
+ freeaddrinfo(sentinel.ai_next);
+ *res = NULL;
+ return(error);
+}
+
+/*
+ * FQDN hostname, DNS lookup
+ */
+static int
+explore_fqdn(pai, hostname, servname, res)
+ const struct addrinfo *pai;
+ const char *hostname;
+ const char *servname;
+ struct addrinfo **res;
+{
+ struct addrinfo *result;
+ struct addrinfo *cur;
+ struct net_data *net_data = init();
+ struct irs_ho *ho;
+ int error = 0;
+ char tmp[NS_MAXDNAME];
+ const char *cp;
+
+ result = NULL;
+
/*
- * 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 the servname does not match socktype/protocol, ignore it.
*/
- 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);
- }
+ if (get_portmatch(pai, servname) != 0)
+ return(0);
+
+ if (!net_data || !(ho = net_data->ho))
+ return(0);
+#if 0 /* XXX (notyet) */
+ if (net_data->ho_stayopen && net_data->ho_last &&
+ net_data->ho_last->h_addrtype == af) {
+ 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);
}
+#endif
+ if (!strchr(hostname, '.') &&
+ (cp = res_hostalias(net_data->res, hostname,
+ tmp, sizeof(tmp))))
+ hostname = cp;
+ result = (*ho->addrinfo)(ho, hostname, pai);
+ if (!net_data->ho_stayopen) {
+ (*ho->minimize)(ho);
+ }
+ if (result == NULL) {
+ int e = h_errno;
- set_order(family, net_order);
- for (i = 0; i < FOUND_MAX; i++) {
- if (net_order[i] == NULL)
+ switch(e) {
+ case NETDB_INTERNAL:
+ error = EAI_SYSTEM;
+ break;
+ case TRY_AGAIN:
+ error = EAI_AGAIN;
+ break;
+ case NO_RECOVERY:
+ error = EAI_FAIL;
+ break;
+ case HOST_NOT_FOUND:
+ case NO_DATA:
+ error = EAI_NONAME;
break;
- if ((err = (net_order[i])(hostname, flags, &ai_list,
- socktype, port)) != 0)
- return(err);
+ default:
+ case NETDB_SUCCESS: /* should be impossible... */
+ error = EAI_NONAME;
+ break;
+ }
+ goto free;
}
- if (ai_list == NULL)
- return (EAI_NODATA);
+ for (cur = result; cur; cur = cur->ai_next) {
+ GET_PORT(cur, servname); /* XXX: redundant lookups... */
+ /* canonname should already be filled. */
+ }
-done:
- ai_list = ai_reverse(ai_list);
+ *res = result;
- *res = ai_list;
- return (0);
+ return(0);
+
+free:
+ if (result)
+ freeaddrinfo(result);
+ return error;
}
-static void
-set_order(family, net_order)
- int family;
- int (**net_order)();
+static int
+explore_copy(pai, src0, res)
+ const struct addrinfo *pai; /* seed */
+ const struct addrinfo *src0; /* source */
+ struct addrinfo **res;
{
- char *order, *tok;
- int found;
+ int error;
+ struct addrinfo sentinel, *cur;
+ const struct addrinfo *src;
- 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;
- }
+ error = 0;
+ sentinel.ai_next = NULL;
+ cur = &sentinel;
+
+ for (src = src0; src != NULL; src = src->ai_next) {
+ if (src->ai_family != pai->ai_family)
+ continue;
+
+ cur->ai_next = copy_ai(src);
+ if (!cur->ai_next) {
+ error = EAI_MEMORY;
+ goto fail;
}
- /* 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;
+ cur->ai_next->ai_socktype = pai->ai_socktype;
+ cur->ai_next->ai_protocol = pai->ai_protocol;
+ cur = cur->ai_next;
}
- *net_order = NULL;
- return;
+
+ *res = sentinel.ai_next;
+ return 0;
+
+fail:
+ freeaddrinfo(sentinel.ai_next);
+ return error;
}
-static char v4_loop[4] = { 127, 0, 0, 1 };
+/*
+ * hostname == NULL.
+ * passive socket -> anyaddr (0.0.0.0 or ::)
+ * non-passive socket -> localhost (127.0.0.1 or ::1)
+ */
+static int
+explore_null(pai, servname, res)
+ const struct addrinfo *pai;
+ const char *servname;
+ struct addrinfo **res;
+{
+ const struct afd *afd;
+ struct addrinfo *cur;
+ struct addrinfo sentinel;
+ int error;
+
+ *res = NULL;
+ sentinel.ai_next = NULL;
+ cur = &sentinel;
+
+ afd = find_afd(pai->ai_family);
+ if (afd == NULL)
+ return 0;
+
+ if (pai->ai_flags & AI_PASSIVE) {
+ GET_AI(cur->ai_next, afd, afd->a_addrany);
+ /* xxx meaningless?
+ * GET_CANONNAME(cur->ai_next, "anyaddr");
+ */
+ GET_PORT(cur->ai_next, servname);
+ } else {
+ GET_AI(cur->ai_next, afd, afd->a_loopback);
+ /* xxx meaningless?
+ * GET_CANONNAME(cur->ai_next, "localhost");
+ */
+ GET_PORT(cur->ai_next, servname);
+ }
+ cur = cur->ai_next;
+
+ *res = sentinel.ai_next;
+ return 0;
+
+free:
+ if (sentinel.ai_next)
+ freeaddrinfo(sentinel.ai_next);
+ return error;
+}
+/*
+ * numeric hostname
+ */
static int
-add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
- int socktype, int port)
+explore_numeric(pai, hostname, servname, res)
+ const struct addrinfo *pai;
+ const char *hostname;
+ const char *servname;
+ struct addrinfo **res;
{
- struct addrinfo *ai;
- struct hostent *hp;
- char **addr;
+ const struct afd *afd;
+ struct addrinfo *cur;
+ struct addrinfo sentinel;
+ int error;
+ char pton[PTON_MAX];
+
+ *res = NULL;
+ sentinel.ai_next = NULL;
+ cur = &sentinel;
- if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
- if ((ai = ai_clone(*aip, AF_INET)) == NULL) {
- freeaddrinfo(*aip);
- return(EAI_MEMORY);
+ afd = find_afd(pai->ai_family);
+ if (afd == NULL)
+ return 0;
+
+ switch (afd->a_af) {
+#if 0 /*X/Open spec*/
+ case AF_INET:
+ if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
+ if (pai->ai_family == afd->a_af ||
+ pai->ai_family == PF_UNSPEC /*?*/) {
+ GET_AI(cur->ai_next, afd, pton);
+ GET_PORT(cur->ai_next, servname);
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ } else
+ ERR(EAI_FAMILY); /*xxx*/
+ }
+ break;
+#endif
+ default:
+ if (inet_pton(afd->a_af, hostname, pton) == 1) {
+ if (pai->ai_family == afd->a_af ||
+ pai->ai_family == PF_UNSPEC /*?*/) {
+ GET_AI(cur->ai_next, afd, pton);
+ GET_PORT(cur->ai_next, servname);
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ } else
+ ERR(EAI_FAMILY); /*xxx*/
}
+ break;
+ }
- *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);
+ *res = sentinel.ai_next;
+ return 0;
+
+free:
+bad:
+ if (sentinel.ai_next)
+ freeaddrinfo(sentinel.ai_next);
+ return error;
+}
+
+/*
+ * numeric hostname with scope
+ */
+static int
+explore_numeric_scope(pai, hostname, servname, res)
+ const struct addrinfo *pai;
+ const char *hostname;
+ const char *servname;
+ struct addrinfo **res;
+{
+#ifndef SCOPE_DELIMITER
+ return explore_numeric(pai, hostname, servname, res);
+#else
+ const struct afd *afd;
+ struct addrinfo *cur;
+ int error;
+ char *cp, *hostname2 = NULL, *scope, *addr;
+ struct sockaddr_in6 *sin6;
+
+ afd = find_afd(pai->ai_family);
+ if (afd == NULL)
+ return 0;
+
+ if (!afd->a_scoped)
+ return explore_numeric(pai, hostname, servname, res);
+
+ cp = strchr(hostname, SCOPE_DELIMITER);
+ if (cp == NULL)
+ return explore_numeric(pai, hostname, servname, res);
+
+ /*
+ * Handle special case of <scoped_address><delimiter><scope id>
+ */
+ hostname2 = strdup(hostname);
+ if (hostname2 == NULL)
+ return EAI_MEMORY;
+ /* terminate at the delimiter */
+ hostname2[cp - hostname] = '\0';
+ addr = hostname2;
+ scope = cp + 1;
+
+ error = explore_numeric(pai, addr, servname, res);
+ if (error == 0) {
+ int scopeid;
+
+ for (cur = *res; cur; cur = cur->ai_next) {
+ if (cur->ai_family != AF_INET6)
+ continue;
+ sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
+ if ((scopeid = ip6_str2scopeid(scope, sin6)) == -1) {
+ free(hostname2);
+ return(EAI_NONAME); /* XXX: is return OK? */
}
- if (flags & AI_CANONNAME)
- ai->ai_canonname = strdup(hp->h_name);
+#ifdef HAVE_SIN6_SCOPE_ID
+ sin6->sin6_scope_id = scopeid;
+#endif
}
}
- return(0);
-}
-static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+ free(hostname2);
+
+ return error;
+#endif
+}
static int
-add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
- int socktype, int port)
+get_canonname(pai, ai, str)
+ const struct addrinfo *pai;
+ struct addrinfo *ai;
+ const char *str;
{
+ if ((pai->ai_flags & AI_CANONNAME) != 0) {
+ ai->ai_canonname = (char *)malloc(strlen(str) + 1);
+ if (ai->ai_canonname == NULL)
+ return EAI_MEMORY;
+ strcpy(ai->ai_canonname, str);
+ }
+ return 0;
+}
+
+static struct addrinfo *
+get_ai(pai, afd, addr)
+ const struct addrinfo *pai;
+ const struct afd *afd;
+ const char *addr;
+{
+ char *p;
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);
- }
+ ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
+ + (afd->a_socklen));
+ if (ai == NULL)
+ return NULL;
- *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);
+ memcpy(ai, pai, sizeof(struct addrinfo));
+ ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
+ memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
+#ifdef HAVE_SA_LEN
+ ai->ai_addr->sa_len = afd->a_socklen;
+#endif
+ ai->ai_addrlen = afd->a_socklen;
+ ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
+ p = (char *)(void *)(ai->ai_addr);
+ memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
+ return ai;
+}
+
+/* XXX need to malloc() the same way we do from other functions! */
+static struct addrinfo *
+copy_ai(pai)
+ const struct addrinfo *pai;
+{
+ struct addrinfo *ai;
+ size_t l;
+
+ l = sizeof(*ai) + pai->ai_addrlen;
+ if ((ai = (struct addrinfo *)malloc(l)) == NULL)
+ return NULL;
+ memset(ai, 0, l);
+ memcpy(ai, pai, sizeof(*ai));
+ ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
+ memcpy(ai->ai_addr, pai->ai_addr, pai->ai_addrlen);
+
+ if (pai->ai_canonname) {
+ l = strlen(pai->ai_canonname) + 1;
+ if ((ai->ai_canonname = malloc(l)) == NULL) {
+ free(ai);
+ return NULL;
}
+#ifdef HAVE_STRLCPY
+ strlcpy(ai->ai_canonname, pai->ai_canonname, l);
+#else
+ strncpy(ai->ai_canonname, pai->ai_canonname, l);
+#endif
+ } else {
+ /* just to make sure */
+ ai->ai_canonname = NULL;
}
- return (0);
+
+ ai->ai_next = NULL;
+
+ return ai;
}
-void
-freeaddrinfo(struct addrinfo *ai) {
- struct addrinfo *ai_next;
+static int
+get_portmatch(const struct addrinfo *ai, const char *servname) {
- 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;
- }
+ /* get_port does not touch first argument. when matchonly == 1. */
+ /* LINTED const cast */
+ return get_port((const struct addrinfo *)ai, servname, 1);
}
-#ifdef AF_LOCAL
static int
-get_local(const char *name, int socktype, struct addrinfo **res) {
- struct addrinfo *ai;
- struct sockaddr_un *sun;
+get_port(const struct addrinfo *ai, const char *servname, int matchonly) {
+ const char *proto;
+ struct servent *sp;
+ int port;
+ int allownumeric;
- if (socktype == 0)
- return (EAI_SOCKTYPE);
+ if (servname == NULL)
+ return 0;
+ switch (ai->ai_family) {
+ case AF_INET:
+#ifdef AF_INET6
+ case AF_INET6:
+#endif
+ break;
+ default:
+ return 0;
+ }
- if ((ai = ai_alloc(AF_LOCAL, sizeof(*sun))) == NULL)
- return (EAI_MEMORY);
+ switch (ai->ai_socktype) {
+ case SOCK_RAW:
+ return EAI_SERVICE;
+ case SOCK_DGRAM:
+ case SOCK_STREAM:
+ allownumeric = 1;
+ break;
+ case ANY:
+ allownumeric = 0;
+ break;
+ default:
+ return EAI_SOCKTYPE;
+ }
- sun = SUN(ai->ai_addr);
- strncpy(sun->sun_path, name, sizeof(sun->sun_path));
+ if (str_isnumber(servname)) {
+ if (!allownumeric)
+ return EAI_SERVICE;
+ port = htons(atoi(servname));
+ if (port < 0 || port > 65535)
+ return EAI_SERVICE;
+ } else {
+ switch (ai->ai_socktype) {
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ default:
+ proto = NULL;
+ break;
+ }
- ai->ai_socktype = socktype;
- /*
- * ai->ai_flags, ai->ai_protocol, ai->ai_canonname,
- * and ai->ai_next were initialized to zero.
- */
+ if ((sp = getservbyname(servname, proto)) == NULL)
+ return EAI_SERVICE;
+ port = sp->s_port;
+ }
+
+ if (!matchonly) {
+ switch (ai->ai_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)(void *)
+ ai->ai_addr)->sin_port = port;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(void *)
+ ai->ai_addr)->sin6_port = port;
+ break;
+ }
+ }
- *res = ai;
- return (0);
+ return 0;
+}
+
+static const struct afd *
+find_afd(af)
+ int af;
+{
+ const struct afd *afd;
+
+ if (af == PF_UNSPEC)
+ return NULL;
+ for (afd = afdl; afd->a_af; afd++) {
+ if (afd->a_af == af)
+ return afd;
+ }
+ return NULL;
}
-#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.
+ * post-2553: AI_ADDRCONFIG check. if we use getipnodeby* as backend, backend
+ * will take care of it.
+ * the semantics of AI_ADDRCONFIG is not defined well. we are not sure
+ * if the code is right or not.
*/
-static struct addrinfo *
-ai_alloc(int family, int addrlen) {
- struct addrinfo *ai;
+static int
+addrconfig(af)
+ int af;
+{
+ int s;
- if ((ai = (struct addrinfo *)calloc(1, sizeof(*ai))) == NULL)
- return (NULL);
+ /* XXX errno */
+ s = socket(af, SOCK_DGRAM, 0);
+ if (s < 0) {
+ if (errno != EMFILE)
+ return 0;
+ } else
+ close(s);
+ return 1;
+}
- if ((ai->ai_addr = SA(calloc(1, addrlen))) == NULL) {
- free(ai);
- return (NULL);
+/* convert a string to a scope identifier. XXX: IPv6 specific */
+static int
+ip6_str2scopeid(scope, sin6)
+ char *scope;
+ struct sockaddr_in6 *sin6;
+{
+ int scopeid;
+ struct in6_addr *a6 = &sin6->sin6_addr;
+ char *ep;
+
+ /* empty scopeid portion is invalid */
+ if (*scope == '\0')
+ return -1;
+
+#ifdef USE_IFNAMELINKID
+ if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
+ /*
+ * Using interface names as link indices can be allowed
+ * only when we can assume a one-to-one mappings between
+ * links and interfaces. See comments in getnameinfo.c.
+ */
+ scopeid = if_nametoindex(scope);
+ if (scopeid == 0)
+ goto trynumeric;
+ return(scopeid);
}
- 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);
+
+ /* still unclear about literal, allow numeric only - placeholder */
+ if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
+ goto trynumeric;
+ if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
+ goto trynumeric;
+ else
+ goto trynumeric; /* global */
+
+ /* try to convert to a numeric id as a last resort */
+trynumeric:
+ scopeid = (int)strtoul(scope, &ep, 10);
+ if (*ep == '\0')
+ return scopeid;
+ else
+ return -1;
}
-static struct addrinfo *
-ai_clone(struct addrinfo *oai, int family) {
- struct addrinfo *ai;
+struct addrinfo *
+hostent2addrinfo(hp, pai)
+ struct hostent *hp;
+ const struct addrinfo *pai;
+{
+ int i, af, error = 0;
+ char **aplist = NULL, *ap;
+ struct addrinfo sentinel, *cur;
+ const struct afd *afd;
+
+ af = hp->h_addrtype;
+ if (pai->ai_family != AF_UNSPEC && af != pai->ai_family)
+ return(NULL);
+
+ afd = find_afd(af);
+ if (afd == NULL)
+ return(NULL);
+
+ aplist = hp->h_addr_list;
- ai = ai_alloc(family, ((family == AF_INET6) ?
- sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
+ memset(&sentinel, 0, sizeof(sentinel));
+ cur = &sentinel;
- if (ai == NULL) {
- freeaddrinfo(oai);
- return (NULL);
+ for (i = 0; (ap = aplist[i]) != NULL; i++) {
+#if 0 /* the trick seems too much */
+ af = hp->h_addr_list;
+ if (af == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
+ af = AF_INET;
+ ap = ap + sizeof(struct in6_addr)
+ - sizeof(struct in_addr);
+ }
+ afd = find_afd(af);
+ if (afd == NULL)
+ continue;
+#endif /* 0 */
+
+ GET_AI(cur->ai_next, afd, ap);
+
+ /* GET_PORT(cur->ai_next, servname); */
+ if ((pai->ai_flags & AI_CANONNAME) != 0) {
+ /*
+ * RFC2553 says that ai_canonname will be set only for
+ * the first element. we do it for all the elements,
+ * just for convenience.
+ */
+ GET_CANONNAME(cur->ai_next, hp->h_name);
+ }
+ while (cur && cur->ai_next) /* no need to loop, actually. */
+ cur = cur->ai_next;
+ continue;
+
+ free:
+ if (cur->ai_next)
+ freeaddrinfo(cur->ai_next);
+ cur->ai_next = NULL;
+ /* continue, without tht pointer CUR advanced. */
}
- 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);
+
+ return(sentinel.ai_next);
}
-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;
+struct addrinfo *
+addr2addrinfo(pai, cp)
+ const struct addrinfo *pai;
+ const char *cp;
+{
+ const struct afd *afd;
+
+ afd = find_afd(pai->ai_family);
+ if (afd == NULL)
+ return(NULL);
+
+ return(get_ai(pai, afd, cp));
+}
+
+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 (nai);
+
+ return (net_data);
}
diff --git a/contrib/bind/lib/irs/getgrent.c b/contrib/bind/lib/irs/getgrent.c
index 866e8c5..f6eea13 100644
--- a/contrib/bind/lib/irs/getgrent.c
+++ b/contrib/bind/lib/irs/getgrent.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: getgrent.c,v 1.19 1999/10/13 16:39:30 vixie Exp $";
+static const char rcsid[] = "$Id: getgrent.c,v 1.20 2001/05/29 05:48:41 marka Exp $";
#endif
/* Imports */
@@ -36,6 +36,8 @@ static int __bind_irs_gr_unneeded;
#include <grp.h>
#include <resolv.h>
#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
#include <irs.h>
@@ -80,14 +82,14 @@ setgroupent(int stayopen) {
#ifdef SETGRENT_VOID
void
-setgrent() {
+setgrent(void) {
struct net_data *net_data = init();
- return (setgrent_p(net_data));
+ setgrent_p(net_data);
}
#else
int
-setgrent() {
+setgrent(void) {
struct net_data *net_data = init();
return (setgrent_p(net_data));
@@ -102,7 +104,7 @@ endgrent() {
}
int
-getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroups) {
+getgrouplist(GETGROUPLIST_ARGS) {
struct net_data *net_data = init();
return (getgrouplist_p(name, basegid, groups, ngroups, net_data));
@@ -142,7 +144,7 @@ getgrgid_p(gid_t gid, struct net_data *net_data) {
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)
+ (gid_t)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)
diff --git a/contrib/bind/lib/irs/getgrent_r.c b/contrib/bind/lib/irs/getgrent_r.c
index df055db..641a2b2 100644
--- a/contrib/bind/lib/irs/getgrent_r.c
+++ b/contrib/bind/lib/irs/getgrent_r.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: getgrent_r.c,v 8.7 2001/11/01 08:02:08 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <port_before.h>
@@ -26,7 +26,17 @@ static const char rcsid[] = "$Id: getgrent_r.c,v 8.4 1999/01/18 07:46:51 vixie E
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <sys/types.h>
+#if (defined(POSIX_GETGRNAM_R) || defined(POSIX_GETGRGID_R)) && \
+ defined(_POSIX_PTHREAD_SEMANTICS)
+ /* turn off solaris remapping in <grp.h> */
+#define _UNIX95
+#undef _POSIX_PTHREAD_SEMANTICS
#include <grp.h>
+#define _POSIX_PTHREAD_SEMANTICS 1
+#else
+#include <grp.h>
+#endif
#include <sys/param.h>
#include <port_after.h>
@@ -50,7 +60,7 @@ getgrnam_r(const char *name, struct group *gptr,
if (ge == NULL) {
*result = NULL;
- return (-1);
+ return (0);
}
res = copy_group(ge, gptr, buf, buflen);
@@ -75,11 +85,11 @@ getgrnam_r(const char *name, struct group *gptr,
/* POSIX 1003.1c */
#ifdef POSIX_GETGRGID_R
int
-__posix_getgrgid_r(const gid_t gid, struct group *gptr,
+__posix_getgrgid_r(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,
+getgrgid_r(gid_t gid, struct group *gptr,
char *buf, size_t buflen, struct group **result) {
#endif /* POSIX_GETGRGID_R */
struct group *ge = getgrgid(gid);
@@ -87,7 +97,7 @@ getgrgid_r(const gid_t gid, struct group *gptr,
if (ge == NULL) {
*result = NULL;
- return (-1);
+ return (0);
}
res = copy_group(ge, gptr, buf, buflen);
@@ -97,7 +107,7 @@ getgrgid_r(const gid_t gid, struct group *gptr,
#ifdef POSIX_GETGRGID_R
struct group *
-getgrgid_r(const gid_t gid, struct group *gptr,
+getgrgid_r(gid_t gid, struct group *gptr,
char *buf, int buflen) {
struct group *ge = getgrgid(gid);
int res;
@@ -181,7 +191,7 @@ copy_group(struct group *ge, struct group *gptr, char *buf, int buflen) {
if (len > buflen) {
errno = ERANGE;
- return (-1);
+ return (ERANGE);
}
/* copy group id */
diff --git a/contrib/bind/lib/irs/gethostent.c b/contrib/bind/lib/irs/gethostent.c
index 5aa46c5..586fa49 100644
--- a/contrib/bind/lib/irs/gethostent.c
+++ b/contrib/bind/lib/irs/gethostent.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: gethostent.c,v 1.28 2001/03/01 05:47:44 marka Exp $";
+static const char rcsid[] = "$Id: gethostent.c,v 1.29 2001/05/29 05:48:44 marka Exp $";
#endif
/* Imports */
@@ -215,10 +215,6 @@ endhostent_p(struct net_data *net_data) {
(*ho->minimize)(ho);
}
-#if !defined(HAS_INET6_STRUCTS) || defined(MISSING_IN6ADDR_ANY)
-static const struct in6_addr in6addr_any;
-#endif
-
#ifndef IN6_IS_ADDR_V4COMPAT
static const unsigned char in6addr_compat[12] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -299,7 +295,7 @@ getipnodebyname(const char *name, int af, int flags, int *error_num) {
char *addr_list[2];
char *aliases[1];
- he.h_name = (char *)name;
+ DE_CONST(name, he.h_name);
he.h_addr_list = addr_list;
he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6;
he.h_addr_list[1] = NULL;
@@ -379,8 +375,10 @@ getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
/*
* 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)) ||
+ if ((af == AF_INET6 &&
+ IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)src)) ||
+ (af == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)src)) ||
(af == AF_INET)) {
const char *cp = src;
@@ -405,7 +403,7 @@ getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
/*
* Lookup IPv6 address.
*/
- if (memcmp((struct in6_addr *)src, &in6addr_any, 16) == 0) {
+ if (memcmp((const struct in6_addr *)src, &in6addr_any, 16) == 0) {
*error_num = HOST_NOT_FOUND;
return (NULL);
}
@@ -491,7 +489,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
struct in_addr in4;
struct in6_addr in6;
char *buf = NULL, *cp, *cplim;
- static int bufsiz = 4095;
+ static unsigned int bufsiz = 4095;
int s, cpsize, n;
/* Set to zero. Used as loop terminators below. */
@@ -571,7 +569,7 @@ scan_interfaces(int *have_v4, int *have_v6) {
#else
cpsize = sizeof lifreq.lifr_name;
/* XXX maybe this should be a hard error? */
- if (ioctl(s, SOICGLIFADDR, (char *)&lifreq) < 0)
+ if (ioctl(s, SIOCGLIFADDR, (char *)&lifreq) < 0)
continue;
#endif
switch (lifreq.lifr_addr.ss_family) {
@@ -816,6 +814,7 @@ fakeaddr(const char *name, int af, struct net_data *net_data) {
return (NULL);
}
pvt = net_data->ho_data;
+#ifndef __bsdi__
/*
* Unlike its forebear(inet_aton), our friendly inet_pton() is strict
* in its interpretation of its input, and it will only return "1" if
@@ -825,6 +824,15 @@ fakeaddr(const char *name, int af, struct net_data *net_data) {
* This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now.
*/
if (inet_pton(af, name, pvt->addr) != 1) {
+#else
+ /* BSDI XXX
+ * We put this back to inet_aton -- we really want the old behavior
+ * Long live 127.1...
+ */
+ if ((af != AF_INET ||
+ inet_aton(name, (struct in_addr *)pvt->addr) != 1) &&
+ inet_pton(af, name, pvt->addr) != 1) {
+#endif
RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
return (NULL);
}
diff --git a/contrib/bind/lib/irs/gethostent_r.c b/contrib/bind/lib/irs/gethostent_r.c
index dab8639..e8017ac 100644
--- a/contrib/bind/lib/irs/gethostent_r.c
+++ b/contrib/bind/lib/irs/gethostent_r.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: gethostent_r.c,v 8.5 2000/07/11 05:46:35 vixie Exp $";
+static const char rcsid[] = "$Id: gethostent_r.c,v 8.7 2001/11/01 08:02:09 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <port_before.h>
@@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: gethostent_r.c,v 8.5 2000/07/11 05:46:35 vixie
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/param.h>
@@ -39,26 +40,50 @@ 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);
+#ifdef HOST_R_SETANSWER
+ int n = 0;
+#endif
HOST_R_ERRNO;
+#ifdef HOST_R_SETANSWER
+ if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
+ *answerp = NULL;
+ else
+ *answerp = hptr;
+
+ return (n);
+#else
if (he == NULL)
return (HOST_R_BAD);
return (copy_hostent(he, hptr, HOST_R_COPY));
+#endif
}
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);
+#ifdef HOST_R_SETANSWER
+ int n = 0;
+#endif
HOST_R_ERRNO;
+#ifdef HOST_R_SETANSWER
+ if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
+ *answerp = NULL;
+ else
+ *answerp = hptr;
+
+ return (n);
+#else
if (he == NULL)
return (HOST_R_BAD);
return (copy_hostent(he, hptr, HOST_R_COPY));
+#endif
}
/*
@@ -70,13 +95,25 @@ gethostbyaddr_r(const char *addr, int len, int type,
HOST_R_RETURN
gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
struct hostent *he = gethostent();
+#ifdef HOST_R_SETANSWER
+ int n = 0;
+#endif
HOST_R_ERRNO;
+#ifdef HOST_R_SETANSWER
+ if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
+ *answerp = NULL;
+ else
+ *answerp = hptr;
+
+ return (n);
+#else
if (he == NULL)
return (HOST_R_BAD);
return (copy_hostent(he, hptr, HOST_R_COPY));
+#endif
}
HOST_R_SET_RETURN
@@ -96,7 +133,7 @@ HOST_R_END_RETURN
#ifdef HOST_R_ENT_ARGS
endhostent_r(HOST_R_ENT_ARGS)
#else
-endhostent_r()
+endhostent_r(void)
#endif
{
endhostent();
@@ -222,6 +259,6 @@ copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
}
#endif /* !HOSTENT_DATA */
#else /* HOST_R_RETURN */
- static int gethostent_r_unknown_systemm = 0;
+ static int gethostent_r_unknown_system = 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
index 9f186f3..0e86cc1 100644
--- a/contrib/bind/lib/irs/getnameinfo.c
+++ b/contrib/bind/lib/irs/getnameinfo.c
@@ -1,8 +1,6 @@
/*
* 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().
*/
/*
@@ -50,14 +48,10 @@
#include <netdb.h>
#include <resolv.h>
#include <string.h>
+#include <stddef.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}.
@@ -66,30 +60,30 @@
static struct afd {
int a_af;
int a_addrlen;
- int a_socklen;
+ size_t a_socklen;
int a_off;
} afdl [] = {
/* first entry is linked last... */
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
- 4 /*XXX*/},
+ offsetof(struct sockaddr_in, sin_addr)},
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
- 8 /*XXX*/},
- {0, 0, 0},
+ offsetof(struct sockaddr_in6, sin6_addr)},
+ {0, 0, 0, 0},
};
struct sockinet {
+#ifdef HAVE_SA_LEN
u_char si_len;
+#endif
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
+static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
+ size_t, int));
+#ifdef HAVE_SIN6_SCOPE_ID
+static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
+#endif
int
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
@@ -106,82 +100,60 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
struct hostent *hp;
u_short port;
#ifdef HAVE_SA_LEN
- int len;
+ size_t len;
#endif
int family, i;
- char *addr, *p;
+ const char *addr;
+ char *p;
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;
- }
+ char numserv[512];
+ char numaddr[512];
if (sa == NULL)
- return ENI_NOSOCKET;
+ return EAI_FAIL;
#ifdef HAVE_SA_LEN
len = sa->sa_len;
- if (len != salen) return ENI_SALEN;
+ if (len != salen) return EAI_FAIL;
#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;
-
+ return EAI_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 (salen != afd->a_socklen) return EAI_FAIL;
+
+ port = ((const struct sockinet *)sa)->si_port; /* network byte order */
+ addr = (const char *)sa + afd->a_off;
if (serv == NULL || servlen == 0) {
- /* what we should do? */
+ /*
+ * rfc2553bis says that serv == NULL or servlen == 0 means that
+ * the caller does not want the result.
+ */
} else if (flags & NI_NUMERICSERV) {
- snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
+ sprintf(numserv, "%d", ntohs(port));
if (strlen(numserv) > servlen)
- return ENI_MEMORY;
+ return EAI_MEMORY;
strcpy(serv, numserv);
} else {
sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
if (sp) {
if (strlen(sp->s_name) + 1 > servlen)
- return ENI_MEMORY;
+ return EAI_MEMORY;
strcpy(serv, sp->s_name);
} else
- return ENI_NOSERVNAME;
+ return EAI_NONAME;
}
switch (sa->sa_family) {
case AF_INET:
- if (ntohl(*(u_long *)addr) >> IN_CLASSA_NSHIFT == 0)
+ if (ntohl(*(const u_long *)addr) >> IN_CLASSA_NSHIFT == 0)
flags |= NI_NUMERICHOST;
break;
case AF_INET6:
@@ -191,14 +163,12 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
break;
}
if (host == NULL || hostlen == 0) {
- /* what should we do? */
+ /*
+ * rfc2553bis says that host == NULL or hostlen == 0 means that
+ * the caller does not want the result.
+ */
} else if (flags & NI_NUMERICHOST) {
- if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
- == NULL)
- return ENI_SYSTEM;
- if (strlen(numaddr) + 1 > hostlen)
- return ENI_MEMORY;
- strcpy(host, numaddr);
+ goto numeric;
} else {
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
@@ -208,18 +178,130 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
if (p) *p = '\0';
}
if (strlen(hp->h_name) + 1 > hostlen)
- return ENI_MEMORY;
+ return EAI_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) + 1 > hostlen)
- return ENI_MEMORY;
- strcpy(host, numaddr);
+ return EAI_NONAME;
+ numeric:
+ switch(afd->a_af) {
+ case AF_INET6:
+ {
+ int error;
+
+ if ((error = ip6_parsenumeric(sa, addr, host,
+ hostlen,
+ flags)) != 0)
+ return(error);
+ break;
+ }
+
+ default:
+ if (inet_ntop(afd->a_af, addr, numaddr,
+ sizeof(numaddr)) == NULL)
+ return EAI_NONAME;
+ if (strlen(numaddr) + 1 > hostlen)
+ return EAI_MEMORY;
+ strcpy(host, numaddr);
+ }
+ }
+ }
+ return(0);
+}
+
+static int
+ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host,
+ size_t hostlen, int flags)
+{
+ size_t numaddrlen;
+ char numaddr[512];
+
+#ifndef HAVE_SIN6_SCOPE_ID
+ UNUSED(sa);
+ UNUSED(flags);
+#endif
+
+ if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ return EAI_SYSTEM;
+
+ numaddrlen = strlen(numaddr);
+ if (numaddrlen + 1 > hostlen) /* don't forget terminator */
+ return EAI_MEMORY;
+ strcpy(host, numaddr);
+
+#ifdef HAVE_SIN6_SCOPE_ID
+ if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
+ char scopebuf[MAXHOSTNAMELEN]; /* XXX */
+ int scopelen;
+
+ /* ip6_sa2str never fails */
+ scopelen = ip6_sa2str((const struct sockaddr_in6 *)sa,
+ scopebuf, sizeof(scopebuf), flags);
+
+ if (scopelen + 1 + numaddrlen + 1 > hostlen)
+ return EAI_MEMORY;
+
+ /* construct <numeric-addr><delim><scopeid> */
+ memcpy(host + numaddrlen + 1, scopebuf,
+ scopelen);
+ host[numaddrlen] = SCOPE_DELIMITER;
+ host[numaddrlen + 1 + scopelen] = '\0';
+ }
+#endif
+
+ return 0;
+}
+
+#ifdef HAVE_SIN6_SCOPE_ID
+/* ARGSUSED */
+static int
+ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf,
+ size_t bufsiz, int flags)
+{
+#ifdef USE_IFNAMELINKID
+ unsigned int ifindex = (unsigned int)sa6->sin6_scope_id;
+ const struct in6_addr *a6 = &sa6->sin6_addr;
+#endif
+ char tmp[64];
+
+#ifdef NI_NUMERICSCOPE
+ if (flags & NI_NUMERICSCOPE) {
+ sprintf(tmp, "%u", sa6->sin6_scope_id);
+ if (bufsiz != 0) {
+ strncpy(buf, tmp, bufsiz - 1);
+ buf[bufsiz - 1] = '\0';
+ }
+ return(strlen(tmp));
+ }
+#endif
+
+#ifdef USE_IFNAMELINKID
+ /*
+ * For a link-local address, convert the index to an interface
+ * name, assuming a one-to-one mapping between links and interfaces.
+ * Note, however, that this assumption is stronger than the
+ * specification of the scoped address architecture; the
+ * specficication says that more than one interfaces can belong to
+ * a single link.
+ */
+
+ /* if_indextoname() does not take buffer size. not a good api... */
+ if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) &&
+ bufsiz >= IF_NAMESIZE) {
+ char *p = if_indextoname(ifindex, buf);
+ if (p) {
+ return(strlen(p));
}
}
- return SUCCESS;
+#endif
+
+ /* last resort */
+ sprintf(tmp, "%u", sa6->sin6_scope_id);
+ if (bufsiz != 0) {
+ strncpy(buf, tmp, bufsiz - 1);
+ buf[bufsiz - 1] = '\0';
+ }
+ return(strlen(tmp));
}
+#endif
diff --git a/contrib/bind/lib/irs/getnetent.c b/contrib/bind/lib/irs/getnetent.c
index 52aebe3..49810b7 100644
--- a/contrib/bind/lib/irs/getnetent.c
+++ b/contrib/bind/lib/irs/getnetent.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: getnetent.c,v 1.18 2000/12/23 08:14:53 vixie Exp $";
+static const char rcsid[] = "$Id: getnetent.c,v 1.19 2001/05/29 05:48:47 marka Exp $";
#endif
/* Imports */
@@ -259,10 +259,11 @@ fakeaddr(const char *name, int af, struct net_data *net_data) {
RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
return (NULL);
}
- if (!isascii(name[0]) || !isdigit(name[0]))
+ if (!isascii((unsigned char)(name[0])) ||
+ !isdigit((unsigned char)(name[0])))
return (NULL);
for (cp = name; *cp; ++cp)
- if (!isascii(*cp) || (!isdigit(*cp) && *cp != '.'))
+ if (!isascii(*cp) || (!isdigit((unsigned char)*cp) && *cp != '.'))
return (NULL);
if (*--cp == '.')
return (NULL);
diff --git a/contrib/bind/lib/irs/getnetent_r.c b/contrib/bind/lib/irs/getnetent_r.c
index b78b45a..1472eb5 100644
--- a/contrib/bind/lib/irs/getnetent_r.c
+++ b/contrib/bind/lib/irs/getnetent_r.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: getnetent_r.c,v 8.6 2001/11/01 08:02:11 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <port_before.h>
@@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: getnetent_r.c,v 8.4 1999/01/18 07:46:52 vixie
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/param.h>
@@ -39,11 +40,22 @@ 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);
+#ifdef NET_R_SETANSWER
+ int n = 0;
+ if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = ne;
+ if (ne == NULL)
+ *h_errnop = h_errno;
+ return (n);
+#else
if (ne == NULL)
return (NET_R_BAD);
return (copy_netent(ne, nptr, NET_R_COPY));
+#endif
}
#ifndef GETNETBYADDR_ADDR_T
@@ -52,11 +64,23 @@ getnetbyname_r(const char *name, struct netent *nptr, NET_R_ARGS) {
NET_R_RETURN
getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_ARGS) {
struct netent *ne = getnetbyaddr(addr, type);
+#ifdef NET_R_SETANSWER
+ int n = 0;
+
+ if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = ne;
+ if (ne == NULL)
+ *h_errnop = h_errno;
+ return (n);
+#else
if (ne == NULL)
return (NET_R_BAD);
return (copy_netent(ne, nptr, NET_R_COPY));
+#endif
}
/*
@@ -68,11 +92,23 @@ getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_AR
NET_R_RETURN
getnetent_r(struct netent *nptr, NET_R_ARGS) {
struct netent *ne = getnetent();
+#ifdef NET_R_SETANSWER
+ int n = 0;
+
+ if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = ne;
+ if (ne == NULL)
+ *h_errnop = h_errno;
+ return (n);
+#else
if (ne == NULL)
return (NET_R_BAD);
return (copy_netent(ne, nptr, NET_R_COPY));
+#endif
}
NET_R_SET_RETURN
@@ -117,7 +153,7 @@ copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
len += strlen(ne->n_name) + 1;
len += numptr * sizeof(char*);
- if (len > buflen) {
+ if (len > (int)buflen) {
errno = ERANGE;
return (NET_R_BAD);
}
@@ -186,6 +222,6 @@ copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
}
#endif /* !NETENT_DATA */
#else /* NET_R_RETURN */
- static int getnetent_r_unknown_systemm = 0;
+ static int getnetent_r_unknown_system = 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 8c5f5f8..e966ea6 100644
--- a/contrib/bind/lib/irs/getnetgrent.c
+++ b/contrib/bind/lib/irs/getnetgrent.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: getnetgrent.c,v 1.14 1999/10/07 20:44:03 vixie Exp $";
+static const char rcsid[] = "$Id: getnetgrent.c,v 1.15 2001/05/29 05:48:49 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -70,7 +70,7 @@ innetgr(const char *netgroup, const char *host,
}
int
-getnetgrent(char **host, char **user, char **domain) {
+getnetgrent(const char **host, const char **user, const char **domain) {
struct net_data *net_data = init();
return (getnetgrent_p(host, user, domain, net_data));
@@ -109,7 +109,7 @@ innetgr_p(const char *netgroup, const char *host,
}
int
-getnetgrent_p(char **host, char **user, char **domain,
+getnetgrent_p(const char **host, const char **user, const char **domain,
struct net_data *net_data ) {
struct irs_ng *ng;
diff --git a/contrib/bind/lib/irs/getnetgrent_r.c b/contrib/bind/lib/irs/getnetgrent_r.c
index e0c366c..adae817 100644
--- a/contrib/bind/lib/irs/getnetgrent_r.c
+++ b/contrib/bind/lib/irs/getnetgrent_r.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.6 2001/11/01 08:02:12 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <port_before.h>
@@ -26,15 +26,18 @@ static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.4 1999/01/18 07:46:52 vixi
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
+#include <netgroup.h>
+#include <stdlib.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);
+copy_protoent(char **, char **, char **, const char *, const char *,
+ const char *, NGR_R_COPY_ARGS);
NGR_R_RETURN
innetgr_r(const char *netgroup, const char *host, const char *user,
@@ -51,7 +54,7 @@ innetgr_r(const char *netgroup, const char *host, const char *user,
NGR_R_RETURN
getnetgrent_r(char **machinep, char **userp, char **domainp, NGR_R_ARGS) {
- char *mp, *up, *dp;
+ const char *mp, *up, *dp;
int res = getnetgrent(&mp, &up, &dp);
if (res != 1)
@@ -69,14 +72,27 @@ setnetgrent_r(const char *netgroup)
#endif
{
setnetgrent(netgroup);
+#ifdef NGR_R_PRIVATE
+ *buf = NULL;
+#endif
#ifdef NGR_R_SET_RESULT
return (NGR_R_SET_RESULT);
#endif
}
NGR_R_END_RETURN
-endnetgrent_r(NGR_R_ENT_ARGS) {
+#ifdef NGR_R_ENT_ARGS
+endnetgrent_r(NGR_R_ENT_ARGS)
+#else
+endnetgrent_r(void)
+#endif
+{
endnetgrent();
+#ifdef NGR_R_PRIVATE
+ if (*buf != NULL)
+ free(*buf);
+ *buf = NULL;
+#endif
NGR_R_END_RESULT(NGR_R_OK);
}
@@ -84,9 +100,10 @@ endnetgrent_r(NGR_R_ENT_ARGS) {
static int
copy_protoent(char **machinep, char **userp, char **domainp,
- char *mp, char *up, char *dp, NGR_R_COPY_ARGS) {
+ const char *mp, const char *up, const char *dp,
+ NGR_R_COPY_ARGS) {
char *cp;
- int i, n;
+ int n;
int len;
/* Find out the amount of space required to store the answer. */
@@ -95,12 +112,20 @@ copy_protoent(char **machinep, char **userp, char **domainp,
if (up != NULL) len += strlen(up) + 1;
if (dp != NULL) len += strlen(dp) + 1;
- if (len > buflen) {
+#ifdef NGR_R_PRIVATE
+ free(*buf);
+ *buf = malloc(len);
+ if (*buf == NULL)
+ return(NGR_R_BAD);
+ cp = *buf;
+#else
+ if (len > (int)buflen) {
errno = ERANGE;
return (NGR_R_BAD);
}
-
cp = buf;
+#endif
+
if (mp != NULL) {
n = strlen(mp) + 1;
diff --git a/contrib/bind/lib/irs/getprotoent.c b/contrib/bind/lib/irs/getprotoent.c
index e3bfc37..724b0ad 100644
--- a/contrib/bind/lib/irs/getprotoent.c
+++ b/contrib/bind/lib/irs/getprotoent.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: getprotoent.c,v 1.15 1999/10/13 16:39:31 vixie Exp $";
+static const char rcsid[] = "$Id: getprotoent.c,v 1.16 2001/11/01 07:34:33 marka Exp $";
#endif
/* Imports */
@@ -33,6 +33,7 @@ static const char rcsid[] = "$Id: getprotoent.c,v 1.15 1999/10/13 16:39:31 vixie
#include <errno.h>
#include <resolv.h>
#include <stdio.h>
+#include <string.h>
#include <irs.h>
diff --git a/contrib/bind/lib/irs/getprotoent_r.c b/contrib/bind/lib/irs/getprotoent_r.c
index e5c54d7..fc3b17e 100644
--- a/contrib/bind/lib/irs/getprotoent_r.c
+++ b/contrib/bind/lib/irs/getprotoent_r.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: getprotoent_r.c,v 8.6 2001/11/01 08:02:14 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <port_before.h>
@@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: getprotoent_r.c,v 8.4 1999/01/18 07:46:52 vixi
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <port_after.h>
@@ -38,21 +39,41 @@ 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);
+#ifdef PROTO_R_SETANSWER
+ int n = 0;
+ if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = pptr;
+
+ return (n);
+#else
if (pe == NULL)
return (PROTO_R_BAD);
return (copy_protoent(pe, pptr, PROTO_R_COPY));
+#endif
}
PROTO_R_RETURN
getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) {
struct protoent *pe = getprotobynumber(proto);
+#ifdef PROTO_R_SETANSWER
+ int n = 0;
+ if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = pptr;
+
+ return (n);
+#else
if (pe == NULL)
return (PROTO_R_BAD);
return (copy_protoent(pe, pptr, PROTO_R_COPY));
+#endif
}
/*
@@ -64,11 +85,21 @@ getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) {
PROTO_R_RETURN
getprotoent_r(struct protoent *pptr, PROTO_R_ARGS) {
struct protoent *pe = getprotoent();
+#ifdef PROTO_R_SETANSWER
+ int n = 0;
+ if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = pptr;
+
+ return (n);
+#else
if (pe == NULL)
return (PROTO_R_BAD);
return (copy_protoent(pe, pptr, PROTO_R_COPY));
+#endif
}
PROTO_R_SET_RETURN
@@ -113,7 +144,7 @@ copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
len += strlen(pe->p_name) + 1;
len += numptr * sizeof(char*);
- if (len > buflen) {
+ if (len > (int)buflen) {
errno = ERANGE;
return (PROTO_R_BAD);
}
@@ -180,6 +211,6 @@ copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
}
#endif /* PROTOENT_DATA */
#else /* PROTO_R_RETURN */
- static int getprotoent_r_unknown_systemm = 0;
+ static int getprotoent_r_unknown_system = 0;
#endif /* PROTO_R_RETURN */
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
diff --git a/contrib/bind/lib/irs/getpwent_r.c b/contrib/bind/lib/irs/getpwent_r.c
index 761fa45..ee2d8a7 100644
--- a/contrib/bind/lib/irs/getpwent_r.c
+++ b/contrib/bind/lib/irs/getpwent_r.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: getpwent_r.c,v 8.6 2001/11/01 08:02:15 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <port_before.h>
@@ -27,7 +27,19 @@ static const char rcsid[] = "$Id: getpwent_r.c,v 8.3 1999/01/08 19:24:33 vixie E
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
+#if (defined(POSIX_GETPWNAM_R) || defined(POSIX_GETPWUID_R))
+#if defined(_POSIX_PTHREAD_SEMANTICS)
+ /* turn off solaris remapping in <grp.h> */
+#undef _POSIX_PTHREAD_SEMANTICS
#include <pwd.h>
+#define _POSIX_PTHREAD_SEMANTICS 1
+#else
+#define _UNIX95 1
+#include <pwd.h>
+#endif
+#else
+#include <pwd.h>
+#endif
#include <port_after.h>
#ifdef PASS_R_RETURN
@@ -50,7 +62,7 @@ getpwnam_r(const char *login, struct passwd *pwptr,
if (pw == NULL) {
*result = NULL;
- return (-1);
+ return (0);
}
res = copy_passwd(pw, pwptr, buf, buflen);
@@ -87,7 +99,7 @@ getpwuid_r(uid_t uid, struct passwd *pwptr,
if (pw == NULL) {
*result = NULL;
- return (-1);
+ return (0);
}
res = copy_passwd(pw, pwptr, buf, buflen);
@@ -142,7 +154,12 @@ setpassent_r(int stayopen)
}
PASS_R_SET_RETURN
-setpwent_r(PASS_R_ENT_ARGS) {
+#ifdef PASS_R_ENT_ARGS
+setpwent_r(PASS_R_ENT_ARGS)
+#else
+setpwent_r(void)
+#endif
+{
setpwent();
#ifdef PASS_R_SET_RESULT
@@ -151,7 +168,12 @@ setpwent_r(PASS_R_ENT_ARGS) {
}
PASS_R_END_RETURN
-endpwent_r(PASS_R_ENT_ARGS) {
+#ifdef PASS_R_ENT_ARGS
+endpwent_r(PASS_R_ENT_ARGS)
+#else
+endpwent_r(void)
+#endif
+{
endpwent();
PASS_R_END_RESULT(PASS_R_OK);
@@ -177,8 +199,8 @@ fgetpwent_r(FILE *f, struct passwd *pwptr, PASS_R_COPY_ARGS) {
static int
copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) {
char *cp;
- int i, n;
- int numptr, len;
+ int n;
+ int len;
/* Find out the amount of space required to store the answer. */
len = strlen(pw->pw_name) + 1;
@@ -192,7 +214,7 @@ copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) {
if (len > buflen) {
errno = ERANGE;
- return (-1);
+ return (ERANGE);
}
/* copy fixed atomic values*/
@@ -248,6 +270,6 @@ copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) {
return (0);
}
#else /* PASS_R_RETURN */
- static int getpwent_r_unknown_systemm = 0;
+ static int getpwent_r_unknown_system = 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 d2b8b50..d63ae1d 100644
--- a/contrib/bind/lib/irs/getservent.c
+++ b/contrib/bind/lib/irs/getservent.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: getservent.c,v 1.16 1999/10/13 16:39:31 vixie Exp $";
+static const char rcsid[] = "$Id: getservent.c,v 1.17 2001/11/01 07:33:16 marka Exp $";
#endif
/* Imports */
@@ -33,6 +33,7 @@ static const char rcsid[] = "$Id: getservent.c,v 1.16 1999/10/13 16:39:31 vixie
#include <errno.h>
#include <resolv.h>
#include <stdio.h>
+#include <string.h>
#include <irs.h>
diff --git a/contrib/bind/lib/irs/getservent_r.c b/contrib/bind/lib/irs/getservent_r.c
index 4da9dc2..b4897ae 100644
--- a/contrib/bind/lib/irs/getservent_r.c
+++ b/contrib/bind/lib/irs/getservent_r.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: getservent_r.c,v 8.5 2001/11/01 08:02:16 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include <port_before.h>
@@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: getservent_r.c,v 8.3 1999/01/08 19:24:36 vixie
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/param.h>
@@ -40,22 +41,42 @@ SERV_R_RETURN
getservbyname_r(const char *name, const char *proto,
struct servent *sptr, SERV_R_ARGS) {
struct servent *se = getservbyname(name, proto);
+#ifdef SERV_R_SETANSWER
+ int n = 0;
+
+ if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = sptr;
+ return (n);
+#else
if (se == NULL)
return (SERV_R_BAD);
return (copy_servent(se, sptr, SERV_R_COPY));
+#endif
}
SERV_R_RETURN
getservbyport_r(int port, const char *proto,
struct servent *sptr, SERV_R_ARGS) {
struct servent *se = getservbyport(port, proto);
+#ifdef SERV_R_SETANSWER
+ int n = 0;
+
+ if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = sptr;
+ return (n);
+#else
if (se == NULL)
return (SERV_R_BAD);
return (copy_servent(se, sptr, SERV_R_COPY));
+#endif
}
/*
@@ -67,11 +88,21 @@ getservbyport_r(int port, const char *proto,
SERV_R_RETURN
getservent_r(struct servent *sptr, SERV_R_ARGS) {
struct servent *se = getservent();
+#ifdef SERV_R_SETANSWER
+ int n = 0;
+
+ if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
+ *answerp = NULL;
+ else
+ *answerp = sptr;
+ return (n);
+#else
if (se == NULL)
return (SERV_R_BAD);
return (copy_servent(se, sptr, SERV_R_COPY));
+#endif
}
SERV_R_SET_RETURN
@@ -119,7 +150,7 @@ copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
len += strlen(se->s_proto) + 1;
len += numptr * sizeof(char*);
- if (len > buflen) {
+ if (len > (int)buflen) {
errno = ERANGE;
return (SERV_R_BAD);
}
@@ -201,6 +232,6 @@ copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
}
#endif /* !SERVENT_DATA */
#else /*SERV_R_RETURN */
- static int getservent_r_unknown_systemm = 0;
+ static int getservent_r_unknown_system = 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 40826eb..2b08911 100644
--- a/contrib/bind/lib/irs/hesiod.c
+++ b/contrib/bind/lib/irs/hesiod.c
@@ -1,5 +1,5 @@
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie Exp $";
+static const char rcsid[] = "$Id: hesiod.c,v 1.22 2001/05/29 05:48:55 marka Exp $";
#endif
/*
@@ -259,6 +259,8 @@ void
hesiod_free_list(void *context, char **list) {
char **p;
+ UNUSED(context);
+
for (p = list; *p; p++)
free(*p);
free(list);
diff --git a/contrib/bind/lib/irs/irp.c b/contrib/bind/lib/irs/irp.c
index a6c8f4f..fa28b3f 100644
--- a/contrib/bind/lib/irs/irp.c
+++ b/contrib/bind/lib/irs/irp.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: irp.c,v 8.6 2000/02/04 08:28:33 vixie Exp $";
+static const char rcsid[] = "$Id: irp.c,v 8.8 2001/09/25 04:50:29 marka Exp $";
#endif
/* Imports */
@@ -84,6 +84,8 @@ irs_irp_acc(const char *options) {
struct irs_acc *acc;
struct irp_p *irp;
+ UNUSED(options);
+
if (!(acc = memget(sizeof *acc))) {
errno = ENOMEM;
return (NULL);
@@ -387,9 +389,9 @@ irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen) {
code = 0;
} else if (text != NULL && textlen > 0) {
p = line;
- while (isspace(*p)) p++;
- while (isdigit(*p)) p++;
- while (isspace(*p)) p++;
+ while (isspace((unsigned char)*p)) p++;
+ while (isdigit((unsigned char)*p)) p++;
+ while (isspace((unsigned char)*p)) p++;
strncpy(text, p, textlen - 1);
p[textlen - 1] = '\0';
}
@@ -537,7 +539,8 @@ irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) {
va_start(ap, fmt);
todo = vsprintf(buffer, fmt, ap);
- if (todo > sizeof buffer - 2) {
+ va_end(ap);
+ if (todo > (int)sizeof(buffer) - 3) {
syslog(LOG_CRIT, "memory overrun in irs_irp_send_command()");
exit(1);
}
@@ -559,7 +562,6 @@ irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) {
}
todo -= i;
}
- va_end(ap);
return (0);
}
diff --git a/contrib/bind/lib/irs/irp_gr.c b/contrib/bind/lib/irs/irp_gr.c
index 4e2a28c..c235e19 100644
--- a/contrib/bind/lib/irs/irp_gr.c
+++ b/contrib/bind/lib/irs/irp_gr.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: irp_gr.c,v 8.3 2001/05/29 05:48:57 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* extern */
@@ -285,7 +285,7 @@ gr_bygid(struct irs_gr *this, gid_t gid) {
int code;
char text[256];
- if (gr->gr_name != NULL && gr->gr_gid == gid) {
+ if (gr->gr_name != NULL && (gid_t)gr->gr_gid == gid) {
return (gr);
}
@@ -397,6 +397,9 @@ free_group(struct group *gr) {
for (p = gr->gr_mem ; p != NULL && *p != NULL ; p++)
free(*p);
+ if (gr->gr_mem)
+ free(gr->gr_mem);
+
if (p != NULL)
free(p);
}
diff --git a/contrib/bind/lib/irs/irp_ho.c b/contrib/bind/lib/irs/irp_ho.c
index 7bfd0e2..2124017 100644
--- a/contrib/bind/lib/irs/irp_ho.c
+++ b/contrib/bind/lib/irs/irp_ho.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: irp_ho.c,v 8.3 2001/05/29 05:48:59 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -79,7 +79,8 @@ static void ho_rewind(struct irs_ho *this);
static void ho_minimize(struct irs_ho *this);
static void free_host(struct hostent *ho);
-
+static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
+ const struct addrinfo *pai);
/* Public. */
@@ -121,6 +122,7 @@ irs_irp_ho(struct irs_acc *this) {
ho->next = ho_next;
ho->rewind = ho_rewind;
ho->minimize = ho_minimize;
+ ho->addrinfo = ho_addrinfo;
return (ho);
}
@@ -416,3 +418,12 @@ free_host(struct hostent *ho) {
}
}
+/* dummy */
+static struct addrinfo *
+ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
+{
+ UNUSED(this);
+ UNUSED(name);
+ UNUSED(pai);
+ return(NULL);
+}
diff --git a/contrib/bind/lib/irs/irp_ng.c b/contrib/bind/lib/irs/irp_ng.c
index e96f66c..b3cf0f4 100644
--- a/contrib/bind/lib/irs/irp_ng.c
+++ b/contrib/bind/lib/irs/irp_ng.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: irp_ng.c,v 8.2 1999/10/13 16:39:31 vixie Exp $";
+static const char rcsid[] = "$Id: irp_ng.c,v 8.3 2001/05/29 05:49:00 marka Exp $";
#endif
/* Imports */
@@ -52,7 +52,8 @@ struct pvt {
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_next(struct irs_ng *, const char **, const char **,
+ const char **);
static int ng_test(struct irs_ng *, const char *,
const char *, const char *,
const char *);
@@ -158,7 +159,8 @@ ng_rewind(struct irs_ng *this, const char *group) {
/*
- * int ng_next(struct irs_ng *this, char **host, char **user, char **domain)
+ * int ng_next(struct irs_ng *this, const char **host, const char **user,
+ * const char **domain)
*
* Notes:
*
@@ -167,7 +169,9 @@ ng_rewind(struct irs_ng *this, const char *group) {
*/
static int
-ng_next(struct irs_ng *this, char **host, char **user, char **domain) {
+ng_next(struct irs_ng *this, const char **host, const char **user,
+ const char **domain)
+{
struct pvt *pvt = (struct pvt *)this->private;
int code;
char *body = NULL;
@@ -224,6 +228,8 @@ ng_test(struct irs_ng *this, const char *name,
char text[256];
int rval = 0;
+ UNUSED(name);
+
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
return (0);
}
diff --git a/contrib/bind/lib/irs/irp_p.h b/contrib/bind/lib/irs/irp_p.h
index adf8174..0f68b28 100644
--- a/contrib/bind/lib/irs/irp_p.h
+++ b/contrib/bind/lib/irs/irp_p.h
@@ -16,7 +16,7 @@
*/
/*
- * $Id: irp_p.h,v 8.1 1999/01/18 07:46:54 vixie Exp $
+ * $Id: irp_p.h,v 8.2 2001/08/10 02:40:52 marka Exp $
*/
#ifndef _IRP_P_H_INCLUDED
@@ -53,7 +53,7 @@ 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, ...);
+int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
extern int irp_log_errors;
diff --git a/contrib/bind/lib/irs/irp_pw.c b/contrib/bind/lib/irs/irp_pw.c
index f23cb73..b659caa 100644
--- a/contrib/bind/lib/irs/irp_pw.c
+++ b/contrib/bind/lib/irs/irp_pw.c
@@ -16,7 +16,7 @@
*/
#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 $";
+static const char rcsid[] = "$Id: irp_pw.c,v 8.2 2001/11/01 07:29:26 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Extern */
@@ -340,8 +340,10 @@ free_passwd(struct passwd *pw) {
if (pw->pw_passwd != NULL)
free(pw->pw_passwd);
+#ifdef HAVE_PW_CLASS
if (pw->pw_class != NULL)
free(pw->pw_class);
+#endif
if (pw->pw_gecos != NULL)
free(pw->pw_gecos);
diff --git a/contrib/bind/lib/irs/irpmarshall.c b/contrib/bind/lib/irs/irpmarshall.c
index 240bb08..6331ce1 100644
--- a/contrib/bind/lib/irs/irpmarshall.c
+++ b/contrib/bind/lib/irs/irpmarshall.c
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: irpmarshall.c,v 8.6 2000/11/13 05:08:08 vixie Exp $";
+static const char rcsid[] = "$Id: irpmarshall.c,v 8.7 2001/05/29 05:49:01 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#if 0
@@ -139,7 +139,7 @@ irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len) {
char pwGid[24];
char pwChange[24];
char pwExpire[24];
- char *pwClass;
+ const char *pwClass;
const char *fieldsep = COLONSTR;
if (pw == NULL || len == NULL) {
@@ -1228,8 +1228,8 @@ irp_marshall_ng(const char *host, const char *user, const char *domain,
/*
- * int irp_unmarshall_ng(char **host, char **user, char **domain,
- * char *buffer)
+ * int irp_unmarshall_ng(const char **host, const char **user,
+ * const char **domain, char *buffer)
*
* notes:
*
@@ -1243,20 +1243,24 @@ irp_marshall_ng(const char *host, const char *user, const char *domain,
*/
int
-irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) {
+irp_unmarshall_ng(const char **hostp, const char **userp, const char **domainp,
+ char *buffer)
+{
char *p, *q;
char fieldsep = ',';
int myerrno = EINVAL;
+ char *host, *user, *domain;
- if (user == NULL || host == NULL || domain == NULL || buffer == NULL) {
+ if (userp == NULL || hostp == NULL ||
+ domainp == NULL || buffer == NULL) {
errno = EINVAL;
return (-1);
}
- *host = *user = *domain = NULL;
+ host = user = domain = NULL;
p = buffer;
- while (isspace(*p)) {
+ while (isspace((unsigned char)*p)) {
p++;
}
if (*p != '(') {
@@ -1269,7 +1273,7 @@ irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) {
if (!*q) {
goto error;
} else if (q > p + 1) {
- *host = strndup(p, q - p);
+ host = strndup(p, q - p);
}
p = q + 1;
@@ -1282,7 +1286,7 @@ irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) {
if (!*q) {
goto error;
}
- *user = strndup(p, q - p);
+ user = strndup(p, q - p);
} else {
p++;
}
@@ -1296,17 +1300,20 @@ irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) {
if (!*q) {
goto error;
}
- *domain = strndup(p, q - p);
+ domain = strndup(p, q - p);
}
+ *hostp = host;
+ *userp = user;
+ *domainp = domain;
return (0);
error:
errno = myerrno;
- if (*host != NULL) free(*host);
- if (*user != NULL) free(*user);
- if (*domain != NULL) free(*domain);
+ if (host != NULL) free(host);
+ if (user != NULL) free(user);
+ if (domain != NULL) free(domain);
return (-1);
}
@@ -1847,7 +1854,7 @@ getfield(char **res, size_t reslen, char **ptr, char delim) {
if (*res == NULL) {
*res = strndup(*ptr, q - *ptr);
} else {
- if (q - *ptr + 1 > reslen) { /* to big for res */
+ if ((size_t)(q - *ptr + 1) > reslen) { /* to big for res */
errno = EINVAL;
return (NULL);
} else {
diff --git a/contrib/bind/lib/irs/irs_data.c b/contrib/bind/lib/irs/irs_data.c
index 8446c6b..000da0c 100644
--- a/contrib/bind/lib/irs/irs_data.c
+++ b/contrib/bind/lib/irs/irs_data.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: irs_data.c,v 1.15 2000/12/23 08:14:54 vixie Exp $";
+static const char rcsid[] = "$Id: irs_data.c,v 1.19 2001/08/20 07:08:41 marka Exp $";
#endif
#include "port_before.h"
@@ -30,6 +30,7 @@ static const char rcsid[] = "$Id: irs_data.c,v 1.15 2000/12/23 08:14:54 vixie Ex
#include <resolv.h>
#include <stdio.h>
+#include <string.h>
#include <isc/memcluster.h>
#ifdef DO_PTHREADS
@@ -67,7 +68,7 @@ void
net_data_destroy(void *p) {
struct net_data *net_data = p;
- res_nclose(net_data->res);
+ res_ndestroy(net_data->res);
if (net_data->gr != NULL) {
(*net_data->gr->close)(net_data->gr);
net_data->gr = NULL;
@@ -152,7 +153,8 @@ net_data_create(const char *conf_file) {
if (net_data->res == NULL)
return (NULL);
- if (res_ninit(net_data->res) == -1)
+ if ((net_data->res->options & RES_INIT) == 0 &&
+ res_ninit(net_data->res) == -1)
return (NULL);
return (net_data);
@@ -165,6 +167,7 @@ net_data_minimize(struct net_data *net_data) {
res_nclose(net_data->res);
}
+#ifdef _REENTRANT
struct __res_state *
__res_state(void) {
/* NULL param here means use the default config file. */
@@ -174,6 +177,7 @@ __res_state(void) {
return (&_res);
}
+#endif
int *
__h_errno(void) {
diff --git a/contrib/bind/lib/irs/lcl.c b/contrib/bind/lib/irs/lcl.c
index 16e167f..ed9e6b4 100644
--- a/contrib/bind/lib/irs/lcl.c
+++ b/contrib/bind/lib/irs/lcl.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: lcl.c,v 1.16 2000/02/28 07:52:16 vixie Exp $";
+static const char rcsid[] = "$Id: lcl.c,v 1.17 2001/05/29 05:49:02 marka Exp $";
#endif
/* Imports */
@@ -55,6 +55,8 @@ irs_lcl_acc(const char *options) {
struct irs_acc *acc;
struct lcl_p *lcl;
+ UNUSED(options);
+
if (!(acc = memget(sizeof *acc))) {
errno = ENOMEM;
return (NULL);
diff --git a/contrib/bind/lib/irs/lcl_gr.c b/contrib/bind/lib/irs/lcl_gr.c
index acb85ee..7536c27 100644
--- a/contrib/bind/lib/irs/lcl_gr.c
+++ b/contrib/bind/lib/irs/lcl_gr.c
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_gr.c,v 1.25 1999/10/13 17:11:19 vixie Exp $";
+static const char rcsid[] = "$Id: lcl_gr.c,v 1.26 2001/05/29 05:49:03 marka 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 */
@@ -129,6 +129,8 @@ irs_lcl_gr(struct irs_acc *this) {
struct irs_gr *gr;
struct pvt *pvt;
+ UNUSED(this);
+
if (!(gr = memget(sizeof *gr))) {
errno = ENOMEM;
return (NULL);
@@ -313,7 +315,7 @@ grscan(struct irs_gr *this, int search, gid_t gid, const char *name) {
continue;
}
pvt->group.gr_gid = atoi(p);
- if (search && name == NULL && pvt->group.gr_gid != gid)
+ if (search && name == NULL && (gid_t)pvt->group.gr_gid != gid)
continue;
/* We want this record. */
diff --git a/contrib/bind/lib/irs/lcl_ho.c b/contrib/bind/lib/irs/lcl_ho.c
index 5939207..e9685a3 100644
--- a/contrib/bind/lib/irs/lcl_ho.c
+++ b/contrib/bind/lib/irs/lcl_ho.c
@@ -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 const char rcsid[] = "$Id: lcl_ho.c,v 1.25 1999/10/13 17:11:19 vixie Exp $";
+static const char rcsid[] = "$Id: lcl_ho.c,v 1.26 2001/05/29 05:49:04 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -83,6 +83,7 @@ static const char rcsid[] = "$Id: lcl_ho.c,v 1.25 1999/10/13 17:11:19 vixie Exp
#include "irs_p.h"
#include "dns_p.h"
+#include "lcl_p.h"
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
@@ -136,6 +137,8 @@ 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 addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
+ const struct addrinfo *pai);
static size_t ns_namelen(const char *);
static int init(struct irs_ho *this);
@@ -153,6 +156,8 @@ irs_lcl_ho(struct irs_acc *this) {
struct irs_ho *ho;
struct pvt *pvt;
+ UNUSED(this);
+
if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
@@ -174,6 +179,7 @@ irs_lcl_ho(struct irs_acc *this) {
ho->minimize = ho_minimize;
ho->res_get = ho_res_get;
ho->res_set = ho_res_set;
+ ho->addrinfo = ho_addrinfo;
return (ho);
}
@@ -257,7 +263,7 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
(!memcmp(uaddr, mapped, sizeof mapped) ||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
/* Unmap. */
- addr = (u_char *)addr + sizeof mapped;
+ addr = (const u_char *)addr + sizeof mapped;
uaddr += sizeof mapped;
af = AF_INET;
len = INADDRSZ;
@@ -479,6 +485,73 @@ ho_res_set(struct irs_ho *this, struct __res_state *res,
pvt->free_res = free_res;
}
+struct lcl_res_target {
+ struct lcl_res_target *next;
+ int family;
+};
+
+/* XXX */
+extern struct addrinfo *hostent2addrinfo __P((struct hostent *,
+ const struct addrinfo *pai));
+
+static struct addrinfo *
+ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
+{
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct hostent *hp;
+ struct lcl_res_target q, q2, *p;
+ struct addrinfo sentinel, *cur;
+
+ memset(&q, 0, sizeof(q2));
+ memset(&q2, 0, sizeof(q2));
+ memset(&sentinel, 0, sizeof(sentinel));
+ cur = &sentinel;
+
+ switch(pai->ai_family) {
+ case AF_UNSPEC: /* INET6 then INET4 */
+ q.family = AF_INET6;
+ q.next = &q2;
+ q2.family = AF_INET;
+ break;
+ case AF_INET6:
+ q.family = AF_INET6;
+ break;
+ case AF_INET:
+ q.family = AF_INET;
+ break;
+ default:
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* ??? */
+ return(NULL);
+ }
+
+ for (p = &q; p; p = p->next) {
+ struct addrinfo *ai;
+
+ hp = (*this->byname2)(this, name, p->family);
+ if (hp == NULL) {
+ /* byname2 should've set an appropriate error */
+ continue;
+ }
+ if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
+ (hp->h_addr_list[0] == NULL)) {
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
+ continue;
+ }
+
+ ai = hostent2addrinfo(hp, pai);
+ if (ai) {
+ cur->ai_next = ai;
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ }
+ }
+
+ if (sentinel.ai_next == NULL)
+ RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
+
+ return(sentinel.ai_next);
+}
+
/* Private. */
static size_t
diff --git a/contrib/bind/lib/irs/lcl_ng.c b/contrib/bind/lib/irs/lcl_ng.c
index 03acbf6..239b63e 100644
--- a/contrib/bind/lib/irs/lcl_ng.c
+++ b/contrib/bind/lib/irs/lcl_ng.c
@@ -16,7 +16,7 @@
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: lcl_ng.c,v 1.16 1999/10/13 16:39:32 vixie Exp $";
+static const char rcsid[] = "$Id: lcl_ng.c,v 1.17 2001/05/29 05:49:05 marka Exp $";
#endif
/* Imports */
@@ -39,6 +39,7 @@ static const char rcsid[] = "$Id: lcl_ng.c,v 1.16 1999/10/13 16:39:32 vixie Exp
#include "port_after.h"
#include "irs_p.h"
+#include "lcl_p.h"
/* Definitions */
@@ -88,7 +89,8 @@ struct pvt {
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_next(struct irs_ng *, const char **,
+ const char **, const char **);
static int ng_test(struct irs_ng *, const char *,
const char *, const char *,
const char *);
@@ -104,6 +106,8 @@ struct irs_ng *
irs_lcl_ng(struct irs_acc *this) {
struct irs_ng *ng;
struct pvt *pvt;
+
+ UNUSED(this);
if (!(ng = memget(sizeof *ng))) {
errno = ENOMEM;
@@ -174,7 +178,9 @@ ng_rewind(struct irs_ng *this, const char *group) {
* Get the next netgroup off the list.
*/
static int
-ng_next(struct irs_ng *this, char **host, char **user, char **domain) {
+ng_next(struct irs_ng *this, const char **host, const char **user,
+ const char **domain)
+{
struct pvt *pvt = (struct pvt *)this->private;
if (pvt->nextgrp) {
@@ -194,7 +200,7 @@ static int
ng_test(struct irs_ng *this, const char *name,
const char *host, const char *user, const char *domain)
{
- char *ng_host, *ng_user, *ng_domain;
+ const char *ng_host, *ng_user, *ng_domain;
ng_rewind(this, name);
while (ng_next(this, &ng_host, &ng_user, &ng_domain))
@@ -350,7 +356,7 @@ parse_netgrp(struct irs_ng *this, const char *group) {
static struct linelist *
read_for_group(struct irs_ng *this, const char *group) {
struct pvt *pvt = (struct pvt *)this->private;
- char *pos, *spos, *linep, *olinep;
+ char *pos, *spos, *linep = NULL, *olinep;
int len, olen, cont;
struct linelist *lp;
char line[LINSIZ + 1];
diff --git a/contrib/bind/lib/irs/lcl_nw.c b/contrib/bind/lib/irs/lcl_nw.c
index 0d41ec4..457621b 100644
--- a/contrib/bind/lib/irs/lcl_nw.c
+++ b/contrib/bind/lib/irs/lcl_nw.c
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_nw.c,v 1.21 1999/10/15 19:49:10 vixie Exp $";
+static const char rcsid[] = "$Id: lcl_nw.c,v 1.22 2001/05/29 05:49:07 marka 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 */
@@ -122,6 +122,8 @@ irs_lcl_nw(struct irs_acc *this) {
struct irs_nw *nw;
struct pvt *pvt;
+ UNUSED(this);
+
if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
diff --git a/contrib/bind/lib/irs/lcl_pw.c b/contrib/bind/lib/irs/lcl_pw.c
index 2655677..31c1ed0 100644
--- a/contrib/bind/lib/irs/lcl_pw.c
+++ b/contrib/bind/lib/irs/lcl_pw.c
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_pw.c,v 1.19 1999/01/18 07:46:57 vixie Exp $";
+static const char rcsid[] = "$Id: lcl_pw.c,v 1.20 2001/05/29 05:49:08 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Extern */
@@ -119,6 +119,8 @@ struct irs_pw *
irs_lcl_pw(struct irs_acc *this) {
struct irs_pw *pw;
struct pvt *pvt;
+
+ UNUSED(this);
if (!(pw = memget(sizeof *pw))) {
errno = ENOMEM;
diff --git a/contrib/bind/lib/irs/lcl_sv.c b/contrib/bind/lib/irs/lcl_sv.c
index 7e5bec9..d94366b 100644
--- a/contrib/bind/lib/irs/lcl_sv.c
+++ b/contrib/bind/lib/irs/lcl_sv.c
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: lcl_sv.c,v 1.20 1999/10/07 20:44:03 vixie Exp $";
+static const char rcsid[] = "$Id: lcl_sv.c,v 1.22 2001/06/18 14:43:59 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* extern */
@@ -122,6 +122,8 @@ struct irs_sv *
irs_lcl_sv(struct irs_acc *this) {
struct irs_sv *sv;
struct pvt *pvt;
+
+ UNUSED(this);
if ((sv = memget(sizeof *sv)) == NULL) {
errno = ENOMEM;
@@ -287,13 +289,10 @@ sv_next(struct irs_sv *this) {
struct pvt *pvt = (struct pvt *)this->private;
#ifdef IRS_LCL_SV_DB
- if (pvt->dbh != NULL)
- NULL;
- else
+ if (pvt->dbh == NULL && pvt->sv.fp == NULL)
+#else
+ if (pvt->sv.fp == NULL)
#endif
- if (pvt->sv.fp != NULL)
- NULL;
- else
sv_rewind(this);
#ifdef IRS_LCL_SV_DB
@@ -395,7 +394,7 @@ sv_db_rec(struct lcl_sv *sv, DBT *key, DBT *data) {
return (NULL);
sv->serv.s_port = ((u_short *)key->data)[1];
n = strlen(p) + 1;
- if (n > sizeof(sv->line)) {
+ if ((size_t)n > sizeof(sv->line)) {
n = sizeof(sv->line);
}
memcpy(sv->line, p, n);
diff --git a/contrib/bind/lib/irs/nis.c b/contrib/bind/lib/irs/nis.c
index e19068a..aa10fba 100644
--- a/contrib/bind/lib/irs/nis.c
+++ b/contrib/bind/lib/irs/nis.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis.c,v 1.14 2000/02/28 07:52:16 vixie Exp $";
+static const char rcsid[] = "$Id: nis.c,v 1.15 2001/05/29 05:49:11 marka Exp $";
#endif
/* Imports */
@@ -63,6 +63,8 @@ irs_nis_acc(const char *options) {
struct irs_acc *acc;
char *domain;
+ UNUSED(options);
+
if (yp_get_default_domain(&domain) != 0)
return (NULL);
if (!(nis = memget(sizeof *nis))) {
diff --git a/contrib/bind/lib/irs/nis_gr.c b/contrib/bind/lib/irs/nis_gr.c
index 713437a..b4e0945 100644
--- a/contrib/bind/lib/irs/nis_gr.c
+++ b/contrib/bind/lib/irs/nis_gr.c
@@ -49,7 +49,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_gr.c,v 1.20 1999/01/30 00:53:16 vixie Exp $";
+static const char rcsid[] = "$Id: nis_gr.c,v 1.21 2001/05/29 05:49:12 marka 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 */
@@ -217,7 +217,7 @@ gr_byname(struct irs_gr *this, const char *name) {
int r;
nisfree(pvt, do_val);
- r = yp_match(pvt->nis_domain, group_byname, (char *)name, strlen(name),
+ r = yp_match(pvt->nis_domain, group_byname, name, strlen(name),
&pvt->curval_data, &pvt->curval_len);
if (r != 0) {
errno = ENOENT;
@@ -252,6 +252,7 @@ gr_rewind(struct irs_gr *this) {
static void
gr_minimize(struct irs_gr *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -260,7 +261,7 @@ gr_minimize(struct irs_gr *this) {
static struct group *
makegroupent(struct irs_gr *this) {
struct pvt *pvt = (struct pvt *)this->private;
- int num_members = 0;
+ unsigned int num_members = 0;
char *cp, **new;
u_long t;
diff --git a/contrib/bind/lib/irs/nis_ho.c b/contrib/bind/lib/irs/nis_ho.c
index 07d2274..72a8d17 100644
--- a/contrib/bind/lib/irs/nis_ho.c
+++ b/contrib/bind/lib/irs/nis_ho.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_ho.c,v 1.16 1999/10/13 16:39:32 vixie Exp $";
+static const char rcsid[] = "$Id: nis_ho.c,v 1.18 2001/06/18 14:44:00 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -103,6 +103,8 @@ 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 addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
+ const struct addrinfo *pai);
static struct hostent * makehostent(struct irs_ho *this);
static void nisfree(struct pvt *, enum do_what);
@@ -138,6 +140,7 @@ irs_nis_ho(struct irs_acc *this) {
ho->minimize = ho_minimize;
ho->res_set = ho_res_set;
ho->res_get = ho_res_get;
+ ho->addrinfo = ho_addrinfo;
return (ho);
}
@@ -175,13 +178,17 @@ static struct hostent *
ho_byname2(struct irs_ho *this, const char *name, int af) {
struct pvt *pvt = (struct pvt *)this->private;
int r;
+ char *tmp;
+
+ UNUSED(af);
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);
+ DE_CONST(name, tmp);
+ r = yp_match(pvt->nis_domain, hosts_byname, tmp,
+ strlen(tmp), &pvt->curval_data, &pvt->curval_len);
if (r != 0) {
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
return (NULL);
@@ -203,7 +210,7 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
(!memcmp(uaddr, mapped, sizeof mapped) ||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
/* Unmap. */
- addr = (u_char *)addr + sizeof mapped;
+ addr = (const u_char *)addr + sizeof mapped;
uaddr += sizeof mapped;
af = AF_INET;
len = INADDRSZ;
@@ -307,6 +314,72 @@ ho_res_set(struct irs_ho *this, struct __res_state *res,
pvt->free_res = free_res;
}
+struct nis_res_target {
+ struct nis_res_target *next;
+ int family;
+};
+
+/* XXX */
+extern struct addrinfo *hostent2addrinfo __P((struct hostent *,
+ const struct addrinfo *pai));
+
+static struct addrinfo *
+ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
+{
+ struct pvt *pvt = (struct pvt *)this->private;
+ struct hostent *hp;
+ struct nis_res_target q, q2, *p;
+ struct addrinfo sentinel, *cur;
+
+ memset(&q, 0, sizeof(q2));
+ memset(&q2, 0, sizeof(q2));
+ memset(&sentinel, 0, sizeof(sentinel));
+ cur = &sentinel;
+
+ switch(pai->ai_family) {
+ case AF_UNSPEC: /* INET6 then INET4 */
+ q.family = AF_INET6;
+ q.next = &q2;
+ q2.family = AF_INET;
+ break;
+ case AF_INET6:
+ q.family = AF_INET6;
+ break;
+ case AF_INET:
+ q.family = AF_INET;
+ break;
+ default:
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* ??? */
+ return(NULL);
+ }
+
+ for (p = &q; p; p = p->next) {
+ struct addrinfo *ai;
+
+ hp = (*this->byname2)(this, name, p->family);
+ if (hp == NULL) {
+ /* byname2 should've set an appropriate error */
+ continue;
+ }
+ if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
+ (hp->h_addr_list[0] == NULL)) {
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
+ continue;
+ }
+ ai = hostent2addrinfo(hp, pai);
+ if (ai) {
+ cur->ai_next = ai;
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ }
+ }
+
+ if (sentinel.ai_next == NULL)
+ RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
+
+ return(sentinel.ai_next);
+}
+
/* Private */
static struct hostent *
diff --git a/contrib/bind/lib/irs/nis_ng.c b/contrib/bind/lib/irs/nis_ng.c
index 88d97ff..a42d994 100644
--- a/contrib/bind/lib/irs/nis_ng.c
+++ b/contrib/bind/lib/irs/nis_ng.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_ng.c,v 1.16 1999/01/18 07:46:58 vixie Exp $";
+static const char rcsid[] = "$Id: nis_ng.c,v 1.17 2001/05/29 05:49:14 marka Exp $";
#endif
/* Imports */
@@ -78,7 +78,8 @@ static /*const*/ char netgroup_map[] = "netgroup";
/* Forward */
static void ng_close(struct irs_ng *);
-static int ng_next(struct irs_ng *, char **, char **, char **);
+static int ng_next(struct irs_ng *, const char **,
+ const char **, const char **);
static int ng_test(struct irs_ng *,
const char *, const char *,
const char *, const char *);
@@ -129,14 +130,14 @@ ng_close(struct irs_ng *this) {
}
static int
-ng_next(struct irs_ng *this, char **host, char **user, char **domain) {
+ng_next(struct irs_ng *this, const char **host, const char **user, const char **domain) {
struct pvt *pvt = (struct pvt *)this->private;
if (!pvt->cur)
return (0);
- *host = (/*const*/ char *)pvt->cur->host;
- *user = (/*const*/ char *)pvt->cur->user;
- *domain = (/*const*/ char *)pvt->cur->domain;
+ *host = pvt->cur->host;
+ *user = pvt->cur->user;
+ *domain = pvt->cur->domain;
pvt->cur = pvt->cur->next;
return (1);
}
@@ -178,6 +179,7 @@ ng_rewind(struct irs_ng *this, const char *name) {
static void
ng_minimize(struct irs_ng *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -188,13 +190,15 @@ add_group_to_list(struct pvt *pvt, const char *name, int len) {
char *vdata, *cp, *np;
struct tmpgrp *tmp;
int vlen, r;
+ char *nametmp;
/* Don't add the same group to the list more than once. */
for (tmp = pvt->tmp; tmp; tmp = tmp->next)
if (!strcmp(tmp->name, name))
return;
- r = yp_match(pvt->nis_domain, netgroup_map, (char *)name, len,
+ DE_CONST(name, nametmp);
+ r = yp_match(pvt->nis_domain, netgroup_map, nametmp, len,
&vdata, &vlen);
if (r == 0) {
cp = vdata;
diff --git a/contrib/bind/lib/irs/nis_nw.c b/contrib/bind/lib/irs/nis_nw.c
index 72ec391..bc659f3 100644
--- a/contrib/bind/lib/irs/nis_nw.c
+++ b/contrib/bind/lib/irs/nis_nw.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_nw.c,v 1.15 1999/01/18 07:46:58 vixie Exp $";
+static const char rcsid[] = "$Id: nis_nw.c,v 1.16 2001/05/29 05:49:15 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -187,6 +187,7 @@ static struct nwent *
nw_byname(struct irs_nw *this, const char *name, int af) {
struct pvt *pvt = (struct pvt *)this->private;
int r;
+ char *tmp;
if (init(this) == -1)
return (NULL);
@@ -197,8 +198,9 @@ nw_byname(struct irs_nw *this, const char *name, int af) {
return (NULL);
}
nisfree(pvt, do_val);
- r = yp_match(pvt->nis_domain, networks_byname, (char *)name,
- strlen(name), &pvt->curval_data, &pvt->curval_len);
+ DE_CONST(name, tmp);
+ r = yp_match(pvt->nis_domain, networks_byname, tmp,
+ strlen(tmp), &pvt->curval_data, &pvt->curval_len);
if (r != 0) {
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
return (NULL);
diff --git a/contrib/bind/lib/irs/nis_pr.c b/contrib/bind/lib/irs/nis_pr.c
index 8dff084..bc09075 100644
--- a/contrib/bind/lib/irs/nis_pr.c
+++ b/contrib/bind/lib/irs/nis_pr.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_pr.c,v 1.13 1999/01/18 07:46:59 vixie Exp $";
+static const char rcsid[] = "$Id: nis_pr.c,v 1.14 2001/05/29 05:49:16 marka Exp $";
#endif
/* Imports */
@@ -132,10 +132,12 @@ static struct protoent *
pr_byname(struct irs_pr *this, const char *name) {
struct pvt *pvt = (struct pvt *)this->private;
int r;
+ char *tmp;
nisfree(pvt, do_val);
- r = yp_match(pvt->nis_domain, protocols_byname, (char *)name,
- strlen(name), &pvt->curval_data, &pvt->curval_len);
+ DE_CONST(name, tmp);
+ r = yp_match(pvt->nis_domain, protocols_byname, tmp,
+ strlen(tmp), &pvt->curval_data, &pvt->curval_len);
if (r != 0) {
errno = ENOENT;
return (NULL);
@@ -204,6 +206,7 @@ pr_rewind(struct irs_pr *this) {
static void
pr_minimize(struct irs_pr *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -220,9 +223,9 @@ makeprotoent(struct irs_pr *this) {
pvt->prbuf = pvt->curval_data;
pvt->curval_data = NULL;
- for (p = pvt->prbuf; *p && *p != '#'; p++)
- NULL;
- while (p > pvt->prbuf && isspace(p[-1]))
+ for (p = pvt->prbuf; *p && *p != '#';)
+ p++;
+ while (p > pvt->prbuf && isspace((unsigned char)(p[-1])))
p--;
*p = '\0';
@@ -230,16 +233,16 @@ makeprotoent(struct irs_pr *this) {
n = m = 0;
pvt->proto.p_name = p;
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
if (!*p)
return (NULL);
*p++ = '\0';
- while (*p && isspace(*p))
+ while (*p && isspace((unsigned char)*p))
p++;
pvt->proto.p_proto = atoi(p);
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
*p++ = '\0';
@@ -255,7 +258,7 @@ makeprotoent(struct irs_pr *this) {
pvt->proto.p_aliases = t;
}
pvt->proto.p_aliases[n++] = p;
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
p++;
if (*p)
*p++ = '\0';
diff --git a/contrib/bind/lib/irs/nis_pw.c b/contrib/bind/lib/irs/nis_pw.c
index ce90f20..1d345a5 100644
--- a/contrib/bind/lib/irs/nis_pw.c
+++ b/contrib/bind/lib/irs/nis_pw.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_pw.c,v 1.16 1999/01/30 00:53:16 vixie Exp $";
+static const char rcsid[] = "$Id: nis_pw.c,v 1.17 2001/05/29 05:49:18 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -169,9 +169,11 @@ static struct passwd *
pw_byname(struct irs_pw *this, const char *name) {
struct pvt *pvt = (struct pvt *)this->private;
int r;
+ char *tmp;
nisfree(pvt, do_val);
- r = yp_match(pvt->nis_domain, passwd_byname, name, strlen(name),
+ DE_CONST(name, tmp);
+ r = yp_match(pvt->nis_domain, passwd_byname, tmp, strlen(tmp),
&pvt->curval_data, &pvt->curval_len);
if (r != 0) {
errno = ENOENT;
@@ -206,6 +208,7 @@ pw_rewind(struct irs_pw *this) {
static void
pw_minimize(struct irs_pw *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -226,7 +229,9 @@ makepasswdent(struct irs_pw *this) {
pvt->passwd.pw_name = cp;
if (!(cp = strchr(cp, ':')))
goto cleanup;
+#ifdef HAS_PW_CLASS
pvt->passwd.pw_class = cp; /* Needs to point at a \0. */
+#endif
*cp++ = '\0';
pvt->passwd.pw_passwd = cp;
diff --git a/contrib/bind/lib/irs/nis_sv.c b/contrib/bind/lib/irs/nis_sv.c
index 8810fd2..40bfda5 100644
--- a/contrib/bind/lib/irs/nis_sv.c
+++ b/contrib/bind/lib/irs/nis_sv.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_sv.c,v 1.14 1999/01/18 07:46:59 vixie Exp $";
+static const char rcsid[] = "$Id: nis_sv.c,v 1.15 2001/05/29 05:49:19 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -205,6 +205,7 @@ sv_next(struct irs_sv *this) {
static void
sv_minimize(struct irs_sv *this) {
+ UNUSED(this);
/* NOOP */
}
@@ -242,7 +243,7 @@ makeservent(struct irs_sv *this) {
pvt->serv.s_port = htons((u_short) atoi(p));
pvt->serv.s_proto = NULL;
- while (*p && !isspace(*p))
+ while (*p && !isspace((unsigned char)*p))
if (*p++ == '/')
pvt->serv.s_proto = p;
if (!pvt->serv.s_proto)
diff --git a/contrib/bind/lib/irs/nul_ng.c b/contrib/bind/lib/irs/nul_ng.c
index cc5c801..1a61d8c 100644
--- a/contrib/bind/lib/irs/nul_ng.c
+++ b/contrib/bind/lib/irs/nul_ng.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nul_ng.c,v 1.10 1999/01/18 07:46:59 vixie Exp $";
+static const char rcsid[] = "$Id: nul_ng.c,v 1.11 2001/05/29 05:49:20 marka Exp $";
#endif
/*
@@ -49,7 +49,8 @@ static const char rcsid[] = "$Id: nul_ng.c,v 1.10 1999/01/18 07:46:59 vixie Exp
/* Forward. */
static void ng_close(struct irs_ng *);
-static int ng_next(struct irs_ng *, char **, char **, char **);
+static int ng_next(struct irs_ng *, const char **,
+ const char **, const char **);
static int ng_test(struct irs_ng *,
const char *, const char *,
const char *, const char *);
@@ -62,6 +63,8 @@ struct irs_ng *
irs_nul_ng(struct irs_acc *this) {
struct irs_ng *ng;
+ UNUSED(this);
+
if (!(ng = memget(sizeof *ng))) {
errno = ENOMEM;
return (NULL);
@@ -85,7 +88,13 @@ ng_close(struct irs_ng *this) {
/* ARGSUSED */
static int
-ng_next(struct irs_ng *this, char **host, char **user, char **domain) {
+ng_next(struct irs_ng *this, const char **host, const char **user,
+ const char **domain)
+{
+ UNUSED(this);
+ UNUSED(host);
+ UNUSED(user);
+ UNUSED(domain);
errno = ENOENT;
return (-1);
}
@@ -94,16 +103,24 @@ static int
ng_test(struct irs_ng *this, const char *name,
const char *user, const char *host, const char *domain)
{
+ UNUSED(this);
+ UNUSED(name);
+ UNUSED(user);
+ UNUSED(host);
+ UNUSED(domain);
errno = ENODEV;
return (-1);
}
static void
ng_rewind(struct irs_ng *this, const char *netgroup) {
+ UNUSED(this);
+ UNUSED(netgroup);
/* NOOP */
}
static void
ng_minimize(struct irs_ng *this) {
+ UNUSED(this);
/* NOOP */
}
diff --git a/contrib/bind/lib/irs/util.c b/contrib/bind/lib/irs/util.c
index 1d097c6..e37f4d9 100644
--- a/contrib/bind/lib/irs/util.c
+++ b/contrib/bind/lib/irs/util.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: util.c,v 1.11 2000/02/04 08:28:33 vixie Exp $";
+static const char rcsid[] = "$Id: util.c,v 1.12 2001/05/29 05:49:21 marka Exp $";
#endif
#include "port_before.h"
@@ -89,7 +89,7 @@ make_group_list(struct irs_gr *this, const char *name,
*/
(*this->rewind)(this);
while ((grp = (*this->next)(this)) != NULL) {
- if (grp->gr_gid == basegid)
+ if ((gid_t)grp->gr_gid == basegid)
continue;
for (i = 0; grp->gr_mem[i]; i++) {
if (!strcmp(grp->gr_mem[i], name)) {
OpenPOWER on IntegriCloud