- make reentrant version of netdb functions glibc style API, and
expose them to outside of libc. - make netdb functions NSS friendly. Reviewed by: arch@ and current@ (no objection)
This commit is contained in:
parent
65a640e4f0
commit
b6bb84cf9e
@ -221,21 +221,47 @@ void endprotoent(void);
|
||||
void endservent(void);
|
||||
void freehostent(struct hostent *);
|
||||
struct hostent *gethostbyaddr(const char *, int, int);
|
||||
int gethostbyaddr_r(const char *, int, int, struct hostent *,
|
||||
char *, size_t, struct hostent **, int *);
|
||||
struct hostent *gethostbyname(const char *);
|
||||
int gethostbyname_r(const char *, struct hostent *, char *, size_t,
|
||||
struct hostent **, int *);
|
||||
struct hostent *gethostbyname2(const char *, int);
|
||||
int gethostbyname2_r(const char *, int, struct hostent *, char *,
|
||||
size_t, struct hostent **, int *);
|
||||
struct hostent *gethostent(void);
|
||||
int gethostent_r(struct hostent *, char *, size_t,
|
||||
struct hostent **, int *);
|
||||
struct hostent *getipnodebyaddr(const void *, size_t, int, int *);
|
||||
struct hostent *getipnodebyname(const char *, int, int, int *);
|
||||
struct netent *getnetbyaddr(uint32_t, int);
|
||||
int getnetbyaddr_r(uint32_t, int, struct netent *, char *, size_t,
|
||||
struct netent**, int *);
|
||||
struct netent *getnetbyname(const char *);
|
||||
int getnetbyname_r(const char *, struct netent *, char *, size_t,
|
||||
struct netent **, int *);
|
||||
struct netent *getnetent(void);
|
||||
int getnetent_r(struct netent *, char *, size_t, struct netent **,
|
||||
int *);
|
||||
int getnetgrent(char **, char **, char **);
|
||||
struct protoent *getprotobyname(const char *);
|
||||
int getprotobyname_r(const char *, struct protoent *, char *,
|
||||
size_t, struct protoent **);
|
||||
struct protoent *getprotobynumber(int);
|
||||
int getprotobynumber_r(int, struct protoent *, char *, size_t,
|
||||
struct protoent **);
|
||||
struct protoent *getprotoent(void);
|
||||
int getprotoent_r(struct protoent *, char *, size_t,
|
||||
struct protoent **);
|
||||
struct servent *getservbyname(const char *, const char *);
|
||||
int getservbyname_r(const char *, const char *, struct servent *,
|
||||
char *, size_t, struct servent **);
|
||||
struct servent *getservbyport(int, const char *);
|
||||
int getservbyport_r(int, const char *, struct servent *, char *,
|
||||
size_t, struct servent **);
|
||||
struct servent *getservent(void);
|
||||
int getservent_r(struct servent *, char *, size_t,
|
||||
struct servent **);
|
||||
void herror(const char *);
|
||||
__const char *hstrerror(int);
|
||||
int innetgr(const char *, const char *, const char *, const char *);
|
||||
|
@ -19,9 +19,13 @@ FBSD_1.0 {
|
||||
getaddrinfo;
|
||||
endhostdnsent;
|
||||
gethostent;
|
||||
gethostent_r;
|
||||
gethostbyname;
|
||||
gethostbyname_r;
|
||||
gethostbyname2;
|
||||
gethostbyname2_r;
|
||||
gethostbyaddr;
|
||||
gethostbyaddr_r;
|
||||
sethostent;
|
||||
endhostent;
|
||||
getifaddrs;
|
||||
@ -30,20 +34,29 @@ FBSD_1.0 {
|
||||
freeifmaddrs;
|
||||
getnameinfo;
|
||||
getnetent;
|
||||
getnetent_r;
|
||||
getnetbyname;
|
||||
getnetbyname_r;
|
||||
getnetbyaddr;
|
||||
getnetbyaddr_r;
|
||||
setnetent;
|
||||
endnetent;
|
||||
getprotobynumber;
|
||||
getprotobynumber_r;
|
||||
setprotoent;
|
||||
endprotoent;
|
||||
getprotoent;
|
||||
getprotoent_r;
|
||||
getprotobyname;
|
||||
getprotobyname_r;
|
||||
getservbyname;
|
||||
getservbyname_r;
|
||||
getservbyport;
|
||||
getservbyport_r;
|
||||
setservent;
|
||||
endservent;
|
||||
getservent;
|
||||
getservent_r;
|
||||
hesiod_init;
|
||||
hesiod_end;
|
||||
hesiod_to_bind;
|
||||
|
@ -131,22 +131,22 @@ dprintf(msg, num, res)
|
||||
do { \
|
||||
cp += x; \
|
||||
if (cp > eom) { \
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY); \
|
||||
return -1; \
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY); \
|
||||
return (-1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BOUNDS_CHECK(ptr, count) \
|
||||
do { \
|
||||
if ((ptr) + (count) > eom) { \
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY); \
|
||||
return -1; \
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY); \
|
||||
return (-1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
struct hostent *he, struct hostent_data *hed)
|
||||
struct hostent *he, struct hostent_data *hed, res_state statp)
|
||||
{
|
||||
const HEADER *hp;
|
||||
const u_char *cp;
|
||||
@ -172,8 +172,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
name_ok = res_dnok;
|
||||
break;
|
||||
default:
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1; /* XXX should be abort(); */
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1); /* XXX should be abort(); */
|
||||
}
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
@ -186,13 +186,13 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
cp = answer->buf;
|
||||
BOUNDED_INCR(HFIXEDSZ);
|
||||
if (qdcount != 1) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
BOUNDED_INCR(n + QFIXEDSZ);
|
||||
if (qtype == T_A || qtype == T_AAAA) {
|
||||
@ -202,8 +202,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
*/
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
he->h_name = bp;
|
||||
bp += n;
|
||||
@ -253,8 +253,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
}
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
/* Store alias. */
|
||||
*ap++ = bp;
|
||||
@ -283,8 +283,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
}
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
@ -322,8 +322,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
#if MULTI_PTRS_ARE_ALIASES
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
if (!haveanswer)
|
||||
he->h_name = bp;
|
||||
@ -342,7 +342,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
break;
|
||||
#else
|
||||
he->h_name = bp;
|
||||
if (hed->res->options & RES_USE_INET6) {
|
||||
if (statp->options & RES_USE_INET6) {
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
@ -351,8 +351,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
bp += n;
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
}
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
|
||||
return (0);
|
||||
#endif
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
@ -377,14 +377,14 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
bp += sizeof(align) - ((u_long)bp % sizeof(align));
|
||||
|
||||
if (bp + n >= ep) {
|
||||
dprintf("size (%d) too big\n", n, hed->res);
|
||||
dprintf("size (%d) too big\n", n, statp);
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
if (hap >= &hed->h_addr_ptrs[_MAXADDRS-1]) {
|
||||
if (!toobig++)
|
||||
dprintf("Too many addresses (%d)\n",
|
||||
_MAXADDRS, hed->res);
|
||||
_MAXADDRS, statp);
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
@ -392,15 +392,15 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
bp += n;
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dprintf("Impossible condition (type=%d)\n", type,
|
||||
hed->res);
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
statp);
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
/* BIND has abort() here, too risky on bad data */
|
||||
}
|
||||
if (!had_error)
|
||||
@ -415,8 +415,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
* in its return structures - should give it the "best"
|
||||
* address in that case, not some random one
|
||||
*/
|
||||
if (hed->res->nsort && haveanswer > 1 && qtype == T_A)
|
||||
addrsort(hed->h_addr_ptrs, haveanswer, hed->res);
|
||||
if (statp->nsort && haveanswer > 1 && qtype == T_A)
|
||||
addrsort(hed->h_addr_ptrs, haveanswer, statp);
|
||||
# endif /*RESOLVSORT*/
|
||||
if (!he->h_name) {
|
||||
n = strlen(qname) + 1; /* for the \0 */
|
||||
@ -426,45 +426,46 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
he->h_name = bp;
|
||||
bp += n;
|
||||
}
|
||||
if (hed->res->options & RES_USE_INET6)
|
||||
if (statp->options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
|
||||
return (0);
|
||||
}
|
||||
no_recovery:
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* XXX: for async DNS resolver in ypserv */
|
||||
struct hostent *
|
||||
__dns_getanswer(const char *answer, int anslen, const char *qname, int qtype)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
if ((he = __hostent_init()) == NULL ||
|
||||
(hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
hd->data.res = statp;
|
||||
switch (qtype) {
|
||||
case T_AAAA:
|
||||
hd->host.h_addrtype = AF_INET6;
|
||||
hd->host.h_length = IN6ADDRSZ;
|
||||
he->h_addrtype = AF_INET6;
|
||||
he->h_length = NS_IN6ADDRSZ;
|
||||
break;
|
||||
case T_A:
|
||||
default:
|
||||
hd->host.h_addrtype = AF_INET;
|
||||
hd->host.h_length = INADDRSZ;
|
||||
he->h_addrtype = AF_INET;
|
||||
he->h_length = NS_INADDRSZ;
|
||||
break;
|
||||
}
|
||||
|
||||
error = gethostanswer((const querybuf *)answer, anslen, qname, qtype,
|
||||
&hd->host, &hd->data);
|
||||
return (error == 0) ? &hd->host : NULL;
|
||||
he, hed, statp);
|
||||
return (error == 0) ? he : NULL;
|
||||
}
|
||||
|
||||
int
|
||||
@ -472,51 +473,78 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *name;
|
||||
int af;
|
||||
struct hostent *he;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct hostent *hptr, he;
|
||||
struct hostent_data *hed;
|
||||
querybuf *buf;
|
||||
int n, size, type, error;
|
||||
int n, type, error;
|
||||
res_state statp;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
hptr = va_arg(ap, struct hostent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
*((struct hostent **)rval) = NULL;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
he.h_addrtype = af;
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
he.h_length = NS_INADDRSZ;
|
||||
type = T_A;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
he.h_length = NS_IN6ADDRSZ;
|
||||
type = T_AAAA;
|
||||
break;
|
||||
default:
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
errno = EAFNOSUPPORT;
|
||||
return NS_UNAVAIL;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
he->h_addrtype = af;
|
||||
he->h_length = size;
|
||||
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
n = res_nsearch(hed->res, name, C_IN, type, buf->buf, sizeof(buf->buf));
|
||||
n = res_nsearch(statp, name, C_IN, type, buf->buf, sizeof(buf->buf));
|
||||
if (n < 0) {
|
||||
free(buf);
|
||||
dprintf("res_nsearch failed (%d)\n", n, hed->res);
|
||||
dprintf("res_nsearch failed (%d)\n", n, statp);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (0);
|
||||
} else if (n > sizeof(buf->buf)) {
|
||||
free(buf);
|
||||
dprintf("static buffer is too small (%d)\n", n, hed->res);
|
||||
dprintf("static buffer is too small (%d)\n", n, statp);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (0);
|
||||
}
|
||||
error = gethostanswer(buf, n, name, type, he, hed);
|
||||
error = gethostanswer(buf, n, name, type, &he, hed, statp);
|
||||
free(buf);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
if (error != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct hostent **)rval) = hptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
@ -524,24 +552,41 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const u_char *uaddr;
|
||||
int len, af;
|
||||
struct hostent *he;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct hostent *hptr, he;
|
||||
struct hostent_data *hed;
|
||||
int n, error;
|
||||
int n;
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME+1], *qp;
|
||||
res_state statp;
|
||||
#ifdef SUNSECURITY
|
||||
struct hostdata rhd;
|
||||
struct hostent *rhe;
|
||||
char **haddr;
|
||||
u_long old_options;
|
||||
char hname2[MAXDNAME+1], numaddr[46];
|
||||
int ret_h_error;
|
||||
#endif /*SUNSECURITY*/
|
||||
|
||||
uaddr = va_arg(ap, const u_char *);
|
||||
len = va_arg(ap, int);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
hptr = va_arg(ap, struct hostent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
*((struct hostent **)rval) = NULL;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
@ -553,7 +598,7 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
break;
|
||||
case AF_INET6:
|
||||
qp = qbuf;
|
||||
for (n = IN6ADDRSZ - 1; n >= 0; n--) {
|
||||
for (n = NS_IN6ADDRSZ - 1; n >= 0; n--) {
|
||||
qp += SPRINTF((qp, "%x.%x.",
|
||||
uaddr[n] & 0xf,
|
||||
(uaddr[n] >> 4) & 0xf));
|
||||
@ -564,24 +609,28 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
abort();
|
||||
}
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
n = res_nquery(hed->res, qbuf, C_IN, T_PTR, (u_char *)buf->buf,
|
||||
n = res_nquery(statp, qbuf, C_IN, T_PTR, (u_char *)buf->buf,
|
||||
sizeof buf->buf);
|
||||
if (n < 0) {
|
||||
free(buf);
|
||||
dprintf("res_nquery failed (%d)\n", n, hed->res);
|
||||
return NS_UNAVAIL;
|
||||
dprintf("res_nquery failed (%d)\n", n, statp);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
if (n > sizeof buf->buf) {
|
||||
free(buf);
|
||||
dprintf("static buffer is too small (%d)\n", n, hed->res);
|
||||
return NS_UNAVAIL;
|
||||
dprintf("static buffer is too small (%d)\n", n, statp);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
if ((error = gethostanswer(buf, n, qbuf, T_PTR, he, hed)) != 0) {
|
||||
if (gethostanswer(buf, n, qbuf, T_PTR, &he, hed, statp) != 0) {
|
||||
free(buf);
|
||||
return NS_NOTFOUND; /* h_errno was set by gethostanswer() */
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND); /* h_errno was set by gethostanswer() */
|
||||
}
|
||||
free(buf);
|
||||
#ifdef SUNSECURITY
|
||||
@ -590,25 +639,28 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
* turn off search as the name should be absolute,
|
||||
* 'localhost' should be matched by defnames
|
||||
*/
|
||||
strncpy(hname2, he->h_name, MAXDNAME);
|
||||
strncpy(hname2, he.h_name, MAXDNAME);
|
||||
hname2[MAXDNAME] = '\0';
|
||||
old_options = hed->res->options;
|
||||
hed->res->options &= ~RES_DNSRCH;
|
||||
hed->res->options |= RES_DEFNAMES;
|
||||
old_options = statp->options;
|
||||
statp->options &= ~RES_DNSRCH;
|
||||
statp->options |= RES_DEFNAMES;
|
||||
memset(&rhd, 0, sizeof rhd);
|
||||
if (!(rhe = gethostbyname_r(hname2, &rhd.host, &rhd.data))) {
|
||||
rhe = gethostbyname_r(hname2, &rhd.host, &rhd.data,
|
||||
sizeof(rhd.data), &ret_h_error);
|
||||
if (rhe == NULL) {
|
||||
if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
|
||||
strlcpy(numaddr, "UNKNOWN", sizeof(numaddr));
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostbyaddr: No A record for %s (verifying [%s])",
|
||||
hname2, numaddr);
|
||||
hed->res->options = old_options;
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return NS_NOTFOUND;
|
||||
statp->options = old_options;
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
hed->res->options = old_options;
|
||||
statp->options = old_options;
|
||||
for (haddr = rhe->h_addr_list; *haddr; haddr++)
|
||||
if (!memcmp(*haddr, addr, INADDRSZ))
|
||||
if (!memcmp(*haddr, addr, NS_INADDRSZ))
|
||||
break;
|
||||
if (!*haddr) {
|
||||
if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
|
||||
@ -616,31 +668,34 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostbyaddr: A record of %s != PTR record [%s]",
|
||||
hname2, numaddr);
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return NS_NOTFOUND;
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
}
|
||||
#endif /*SUNSECURITY*/
|
||||
he->h_addrtype = af;
|
||||
he->h_length = len;
|
||||
he.h_addrtype = af;
|
||||
he.h_length = len;
|
||||
memcpy(hed->host_addr, uaddr, len);
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
if (af == AF_INET && (hed->res->options & RES_USE_INET6)) {
|
||||
if (af == AF_INET && (statp->options & RES_USE_INET6)) {
|
||||
_map_v4v6_address((char*)hed->host_addr, (char*)hed->host_addr);
|
||||
he->h_addrtype = AF_INET6;
|
||||
he->h_length = IN6ADDRSZ;
|
||||
he.h_addrtype = AF_INET6;
|
||||
he.h_length = NS_IN6ADDRSZ;
|
||||
}
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct hostent **)rval) = hptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
static void
|
||||
addrsort(ap, num, res)
|
||||
char **ap;
|
||||
int num;
|
||||
res_state res;
|
||||
addrsort(char **ap, int num, res_state res)
|
||||
{
|
||||
int i, j;
|
||||
char **p;
|
||||
@ -682,8 +737,7 @@ addrsort(ap, num, res)
|
||||
#endif
|
||||
|
||||
void
|
||||
_sethostdnsent(stayopen)
|
||||
int stayopen;
|
||||
_sethostdnsent(int stayopen)
|
||||
{
|
||||
res_state statp;
|
||||
|
||||
|
@ -91,7 +91,8 @@ _endhosthtent(struct hostent_data *hed)
|
||||
}
|
||||
|
||||
static int
|
||||
gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped)
|
||||
gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped,
|
||||
res_state statp)
|
||||
{
|
||||
char *p, *bp, *ep;
|
||||
char *cp, **q;
|
||||
@ -99,13 +100,13 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped)
|
||||
char hostbuf[BUFSIZ + 1];
|
||||
|
||||
if (!hed->hostf && !(hed->hostf = fopen(_PATH_HOSTS, "r"))) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
again:
|
||||
if (!(p = fgets(hostbuf, sizeof hostbuf, hed->hostf))) {
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
return (-1);
|
||||
}
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
@ -146,8 +147,8 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped)
|
||||
*p++ = '\0';
|
||||
len = strlen(cp) + 1;
|
||||
if (ep - bp < len) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
bp += len;
|
||||
@ -170,31 +171,50 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped)
|
||||
cp = p;
|
||||
}
|
||||
*q = NULL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
gethostent_r(struct hostent *he, struct hostent_data *hed)
|
||||
gethostent_r(struct hostent *hptr, char *buffer, size_t buflen,
|
||||
struct hostent **result, int *h_errnop)
|
||||
{
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
struct hostent_data *hed;
|
||||
struct hostent he;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
return gethostent_p(he, hed, hed->res->options & RES_USE_INET6);
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
if (gethostent_p(&he, hed, statp->options & RES_USE_INET6, statp) != 0)
|
||||
return (-1);
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = hptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostent(void)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
struct hostent *rval;
|
||||
int ret_h_errno;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostent_r(&hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
return (NULL);
|
||||
if (gethostent_r(&hd->host, hd->data, sizeof(hd->data), &rval,
|
||||
&ret_h_errno) != 0)
|
||||
return (NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -202,36 +222,61 @@ _ht_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *name;
|
||||
int af;
|
||||
struct hostent *he;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct hostent *hptr, he;
|
||||
struct hostent_data *hed;
|
||||
char **cp;
|
||||
res_state statp;
|
||||
int error;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
hptr = va_arg(ap, struct hostent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
sethostent_r(0, hed);
|
||||
while ((error = gethostent_p(he, hed, 0)) == 0) {
|
||||
if (he->h_addrtype != af)
|
||||
*((struct hostent **)rval) = NULL;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
_sethosthtent(0, hed);
|
||||
while ((error = gethostent_p(&he, hed, 0, statp)) == 0) {
|
||||
if (he.h_addrtype != af)
|
||||
continue;
|
||||
if (he->h_addrtype == AF_INET &&
|
||||
hed->res->options & RES_USE_INET6) {
|
||||
_map_v4v6_address(he->h_addr, he->h_addr);
|
||||
he->h_length = IN6ADDRSZ;
|
||||
he->h_addrtype = AF_INET6;
|
||||
if (he.h_addrtype == AF_INET &&
|
||||
statp->options & RES_USE_INET6) {
|
||||
_map_v4v6_address(he.h_addr, he.h_addr);
|
||||
he.h_length = IN6ADDRSZ;
|
||||
he.h_addrtype = AF_INET6;
|
||||
}
|
||||
if (strcasecmp(he->h_name, name) == 0)
|
||||
if (strcasecmp(he.h_name, name) == 0)
|
||||
break;
|
||||
for (cp = he->h_aliases; *cp != 0; cp++)
|
||||
for (cp = he.h_aliases; *cp != 0; cp++)
|
||||
if (strcasecmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
endhostent_r(hed);
|
||||
_endhosthtent(hed);
|
||||
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
if (error != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct hostent **)rval) = hptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
@ -239,28 +284,51 @@ _ht_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *addr;
|
||||
int len, af;
|
||||
struct hostent *he;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct hostent *hptr, he;
|
||||
struct hostent_data *hed;
|
||||
res_state statp;
|
||||
int error;
|
||||
|
||||
addr = va_arg(ap, const char *);
|
||||
len = va_arg(ap, int);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
hptr = va_arg(ap, struct hostent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
sethostent_r(0, hed);
|
||||
while ((error = gethostent_p(he, hed, 0)) == 0)
|
||||
if (he->h_addrtype == af && !bcmp(he->h_addr, addr, len)) {
|
||||
if (he->h_addrtype == AF_INET &&
|
||||
hed->res->options & RES_USE_INET6) {
|
||||
_map_v4v6_address(he->h_addr, he->h_addr);
|
||||
he->h_length = IN6ADDRSZ;
|
||||
he->h_addrtype = AF_INET6;
|
||||
*((struct hostent **)rval) = NULL;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
_sethosthtent(0, hed);
|
||||
while ((error = gethostent_p(&he, hed, 0, statp)) == 0)
|
||||
if (he.h_addrtype == af && !bcmp(he.h_addr, addr, len)) {
|
||||
if (he.h_addrtype == AF_INET &&
|
||||
statp->options & RES_USE_INET6) {
|
||||
_map_v4v6_address(he.h_addr, he.h_addr);
|
||||
he.h_length = IN6ADDRSZ;
|
||||
he.h_addrtype = AF_INET6;
|
||||
}
|
||||
break;
|
||||
}
|
||||
endhostent_r(hed);
|
||||
_endhosthtent(hed);
|
||||
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
if (error != 0)
|
||||
return (NS_NOTFOUND);
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct hostent **)rval) = hptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
|
@ -57,7 +57,9 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
char *result;
|
||||
int resultlen, size, addrok = 0;
|
||||
char ypbuf[YPMAXRECORD + 2];
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
size = NS_INADDRSZ;
|
||||
@ -67,20 +69,20 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (hed->yp_domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&hed->yp_domain)) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
|
||||
&resultlen)) {
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* avoid potential memory leak */
|
||||
@ -101,7 +103,7 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
|
||||
if (addrok != 1)
|
||||
break;
|
||||
if (hed->res->options & RES_USE_INET6) {
|
||||
if (statp->options & RES_USE_INET6) {
|
||||
_map_v4v6_address((char *)hed->host_addr,
|
||||
(char *)hed->host_addr);
|
||||
af = AF_INET6;
|
||||
@ -113,8 +115,8 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
break;
|
||||
}
|
||||
if (addrok != 1) {
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
return (-1);
|
||||
}
|
||||
he->h_addr_list[1] = NULL;
|
||||
he->h_length = size;
|
||||
@ -130,8 +132,8 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
*p++ = '\0';
|
||||
size = strlen(cp) + 1;
|
||||
if (ep - bp < size) {
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
bp += size;
|
||||
@ -155,7 +157,7 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
cp = p;
|
||||
}
|
||||
*q = NULL;
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -172,7 +174,7 @@ _gethostbynisname_r(const char *name, int af, struct hostent *he,
|
||||
map = "ipnodes.byname";
|
||||
break;
|
||||
}
|
||||
return _gethostbynis(name, map, af, he, hed);
|
||||
return (_gethostbynis(name, map, af, he, hed));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -191,8 +193,8 @@ _gethostbynisaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
break;
|
||||
}
|
||||
if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
|
||||
return -1;
|
||||
return _gethostbynis(numaddr, map, af, he, hed);
|
||||
return (-1);
|
||||
return (_gethostbynis(numaddr, map, af, he, hed));
|
||||
}
|
||||
#endif /* YP */
|
||||
|
||||
@ -201,24 +203,26 @@ struct hostent *
|
||||
_gethostbynisname(const char *name, int af)
|
||||
{
|
||||
#ifdef YP
|
||||
struct hostdata *hd;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
u_long oresopt;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
if ((he = __hostent_init()) == NULL ||
|
||||
(hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
hd->data.res = statp;
|
||||
|
||||
oresopt = statp->options;
|
||||
statp->options &= ~RES_USE_INET6;
|
||||
error = _gethostbynisname_r(name, af, &hd->host, &hd->data);
|
||||
error = _gethostbynisname_r(name, af, he, hed);
|
||||
statp->options = oresopt;
|
||||
return (error == 0) ? &hd->host : NULL;
|
||||
return (error == 0) ? he : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -226,24 +230,26 @@ struct hostent *
|
||||
_gethostbynisaddr(const char *addr, int len, int af)
|
||||
{
|
||||
#ifdef YP
|
||||
struct hostdata *hd;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
u_long oresopt;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
if ((he = __hostent_init()) == NULL ||
|
||||
(hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NULL;
|
||||
return (NULL);
|
||||
}
|
||||
hd->data.res = statp;
|
||||
|
||||
oresopt = statp->options;
|
||||
statp->options &= ~RES_USE_INET6;
|
||||
error = _gethostbynisaddr_r(addr, len, af, &hd->host, &hd->data);
|
||||
error = _gethostbynisaddr_r(addr, len, af, he, hed);
|
||||
statp->options = oresopt;
|
||||
return (error == 0) ? &hd->host : NULL;
|
||||
return (error == 0) ? he : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -253,19 +259,43 @@ _nis_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
#ifdef YP
|
||||
const char *name;
|
||||
int af;
|
||||
struct hostent *he;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct hostent *hptr, he;
|
||||
struct hostent_data *hed;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
hptr = va_arg(ap, struct hostent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
error = _gethostbynisname_r(name, af, he, hed);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
*((struct hostent **)rval) = NULL;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
if (_gethostbynisname_r(name, af, &he, hed) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct hostent **)rval) = hptr;
|
||||
return (NS_SUCCESS);
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
*((struct hostent **)rval) = NULL;
|
||||
return (NS_UNAVAIL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -276,19 +306,43 @@ _nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
const char *addr;
|
||||
int len;
|
||||
int af;
|
||||
struct hostent *he;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct hostent *hptr, he;
|
||||
struct hostent_data *hed;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
addr = va_arg(ap, const char *);
|
||||
len = va_arg(ap, int);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
hptr = va_arg(ap, struct hostent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
error = _gethostbynisaddr_r(addr, len, af, he, hed);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
*((struct hostent **)rval) = NULL;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct hostent **)rval) = hptr;
|
||||
return (NS_SUCCESS);
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
*((struct hostent **)rval) = NULL;
|
||||
return (NS_UNAVAIL);
|
||||
#endif
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ extern int _ht_gethostbyaddr(void *, void *, va_list);
|
||||
extern int _dns_gethostbyaddr(void *, void *, va_list);
|
||||
extern int _nis_gethostbyaddr(void *, void *, va_list);
|
||||
|
||||
static int gethostbyname_internal(const char *, int, struct hostent *,
|
||||
struct hostent_data *);
|
||||
static int gethostbyname_internal(const char *, int, struct hostent *, char *,
|
||||
size_t, struct hostent **, int *, res_state);
|
||||
|
||||
/* Host lookup order if nsswitch.conf is broken or nonexistant */
|
||||
static const ns_src default_src[] = {
|
||||
@ -62,87 +62,190 @@ static const ns_src default_src[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static struct hostdata hostdata;
|
||||
static thread_key_t hostdata_key;
|
||||
static once_t hostdata_init_once = ONCE_INITIALIZER;
|
||||
static int hostdata_thr_keycreated = 0;
|
||||
NETDB_THREAD_ALLOC(hostent)
|
||||
NETDB_THREAD_ALLOC(hostent_data)
|
||||
NETDB_THREAD_ALLOC(hostdata)
|
||||
|
||||
static void
|
||||
hostent_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
hostent_data_free(void *ptr)
|
||||
{
|
||||
struct hostent_data *hed = ptr;
|
||||
|
||||
if (hed == NULL)
|
||||
return;
|
||||
hed->stayopen = 0;
|
||||
_endhosthtent(hed);
|
||||
free(hed);
|
||||
}
|
||||
|
||||
static void
|
||||
hostdata_free(void *ptr)
|
||||
{
|
||||
struct hostdata *hd = ptr;
|
||||
|
||||
if (hd == NULL)
|
||||
return;
|
||||
hd->data.stayopen = 0;
|
||||
_endhosthtent(&hd->data);
|
||||
free(hd);
|
||||
}
|
||||
|
||||
static void
|
||||
hostdata_keycreate(void)
|
||||
{
|
||||
hostdata_thr_keycreated =
|
||||
(thr_keycreate(&hostdata_key, hostdata_free) == 0);
|
||||
}
|
||||
|
||||
struct hostdata *
|
||||
__hostdata_init(void)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if (thr_main() != 0)
|
||||
return &hostdata;
|
||||
if (thr_once(&hostdata_init_once, hostdata_keycreate) != 0 ||
|
||||
!hostdata_thr_keycreated)
|
||||
return NULL;
|
||||
if ((hd = thr_getspecific(hostdata_key)) != NULL)
|
||||
return hd;
|
||||
if ((hd = calloc(1, sizeof(*hd))) == NULL)
|
||||
return NULL;
|
||||
if (thr_setspecific(hostdata_key, hd) == 0)
|
||||
return hd;
|
||||
free(hd);
|
||||
return NULL;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
int
|
||||
gethostbyname_r(const char *name, struct hostent *he, struct hostent_data *hed)
|
||||
__copy_hostent(struct hostent *he, struct hostent *hptr, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
int error;
|
||||
char *cp;
|
||||
char **ptr;
|
||||
int i, n;
|
||||
int nptr, len;
|
||||
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
nptr = 2; /* NULL ptrs */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; he->h_addr_list[i]; i++, nptr++) {
|
||||
len += he->h_length;
|
||||
}
|
||||
if (hed->res->options & RES_USE_INET6) {
|
||||
error = gethostbyname_internal(name, AF_INET6, he, hed);
|
||||
if (error == 0)
|
||||
return 0;
|
||||
for (i = 0; he->h_aliases[i]; i++, nptr++) {
|
||||
len += strlen(he->h_aliases[i]) + 1;
|
||||
}
|
||||
return gethostbyname_internal(name, AF_INET, he, hed);
|
||||
}
|
||||
len += strlen(he->h_name) + 1;
|
||||
len += nptr * sizeof(char*);
|
||||
|
||||
int
|
||||
gethostbyname2_r(const char *name, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
if (len > buflen) {
|
||||
errno = ERANGE;
|
||||
return (-1);
|
||||
}
|
||||
return gethostbyname_internal(name, af, he, hed);
|
||||
|
||||
/* copy address size and type */
|
||||
hptr->h_addrtype = he->h_addrtype;
|
||||
n = hptr->h_length = he->h_length;
|
||||
|
||||
ptr = (char **)ALIGN(buf);
|
||||
cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
|
||||
|
||||
/* copy address list */
|
||||
hptr->h_addr_list = ptr;
|
||||
for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
|
||||
memcpy(cp, he->h_addr_list[i], n);
|
||||
hptr->h_addr_list[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
hptr->h_addr_list[i] = NULL;
|
||||
ptr++;
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(he->h_name) + 1;
|
||||
strcpy(cp, he->h_name);
|
||||
hptr->h_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
hptr->h_aliases = ptr;
|
||||
for (i = 0 ; he->h_aliases[i]; i++) {
|
||||
n = strlen(he->h_aliases[i]) + 1;
|
||||
strcpy(cp, he->h_aliases[i]);
|
||||
hptr->h_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
hptr->h_aliases[i] = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
fakeaddr(const char *name, int af, struct hostent *hp, char *buf,
|
||||
size_t buflen, res_state statp)
|
||||
{
|
||||
struct hostent_data *hed;
|
||||
struct hostent he;
|
||||
|
||||
if ((hed = __hostent_data_init()) == NULL) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((af != AF_INET ||
|
||||
inet_aton(name, (struct in_addr *)hed->host_addr) != 1) &&
|
||||
inet_pton(af, name, hed->host_addr) != 1) {
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
return (-1);
|
||||
}
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
hed->hostbuf[MAXDNAME] = '\0';
|
||||
if (af == AF_INET && (statp->options & RES_USE_INET6) != 0U) {
|
||||
_map_v4v6_address((char *)hed->host_addr,
|
||||
(char *)hed->host_addr);
|
||||
af = AF_INET6;
|
||||
}
|
||||
he.h_addrtype = af;
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
he.h_length = NS_INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
he.h_length = NS_IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
he.h_name = hed->hostbuf;
|
||||
he.h_aliases = hed->host_aliases;
|
||||
hed->host_aliases[0] = NULL;
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he.h_addr_list = hed->h_addr_ptrs;
|
||||
RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
|
||||
return (__copy_hostent(&he, hp, buf, buflen));
|
||||
}
|
||||
|
||||
int
|
||||
gethostbyname_r(const char *name, struct hostent *he, char *buffer,
|
||||
size_t buflen, struct hostent **result, int *h_errnop)
|
||||
{
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
if (statp->options & RES_USE_INET6) {
|
||||
if (fakeaddr(name, AF_INET, he, buffer, buflen, statp) == 0) {
|
||||
*result = he;
|
||||
return (0);
|
||||
}
|
||||
if (gethostbyname_internal(name, AF_INET6, he, buffer, buflen,
|
||||
result, h_errnop, statp) == 0)
|
||||
return (0);
|
||||
}
|
||||
return (gethostbyname_internal(name, AF_INET, he, buffer, buflen,
|
||||
result, h_errnop, statp));
|
||||
}
|
||||
|
||||
int
|
||||
gethostbyname2_r(const char *name, int af, struct hostent *he, char *buffer,
|
||||
size_t buflen, struct hostent **result, int *h_errnop)
|
||||
{
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
return (gethostbyname_internal(name, af, he, buffer, buflen, result,
|
||||
h_errnop, statp));
|
||||
}
|
||||
|
||||
int
|
||||
gethostbyname_internal(const char *name, int af, struct hostent *hp, char *buf,
|
||||
size_t buflen, struct hostent **result, int *h_errnop, res_state statp)
|
||||
{
|
||||
const char *cp;
|
||||
char *bp, *ep;
|
||||
int size, rval;
|
||||
int rval, ret_errno;
|
||||
char abuf[MAXDNAME];
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
@ -154,111 +257,45 @@ gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
he->h_addrtype = af;
|
||||
he->h_length = size;
|
||||
|
||||
/*
|
||||
* if there aren't any dots, it could be a user-level alias.
|
||||
* this is also done in res_query() since we are not the only
|
||||
* function that looks up host names.
|
||||
*/
|
||||
if (!strchr(name, '.') &&
|
||||
(cp = res_hostalias(hed->res, name, abuf, sizeof abuf)))
|
||||
(cp = res_hostalias(statp, name, abuf, sizeof abuf)))
|
||||
name = cp;
|
||||
|
||||
/*
|
||||
* disallow names consisting only of digits/dots, unless
|
||||
* they end in a dot.
|
||||
*/
|
||||
if (isdigit((u_char)name[0]))
|
||||
for (cp = name;; ++cp) {
|
||||
if (!*cp) {
|
||||
if (*--cp == '.')
|
||||
break;
|
||||
/*
|
||||
* All-numeric, no dot at the end.
|
||||
* Fake up a hostent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, hed->host_addr) <= 0) {
|
||||
RES_SET_H_ERRNO(hed->res,
|
||||
HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
hed->hostbuf[MAXDNAME] = '\0';
|
||||
bp = hed->hostbuf + MAXDNAME + 1;
|
||||
ep = hed->hostbuf + sizeof hed->hostbuf;
|
||||
he->h_name = hed->hostbuf;
|
||||
he->h_aliases = hed->host_aliases;
|
||||
hed->host_aliases[0] = NULL;
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
if (hed->res->options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
if (!isdigit((u_char)*cp) && *cp != '.')
|
||||
break;
|
||||
}
|
||||
if ((isxdigit((u_char)name[0]) && strchr(name, ':') != NULL) ||
|
||||
name[0] == ':')
|
||||
for (cp = name;; ++cp) {
|
||||
if (!*cp) {
|
||||
if (*--cp == '.')
|
||||
break;
|
||||
/*
|
||||
* All-IPv6-legal, no dot at the end.
|
||||
* Fake up a hostent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, hed->host_addr) <= 0) {
|
||||
RES_SET_H_ERRNO(hed->res,
|
||||
HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
hed->hostbuf[MAXDNAME] = '\0';
|
||||
he->h_name = hed->hostbuf;
|
||||
he->h_aliases = hed->host_aliases;
|
||||
hed->host_aliases[0] = NULL;
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
if (!isxdigit((u_char)*cp) && *cp != ':' && *cp != '.')
|
||||
break;
|
||||
}
|
||||
if (fakeaddr(name, af, hp, buf, buflen, statp) == 0) {
|
||||
*result = hp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_HOSTS, "gethostbyname",
|
||||
default_src, name, af, he, hed);
|
||||
rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS,
|
||||
"gethostbyname2_r", default_src, name, af, hp, buf, buflen,
|
||||
&ret_errno, h_errnop);
|
||||
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
return ((rval == NS_SUCCESS) ? 0 : -1);
|
||||
}
|
||||
|
||||
int
|
||||
gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
gethostbyaddr_r(const char *addr, int len, int af, struct hostent *hp,
|
||||
char *buf, size_t buflen, struct hostent **result, int *h_errnop)
|
||||
{
|
||||
const u_char *uaddr = (const u_char *)addr;
|
||||
const struct in6_addr *addr6;
|
||||
socklen_t size;
|
||||
int rval;
|
||||
int rval, ret_errno;
|
||||
res_state statp;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
NS_FILES_CB(_ht_gethostbyaddr, NULL)
|
||||
@ -267,116 +304,118 @@ gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ) {
|
||||
if (af == AF_INET6 && len == NS_IN6ADDRSZ) {
|
||||
addr6 = (const struct in6_addr *)(const void *)uaddr;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(addr6)) {
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(addr6) ||
|
||||
IN6_IS_ADDR_V4COMPAT(addr6)) {
|
||||
/* Unmap. */
|
||||
uaddr += IN6ADDRSZ - INADDRSZ;
|
||||
uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
len = NS_INADDRSZ;
|
||||
}
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
size = NS_INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
size = NS_IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
if (size != len) {
|
||||
errno = EINVAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_HOSTS, "gethostbyaddr",
|
||||
default_src, uaddr, len, af, he, hed);
|
||||
rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS,
|
||||
"gethostbyaddr_r", default_src, uaddr, len, af, hp, buf, buflen,
|
||||
&ret_errno, h_errnop);
|
||||
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
void
|
||||
sethostent_r(int stayopen, struct hostent_data *hed)
|
||||
{
|
||||
_sethosthtent(stayopen, hed);
|
||||
_sethostdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endhostent_r(struct hostent_data *hed)
|
||||
{
|
||||
_endhosthtent(hed);
|
||||
_endhostdnsent();
|
||||
return ((rval == NS_SUCCESS) ? 0 : -1);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname(const char *name)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
struct hostent *rval;
|
||||
int ret_h_errno;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostbyname_r(name, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
return (NULL);
|
||||
if (gethostbyname_r(name, &hd->host, hd->data, sizeof(hd->data), &rval,
|
||||
&ret_h_errno) != 0)
|
||||
return (NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname2(const char *name, int af)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
struct hostent *rval;
|
||||
int ret_h_errno;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostbyname2_r(name, af, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
return (NULL);
|
||||
if (gethostbyname2_r(name, af, &hd->host, hd->data, sizeof(hd->data),
|
||||
&rval, &ret_h_errno) != 0)
|
||||
return (NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyaddr(const char *addr, int len, int af)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
struct hostent *rval;
|
||||
int ret_h_errno;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostbyaddr_r(addr, len, af, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
return (NULL);
|
||||
if (gethostbyaddr_r(addr, len, af, &hd->host, hd->data,
|
||||
sizeof(hd->data), &rval, &ret_h_errno) != 0)
|
||||
return (NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
void
|
||||
sethostent(int stayopen)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
struct hostent_data *hed;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
if ((hed = __hostent_data_init()) == NULL)
|
||||
return;
|
||||
sethostent_r(stayopen, &hd->data);
|
||||
_sethosthtent(stayopen, hed);
|
||||
_sethostdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endhostent(void)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
struct hostent_data *hed;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
if ((hed = __hostent_data_init()) == NULL)
|
||||
return;
|
||||
endhostent_r(&hd->data);
|
||||
_endhosthtent(hed);
|
||||
_endhostdnsent();
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
else
|
||||
RES_SET_H_ERRNO(statp, TRY_AGAIN);
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
while (qdcount-- > 0)
|
||||
cp += __dn_skipname(cp, eom) + QFIXEDSZ;
|
||||
@ -220,9 +220,9 @@ getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !res_hnok(bp)) {
|
||||
cp += n;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
cp += n;
|
||||
cp += n;
|
||||
*ap++ = bp;
|
||||
n = strlen(bp) + 1;
|
||||
bp += n;
|
||||
@ -243,24 +243,24 @@ getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
if (ep - bp < n) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
strlcpy(bp, ans, ep - bp);
|
||||
ne->n_name = bp;
|
||||
if (strlen(in) + 1 > sizeof(aux)) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
ipreverse(in, aux);
|
||||
ne->n_net = inet_network(aux);
|
||||
break;
|
||||
}
|
||||
ne->n_aliases++;
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
RES_SET_H_ERRNO(statp, TRY_AGAIN);
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -268,7 +268,10 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
uint32_t net;
|
||||
int net_type;
|
||||
struct netent *ne;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct netent *nptr, ne;
|
||||
struct netent_data *ned;
|
||||
unsigned int netbr[4];
|
||||
int nn, anslen, error;
|
||||
@ -279,16 +282,31 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
|
||||
net = va_arg(ap, uint32_t);
|
||||
net_type = va_arg(ap, int);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
if (net_type != AF_INET)
|
||||
return NS_UNAVAIL;
|
||||
nptr = va_arg(ap, struct netent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_UNAVAIL;
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
if ((ned = __netent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
*((struct netent **)rval) = NULL;
|
||||
|
||||
if (net_type != AF_INET) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
for (nn = 4, net2 = net; net2; net2 >>= 8)
|
||||
@ -311,7 +329,8 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
}
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
anslen = res_nquery(statp, qbuf, C_IN, T_PTR, (u_char *)buf,
|
||||
sizeof(*buf));
|
||||
@ -321,32 +340,43 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_nsearch failed\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
} else if (anslen > sizeof(*buf)) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_nsearch static buffer too small\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
error = getnetanswer(buf, anslen, BYADDR, ne, ned, statp);
|
||||
error = getnetanswer(buf, anslen, BYADDR, &ne, ned, statp);
|
||||
free(buf);
|
||||
if (error == 0) {
|
||||
/* Strip trailing zeros */
|
||||
while ((net & 0xff) == 0 && net != 0)
|
||||
net >>= 8;
|
||||
ne->n_net = net;
|
||||
return NS_SUCCESS;
|
||||
ne.n_net = net;
|
||||
if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct netent **)rval) = nptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
return NS_NOTFOUND;
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
int
|
||||
_dns_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *net;
|
||||
struct netent *ne;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct netent *nptr, ne;
|
||||
struct netent_data *ned;
|
||||
int anslen, error;
|
||||
querybuf *buf;
|
||||
@ -354,18 +384,31 @@ _dns_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
res_state statp;
|
||||
|
||||
net = va_arg(ap, const char *);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
nptr = va_arg(ap, struct netent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_UNAVAIL;
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
if ((ned = __netent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
|
||||
*((struct netent **)rval) = NULL;
|
||||
|
||||
strncpy(qbuf, net, sizeof(qbuf) - 1);
|
||||
qbuf[sizeof(qbuf) - 1] = '\0';
|
||||
anslen = res_nsearch(statp, qbuf, C_IN, T_PTR, (u_char *)buf,
|
||||
@ -376,23 +419,31 @@ _dns_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_nsearch failed\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
return (NS_UNAVAIL);
|
||||
} else if (anslen > sizeof(*buf)) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_search static buffer too small\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
error = getnetanswer(buf, anslen, BYNAME, ne, ned, statp);
|
||||
error = getnetanswer(buf, anslen, BYNAME, &ne, ned, statp);
|
||||
free(buf);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
if (error != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct netent **)rval) = nptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
_setnetdnsent(stayopen)
|
||||
int stayopen;
|
||||
_setnetdnsent(int stayopen)
|
||||
{
|
||||
res_state statp;
|
||||
|
||||
|
@ -83,8 +83,8 @@ _endnethtent(struct netent_data *ned)
|
||||
ned->stayopen = 0;
|
||||
}
|
||||
|
||||
int
|
||||
getnetent_r(struct netent *ne, struct netent_data *ned)
|
||||
static int
|
||||
getnetent_p(struct netent *ne, struct netent_data *ned)
|
||||
{
|
||||
char *p, *bp, *ep;
|
||||
char *cp, **q;
|
||||
@ -93,11 +93,11 @@ getnetent_r(struct netent *ne, struct netent_data *ned)
|
||||
|
||||
if (ned->netf == NULL &&
|
||||
(ned->netf = fopen(_PATH_NETWORKS, "r")) == NULL)
|
||||
return -1;
|
||||
return (-1);
|
||||
again:
|
||||
p = fgets(line, sizeof line, ned->netf);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
return (-1);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = strpbrk(p, "#\n");
|
||||
@ -113,7 +113,7 @@ again:
|
||||
len = strlen(p) + 1;
|
||||
if (ep - bp < len) {
|
||||
RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
strlcpy(bp, p, ep - bp);
|
||||
bp += len;
|
||||
@ -147,46 +147,94 @@ again:
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
getnetent_r(struct netent *nptr, char *buffer, size_t buflen,
|
||||
struct netent **result, int *h_errnop)
|
||||
{
|
||||
struct netent_data *ned;
|
||||
struct netent ne;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((ned = __netent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (-1);
|
||||
}
|
||||
if (getnetent_p(&ne, ned) != 0)
|
||||
return (-1);
|
||||
if (__copy_netent(&ne, nptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = nptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetent(void)
|
||||
{
|
||||
struct netdata *nd;
|
||||
struct netent *rval;
|
||||
int ret_h_errno;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (getnetent_r(&nd->net, &nd->data) != 0)
|
||||
return NULL;
|
||||
return &nd->net;
|
||||
return (NULL);
|
||||
if (getnetent_r(&nd->net, nd->data, sizeof(nd->data), &rval,
|
||||
&ret_h_errno) != 0)
|
||||
return (NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
_ht_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *name;
|
||||
struct netent *ne;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct netent *nptr, ne;
|
||||
struct netent_data *ned;
|
||||
char **cp;
|
||||
res_state statp;
|
||||
int error;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
nptr = va_arg(ap, struct netent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
setnetent_r(ned->stayopen, ned);
|
||||
while ((error = getnetent_r(ne, ned)) == 0) {
|
||||
if (strcasecmp(ne->n_name, name) == 0)
|
||||
statp = __res_state();
|
||||
if ((ned = __netent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
_setnethtent(ned->stayopen, ned);
|
||||
while ((error = getnetent_p(&ne, ned)) == 0) {
|
||||
if (strcasecmp(ne.n_name, name) == 0)
|
||||
break;
|
||||
for (cp = ne->n_aliases; *cp != 0; cp++)
|
||||
for (cp = ne.n_aliases; *cp != 0; cp++)
|
||||
if (strcasecmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!ned->stayopen)
|
||||
endnetent_r(ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
_endnethtent(ned);
|
||||
if (error != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct netent **)rval) = nptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
@ -194,20 +242,43 @@ _ht_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
uint32_t net;
|
||||
int type;
|
||||
struct netent *ne;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct netent *nptr, ne;
|
||||
struct netent_data *ned;
|
||||
res_state statp;
|
||||
int error;
|
||||
|
||||
net = va_arg(ap, uint32_t);
|
||||
type = va_arg(ap, int);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
nptr = va_arg(ap, struct netent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
setnetent_r(ned->stayopen, ned);
|
||||
while ((error = getnetent_r(ne, ned)) == 0)
|
||||
if (ne->n_addrtype == type && ne->n_net == net)
|
||||
statp = __res_state();
|
||||
if ((ned = __netent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
_setnethtent(ned->stayopen, ned);
|
||||
while ((error = getnetent_p(&ne, ned)) == 0)
|
||||
if (ne.n_addrtype == type && ne.n_net == net)
|
||||
break;
|
||||
if (!ned->stayopen)
|
||||
endnetent_r(ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
_endnethtent(ned);
|
||||
if (error != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct netent **)rval) = nptr;
|
||||
return (NS_SUCCESS);
|
||||
}
|
||||
|
@ -64,16 +64,16 @@ _getnetbynis(const char *name, char *map, int af, struct netent *ne,
|
||||
default:
|
||||
case AF_INET6:
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ned->yp_domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&ned->yp_domain))
|
||||
return -1;
|
||||
return (-1);
|
||||
|
||||
if (yp_match(ned->yp_domain, map, name, strlen(name), &result,
|
||||
&resultlen))
|
||||
return -1;
|
||||
return (-1);
|
||||
|
||||
bcopy((char *)result, (char *)&ypbuf, resultlen);
|
||||
ypbuf[resultlen] = '\0';
|
||||
@ -90,7 +90,7 @@ _getnetbynis(const char *name, char *map, int af, struct netent *ne,
|
||||
len = strlen(result) + 1;
|
||||
if (ep - bp < len) {
|
||||
RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
strlcpy(bp, result, ep - bp);
|
||||
ne->n_name = bp;
|
||||
@ -125,7 +125,7 @@ _getnetbynis(const char *name, char *map, int af, struct netent *ne,
|
||||
cp = p;
|
||||
}
|
||||
*q = NULL;
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
#endif /* YP */
|
||||
|
||||
@ -134,18 +134,39 @@ _nis_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
#ifdef YP
|
||||
const char *name;
|
||||
struct netent *ne;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct netent *nptr, ne;
|
||||
struct netent_data *ned;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
nptr = va_arg(ap, struct netent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
error = _getnetbynis(name, "networks.byname", AF_INET, ne, ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
statp = __res_state();
|
||||
if ((ned = __netent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
if (_getnetbynis(name, "networks.byname", AF_INET, &ne, ned) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct netent **)rval) = nptr;
|
||||
return (NS_SUCCESS);
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
return (NS_UNAVAIL);
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -156,23 +177,38 @@ _nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
#ifdef YP
|
||||
uint32_t addr;
|
||||
int af;
|
||||
struct netent *ne;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
int *errnop, *h_errnop;
|
||||
struct netent *nptr, ne;
|
||||
struct netent_data *ned;
|
||||
char *str, *cp;
|
||||
uint32_t net2;
|
||||
int nn;
|
||||
unsigned int netbr[4];
|
||||
char buf[MAXDNAME];
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
addr = va_arg(ap, uint32_t);
|
||||
af = va_arg(ap, int);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
nptr = va_arg(ap, struct netent *);
|
||||
buffer = va_arg(ap, char *);
|
||||
buflen = va_arg(ap, size_t);
|
||||
errnop = va_arg(ap, int *);
|
||||
h_errnop = va_arg(ap, int *);
|
||||
|
||||
statp = __res_state();
|
||||
if ((ned = __netent_data_init()) == NULL) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
if (af != AF_INET) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
*h_errnop = statp->res_h_errno;
|
||||
errno = EAFNOSUPPORT;
|
||||
return NS_UNAVAIL;
|
||||
return (NS_UNAVAIL);
|
||||
}
|
||||
|
||||
for (nn = 4, net2 = addr; net2; net2 >>= 8) {
|
||||
@ -203,9 +239,17 @@ _nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
cp = str + (strlen(str) - 2);
|
||||
}
|
||||
|
||||
error = _getnetbynis(str, "networks.byaddr", af, ne, ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
if (_getnetbynis(str, "networks.byaddr", af, &ne, ned) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
|
||||
*h_errnop = statp->res_h_errno;
|
||||
return (NS_NOTFOUND);
|
||||
}
|
||||
*((struct netent **)rval) = nptr;
|
||||
return (NS_SUCCESS);
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
return (NS_UNAVAIL);
|
||||
#endif /* YP */
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
@ -50,61 +51,84 @@ extern int _dns_getnetbyaddr(void *, void *, va_list);
|
||||
extern int _nis_getnetbyaddr(void *, void *, va_list);
|
||||
|
||||
/* Network lookup order if nsswitch.conf is broken or nonexistant */
|
||||
static const ns_src default_src[] = {
|
||||
static const ns_src default_src[] = {
|
||||
{ NSSRC_FILES, NS_SUCCESS },
|
||||
{ NSSRC_DNS, NS_SUCCESS },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static struct netdata netdata;
|
||||
static thread_key_t netdata_key;
|
||||
static once_t netdata_init_once = ONCE_INITIALIZER;
|
||||
static int netdata_thr_keycreated = 0;
|
||||
NETDB_THREAD_ALLOC(netent_data)
|
||||
NETDB_THREAD_ALLOC(netdata)
|
||||
|
||||
static void
|
||||
netent_data_free(void *ptr)
|
||||
{
|
||||
struct netent_data *ned = ptr;
|
||||
|
||||
if (ned == NULL)
|
||||
return;
|
||||
ned->stayopen = 0;
|
||||
_endnethtent(ned);
|
||||
free(ned);
|
||||
}
|
||||
|
||||
static void
|
||||
netdata_free(void *ptr)
|
||||
{
|
||||
struct netdata *nd = ptr;
|
||||
|
||||
if (nd == NULL)
|
||||
return;
|
||||
nd->data.stayopen = 0;
|
||||
_endnethtent(&nd->data);
|
||||
free(nd);
|
||||
}
|
||||
|
||||
static void
|
||||
netdata_keycreate(void)
|
||||
{
|
||||
netdata_thr_keycreated =
|
||||
(thr_keycreate(&netdata_key, netdata_free) == 0);
|
||||
}
|
||||
|
||||
struct netdata *
|
||||
__netdata_init(void)
|
||||
{
|
||||
struct netdata *nd;
|
||||
|
||||
if (thr_main() != 0)
|
||||
return &netdata;
|
||||
if (thr_once(&netdata_init_once, netdata_keycreate) != 0 ||
|
||||
!netdata_thr_keycreated)
|
||||
return NULL;
|
||||
if ((nd = thr_getspecific(netdata_key)) != NULL)
|
||||
return nd;
|
||||
if ((nd = calloc(1, sizeof(*nd))) == NULL)
|
||||
return NULL;
|
||||
if (thr_setspecific(netdata_key, nd) == 0)
|
||||
return nd;
|
||||
free(nd);
|
||||
return NULL;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
int
|
||||
getnetbyname_r(const char *name, struct netent *ne, struct netent_data *ned)
|
||||
__copy_netent(struct netent *ne, struct netent *nptr, char *buf, size_t buflen)
|
||||
{
|
||||
int rval;
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /* NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; ne->n_aliases[i]; i++, numptr++) {
|
||||
len += strlen(ne->n_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(ne->n_name) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy net value and type */
|
||||
nptr->n_addrtype = ne->n_addrtype;
|
||||
nptr->n_net = ne->n_net;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(ne->n_name) + 1;
|
||||
strcpy(cp, ne->n_name);
|
||||
nptr->n_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
nptr->n_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; ne->n_aliases[i]; i++) {
|
||||
n = strlen(ne->n_aliases[i]) + 1;
|
||||
strcpy(cp, ne->n_aliases[i]);
|
||||
nptr->n_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
nptr->n_aliases[i] = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
getnetbyname_r(const char *name, struct netent *ne, char *buffer,
|
||||
size_t buflen, struct netent **result, int *h_errorp)
|
||||
{
|
||||
int rval, ret_errno;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
NS_FILES_CB(_ht_getnetbyname, NULL)
|
||||
@ -113,17 +137,18 @@ getnetbyname_r(const char *name, struct netent *ne, struct netent_data *ned)
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyname",
|
||||
default_src, name, ne, ned);
|
||||
rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
|
||||
"getnetbyname_r", default_src, name, ne, buffer, buflen,
|
||||
&ret_errno, h_errorp);
|
||||
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
return ((rval == NS_SUCCESS) ? 0 : -1);
|
||||
}
|
||||
|
||||
int
|
||||
getnetbyaddr_r(uint32_t addr, int af, struct netent *ne,
|
||||
struct netent_data *ned)
|
||||
getnetbyaddr_r(uint32_t addr, int af, struct netent *ne, char *buffer,
|
||||
size_t buflen, struct netent **result, int *h_errorp)
|
||||
{
|
||||
int rval;
|
||||
int rval, ret_errno;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
NS_FILES_CB(_ht_getnetbyaddr, NULL)
|
||||
@ -132,66 +157,61 @@ getnetbyaddr_r(uint32_t addr, int af, struct netent *ne,
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyaddr",
|
||||
default_src, addr, af, ne, ned);
|
||||
rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
|
||||
"getnetbyaddr_r", default_src, addr, af, ne, buffer, buflen,
|
||||
&ret_errno, h_errorp);
|
||||
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
void
|
||||
setnetent_r(int stayopen, struct netent_data *ned)
|
||||
{
|
||||
_setnethtent(stayopen, ned);
|
||||
_setnetdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endnetent_r(struct netent_data *ned)
|
||||
{
|
||||
_endnethtent(ned);
|
||||
_endnetdnsent();
|
||||
return ((rval == NS_SUCCESS) ? 0 : -1);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname(const char *name)
|
||||
{
|
||||
struct netdata *nd;
|
||||
struct netent *rval;
|
||||
int ret_h_errno;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (getnetbyname_r(name, &nd->net, &nd->data) != 0)
|
||||
return NULL;
|
||||
return &nd->net;
|
||||
return (NULL);
|
||||
if (getnetbyname_r(name, &nd->net, nd->data, sizeof(nd->data), &rval,
|
||||
&ret_h_errno) != 0)
|
||||
return (NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(uint32_t addr, int af)
|
||||
{
|
||||
struct netdata *nd;
|
||||
struct netent *rval;
|
||||
int ret_h_errno;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (getnetbyaddr_r(addr, af, &nd->net, &nd->data) != 0)
|
||||
return NULL;
|
||||
return &nd->net;
|
||||
return (NULL);
|
||||
if (getnetbyaddr_r(addr, af, &nd->net, nd->data, sizeof(nd->data),
|
||||
&rval, &ret_h_errno) != 0)
|
||||
return (NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
void
|
||||
setnetent(int stayopen)
|
||||
{
|
||||
struct netdata *nd;
|
||||
struct netent_data *ned;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
if ((ned = __netent_data_init()) == NULL)
|
||||
return;
|
||||
setnetent_r(stayopen, &nd->data);
|
||||
_setnethtent(stayopen, ned);
|
||||
_setnetdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endnetent(void)
|
||||
{
|
||||
struct netdata *nd;
|
||||
struct netent_data *ned;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
if ((ned = __netent_data_init()) == NULL)
|
||||
return;
|
||||
endnetent_r(&nd->data);
|
||||
_endnethtent(ned);
|
||||
_endnetdnsent();
|
||||
}
|
||||
|
@ -41,27 +41,39 @@ __FBSDID("$FreeBSD$");
|
||||
#include "netdb_private.h"
|
||||
|
||||
int
|
||||
getprotobynumber_r(int proto, struct protoent *pe, struct protoent_data *ped)
|
||||
getprotobynumber_r(int proto, struct protoent *pptr, char *buffer,
|
||||
size_t buflen, struct protoent **result)
|
||||
{
|
||||
struct protoent pe;
|
||||
struct protoent_data *ped;
|
||||
int error;
|
||||
|
||||
setprotoent_r(ped->stayopen, ped);
|
||||
while ((error = getprotoent_r(pe, ped)) == 0)
|
||||
if (pe->p_proto == proto)
|
||||
if ((ped = __protoent_data_init()) == NULL)
|
||||
return (-1);
|
||||
__setprotoent_p(ped->stayopen, ped);
|
||||
while ((error = __getprotoent_p(&pe, ped)) == 0)
|
||||
if (pe.p_proto == proto)
|
||||
break;
|
||||
if (!ped->stayopen)
|
||||
endprotoent_r(ped);
|
||||
return (error);
|
||||
__endprotoent_p(ped);
|
||||
if (error != 0)
|
||||
return (-1);
|
||||
if (__copy_protoent(&pe, pptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = pptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber(int proto)
|
||||
{
|
||||
struct protodata *pd;
|
||||
struct protoent *rval;
|
||||
|
||||
if ((pd = __protodata_init()) == NULL)
|
||||
return (NULL);
|
||||
if (getprotobynumber_r(proto, &pd->proto, &pd->data) != 0)
|
||||
if (getprotobynumber_r(proto, &pd->proto, pd->data, sizeof(pd->data),
|
||||
&rval) != 0)
|
||||
return (NULL);
|
||||
return (&pd->proto);
|
||||
return (rval);
|
||||
}
|
||||
|
@ -37,8 +37,10 @@ static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
@ -49,10 +51,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include "un-namespace.h"
|
||||
#include "netdb_private.h"
|
||||
|
||||
static struct protodata protodata;
|
||||
static thread_key_t protodata_key;
|
||||
static once_t protodata_init_once = ONCE_INITIALIZER;
|
||||
static int protodata_thr_keycreated = 0;
|
||||
NETDB_THREAD_ALLOC(protoent_data)
|
||||
NETDB_THREAD_ALLOC(protodata)
|
||||
|
||||
static void
|
||||
protoent_data_clear(struct protoent_data *ped)
|
||||
@ -64,45 +64,68 @@ protoent_data_clear(struct protoent_data *ped)
|
||||
}
|
||||
|
||||
static void
|
||||
protodata_free(void *ptr)
|
||||
protoent_data_free(void *ptr)
|
||||
{
|
||||
struct protodata *pd = ptr;
|
||||
struct protoent_data *ped = ptr;
|
||||
|
||||
if (pd == NULL)
|
||||
return;
|
||||
protoent_data_clear(&pd->data);
|
||||
free(pd);
|
||||
protoent_data_clear(ped);
|
||||
free(ped);
|
||||
}
|
||||
|
||||
static void
|
||||
protodata_keycreate(void)
|
||||
protodata_free(void *ptr)
|
||||
{
|
||||
protodata_thr_keycreated =
|
||||
(thr_keycreate(&protodata_key, protodata_free) == 0);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
struct protodata *
|
||||
__protodata_init(void)
|
||||
int
|
||||
__copy_protoent(struct protoent *pe, struct protoent *pptr, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
struct protodata *pd;
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
if (thr_main() != 0)
|
||||
return (&protodata);
|
||||
if (thr_once(&protodata_init_once, protodata_keycreate) != 0 ||
|
||||
!protodata_thr_keycreated)
|
||||
return (NULL);
|
||||
if ((pd = thr_getspecific(protodata_key)) != NULL)
|
||||
return (pd);
|
||||
if ((pd = calloc(1, sizeof(*pd))) == NULL)
|
||||
return (NULL);
|
||||
if (thr_setspecific(protodata_key, pd) == 0)
|
||||
return (pd);
|
||||
free(pd);
|
||||
return (NULL);
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /* NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; pe->p_aliases[i]; i++, numptr++) {
|
||||
len += strlen(pe->p_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(pe->p_name) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy protocol value*/
|
||||
pptr->p_proto = pe->p_proto;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(pe->p_name) + 1;
|
||||
strcpy(cp, pe->p_name);
|
||||
pptr->p_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
pptr->p_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; pe->p_aliases[i]; i++) {
|
||||
n = strlen(pe->p_aliases[i]) + 1;
|
||||
strcpy(cp, pe->p_aliases[i]);
|
||||
pptr->p_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
pptr->p_aliases[i] = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
setprotoent_r(int f, struct protoent_data *ped)
|
||||
__setprotoent_p(int f, struct protoent_data *ped)
|
||||
{
|
||||
if (ped->fp == NULL)
|
||||
ped->fp = fopen(_PATH_PROTOCOLS, "r");
|
||||
@ -112,7 +135,7 @@ setprotoent_r(int f, struct protoent_data *ped)
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent_r(struct protoent_data *ped)
|
||||
__endprotoent_p(struct protoent_data *ped)
|
||||
{
|
||||
if (ped->fp) {
|
||||
fclose(ped->fp);
|
||||
@ -122,7 +145,7 @@ endprotoent_r(struct protoent_data *ped)
|
||||
}
|
||||
|
||||
int
|
||||
getprotoent_r(struct protoent *pe, struct protoent_data *ped)
|
||||
__getprotoent_p(struct protoent *pe, struct protoent_data *ped)
|
||||
{
|
||||
char *p;
|
||||
char *cp, **q, *endp;
|
||||
@ -171,34 +194,53 @@ again:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
getprotoent_r(struct protoent *pptr, char *buffer, size_t buflen,
|
||||
struct protoent **result)
|
||||
{
|
||||
struct protoent pe;
|
||||
struct protoent_data *ped;
|
||||
|
||||
if ((ped = __protoent_data_init()) == NULL)
|
||||
return (-1);
|
||||
|
||||
if (__getprotoent_p(&pe, ped) != 0)
|
||||
return (-1);
|
||||
if (__copy_protoent(&pe, pptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = pptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
setprotoent(int f)
|
||||
{
|
||||
struct protodata *pd;
|
||||
struct protoent_data *ped;
|
||||
|
||||
if ((pd = __protodata_init()) == NULL)
|
||||
if ((ped = __protoent_data_init()) == NULL)
|
||||
return;
|
||||
setprotoent_r(f, &pd->data);
|
||||
__setprotoent_p(f, ped);
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent(void)
|
||||
{
|
||||
struct protodata *pd;
|
||||
struct protoent_data *ped;
|
||||
|
||||
if ((pd = __protodata_init()) == NULL)
|
||||
if ((ped = __protoent_data_init()) == NULL)
|
||||
return;
|
||||
endprotoent_r(&pd->data);
|
||||
__endprotoent_p(ped);
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotoent(void)
|
||||
{
|
||||
struct protodata *pd;
|
||||
struct protoent *rval;
|
||||
|
||||
if ((pd = __protodata_init()) == NULL)
|
||||
return (NULL);
|
||||
if (getprotoent_r(&pd->proto, &pd->data) != 0)
|
||||
if (getprotoent_r(&pd->proto, pd->data, sizeof(pd->data), &rval) != 0)
|
||||
return (NULL);
|
||||
return (&pd->proto);
|
||||
return (rval);
|
||||
}
|
||||
|
@ -42,34 +42,46 @@ __FBSDID("$FreeBSD$");
|
||||
#include "netdb_private.h"
|
||||
|
||||
int
|
||||
getprotobyname_r(const char *name, struct protoent *pe,
|
||||
struct protoent_data *ped)
|
||||
getprotobyname_r(const char *name, struct protoent *pptr, char *buffer,
|
||||
size_t buflen, struct protoent **result)
|
||||
{
|
||||
struct protoent pe;
|
||||
struct protoent_data *ped;
|
||||
char **cp;
|
||||
int error;
|
||||
|
||||
setprotoent_r(ped->stayopen, ped);
|
||||
while ((error = getprotoent_r(pe, ped)) == 0) {
|
||||
if (strcmp(pe->p_name, name) == 0)
|
||||
if ((ped = __protoent_data_init()) == NULL)
|
||||
return (-1);
|
||||
|
||||
__setprotoent_p(ped->stayopen, ped);
|
||||
while ((error = __getprotoent_p(&pe, ped)) == 0) {
|
||||
if (strcmp(pe.p_name, name) == 0)
|
||||
break;
|
||||
for (cp = pe->p_aliases; *cp != 0; cp++)
|
||||
for (cp = pe.p_aliases; *cp != 0; cp++)
|
||||
if (strcmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!ped->stayopen)
|
||||
endprotoent_r(ped);
|
||||
return (error);
|
||||
__endprotoent_p(ped);
|
||||
if (error != 0)
|
||||
return (-1);
|
||||
if (__copy_protoent(&pe, pptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = pptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobyname(const char *name)
|
||||
{
|
||||
struct protodata *pd;
|
||||
struct protoent *rval;
|
||||
|
||||
if ((pd = __protodata_init()) == NULL)
|
||||
return (NULL);
|
||||
if (getprotobyname_r(name, &pd->proto, &pd->data) != 0)
|
||||
if (getprotobyname_r(name, &pd->proto, pd->data, sizeof(pd->data),
|
||||
&rval) != 0)
|
||||
return (NULL);
|
||||
return (&pd->proto);
|
||||
return (rval);
|
||||
}
|
||||
|
@ -42,48 +42,60 @@ __FBSDID("$FreeBSD$");
|
||||
#include "netdb_private.h"
|
||||
|
||||
int
|
||||
getservbyname_r(const char *name, const char *proto, struct servent *se,
|
||||
struct servent_data *sed)
|
||||
getservbyname_r(const char *name, const char *proto, struct servent *sptr,
|
||||
char *buffer, size_t buflen, struct servent **result)
|
||||
{
|
||||
struct servent se;
|
||||
struct servent_data *sed;
|
||||
char **cp;
|
||||
int error;
|
||||
|
||||
if ((sed = __servent_data_init()) == NULL)
|
||||
return (-1);
|
||||
|
||||
#ifdef YP
|
||||
sed->yp_name = (char *)name;
|
||||
sed->yp_proto = (char *)proto;
|
||||
#endif
|
||||
|
||||
setservent_r(sed->stayopen, sed);
|
||||
while ((error = getservent_r(se, sed)) == 0) {
|
||||
if (strcmp(name, se->s_name) == 0)
|
||||
__setservent_p(sed->stayopen, sed);
|
||||
while ((error = __getservent_p(&se, sed)) == 0) {
|
||||
if (strcmp(name, se.s_name) == 0)
|
||||
goto gotname;
|
||||
for (cp = se->s_aliases; *cp; cp++)
|
||||
for (cp = se.s_aliases; *cp; cp++)
|
||||
if (strcmp(name, *cp) == 0)
|
||||
goto gotname;
|
||||
continue;
|
||||
gotname:
|
||||
if (proto == 0 || strcmp(se->s_proto, proto) == 0)
|
||||
if (proto == 0 || strcmp(se.s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
if (!sed->stayopen)
|
||||
endservent_r(sed);
|
||||
__endservent_p(sed);
|
||||
|
||||
#ifdef YP
|
||||
sed->yp_name = NULL;
|
||||
sed->yp_proto = NULL;
|
||||
#endif
|
||||
|
||||
return (error);
|
||||
if (error != 0)
|
||||
return (-1);
|
||||
if (__copy_servent(&se, sptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = sptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyname(const char *name, const char *proto)
|
||||
{
|
||||
struct servdata *sd;
|
||||
struct servent *rval;
|
||||
|
||||
if ((sd = __servdata_init()) == NULL)
|
||||
return (NULL);
|
||||
if (getservbyname_r(name, proto, &sd->serv, &sd->data) != 0)
|
||||
if (getservbyname_r(name, proto, &sd->serv, sd->data, sizeof(sd->data),
|
||||
&rval) != 0)
|
||||
return (NULL);
|
||||
return (&sd->serv);
|
||||
return (rval);
|
||||
}
|
||||
|
@ -42,42 +42,54 @@ __FBSDID("$FreeBSD$");
|
||||
#include "netdb_private.h"
|
||||
|
||||
int
|
||||
getservbyport_r(int port, const char *proto, struct servent *se,
|
||||
struct servent_data *sed)
|
||||
getservbyport_r(int port, const char *proto, struct servent *sptr,
|
||||
char *buffer, size_t buflen, struct servent **result)
|
||||
{
|
||||
struct servent se;
|
||||
struct servent_data *sed;
|
||||
int error;
|
||||
|
||||
if ((sed = __servent_data_init()) == NULL)
|
||||
return (-1);
|
||||
|
||||
#ifdef YP
|
||||
sed->yp_port = port;
|
||||
sed->yp_proto = (char *)proto;
|
||||
#endif
|
||||
|
||||
setservent_r(sed->stayopen, sed);
|
||||
while ((error = getservent_r(se, sed)) == 0) {
|
||||
if (se->s_port != port)
|
||||
__setservent_p(sed->stayopen, sed);
|
||||
while ((error = __getservent_p(&se, sed)) == 0) {
|
||||
if (se.s_port != port)
|
||||
continue;
|
||||
if (proto == 0 || strcmp(se->s_proto, proto) == 0)
|
||||
if (proto == 0 || strcmp(se.s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
if (!sed->stayopen)
|
||||
endservent_r(sed);
|
||||
__endservent_p(sed);
|
||||
|
||||
#ifdef YP
|
||||
sed->yp_port = 0;
|
||||
sed->yp_proto = NULL;
|
||||
#endif
|
||||
|
||||
return (error);
|
||||
if (error != 0)
|
||||
return (-1);
|
||||
if (__copy_servent(&se, sptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = sptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyport(int port, const char *proto)
|
||||
{
|
||||
struct servdata *sd;
|
||||
struct servent *rval;
|
||||
|
||||
if ((sd = __servdata_init()) == NULL)
|
||||
return (NULL);
|
||||
if (getservbyport_r(port, proto, &sd->serv, &sd->data) != 0)
|
||||
if (getservbyport_r(port, proto, &sd->serv, sd->data,
|
||||
sizeof(sd->data), &rval) != 0)
|
||||
return (NULL);
|
||||
return (&sd->serv);
|
||||
return (rval);
|
||||
}
|
||||
|
@ -37,9 +37,11 @@ static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
@ -55,10 +57,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include "un-namespace.h"
|
||||
#include "netdb_private.h"
|
||||
|
||||
static struct servdata servdata;
|
||||
static thread_key_t servdata_key;
|
||||
static once_t servdata_init_once = ONCE_INITIALIZER;
|
||||
static int servdata_thr_keycreated = 0;
|
||||
NETDB_THREAD_ALLOC(servent_data)
|
||||
NETDB_THREAD_ALLOC(servdata)
|
||||
|
||||
static void
|
||||
servent_data_clear(struct servent_data *sed)
|
||||
@ -74,41 +74,71 @@ servent_data_clear(struct servent_data *sed)
|
||||
}
|
||||
|
||||
static void
|
||||
servdata_free(void *ptr)
|
||||
servent_data_free(void *ptr)
|
||||
{
|
||||
struct servdata *sd = ptr;
|
||||
struct servent_data *sed = ptr;
|
||||
|
||||
if (sd == NULL)
|
||||
return;
|
||||
servent_data_clear(&sd->data);
|
||||
free(sd);
|
||||
servent_data_clear(sed);
|
||||
free(sed);
|
||||
}
|
||||
|
||||
static void
|
||||
servdata_keycreate(void)
|
||||
servdata_free(void *ptr)
|
||||
{
|
||||
servdata_thr_keycreated =
|
||||
(thr_keycreate(&servdata_key, servdata_free) == 0);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
struct servdata *
|
||||
__servdata_init(void)
|
||||
int
|
||||
__copy_servent(struct servent *se, struct servent *sptr, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
struct servdata *sd;
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
if (thr_main() != 0)
|
||||
return (&servdata);
|
||||
if (thr_once(&servdata_init_once, servdata_keycreate) != 0 ||
|
||||
!servdata_thr_keycreated)
|
||||
return (NULL);
|
||||
if ((sd = thr_getspecific(servdata_key)) != NULL)
|
||||
return (sd);
|
||||
if ((sd = calloc(1, sizeof(*sd))) == NULL)
|
||||
return (NULL);
|
||||
if (thr_setspecific(servdata_key, sd) == 0)
|
||||
return (sd);
|
||||
free(sd);
|
||||
return (NULL);
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /* NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; se->s_aliases[i]; i++, numptr++) {
|
||||
len += strlen(se->s_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(se->s_name) + 1;
|
||||
len += strlen(se->s_proto) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy port value */
|
||||
sptr->s_port = se->s_port;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(se->s_name) + 1;
|
||||
strcpy(cp, se->s_name);
|
||||
sptr->s_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
sptr->s_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; se->s_aliases[i]; i++) {
|
||||
n = strlen(se->s_aliases[i]) + 1;
|
||||
strcpy(cp, se->s_aliases[i]);
|
||||
sptr->s_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
sptr->s_aliases[i] = NULL;
|
||||
|
||||
/* copy proto */
|
||||
n = strlen(se->s_proto) + 1;
|
||||
strcpy(cp, se->s_proto);
|
||||
sptr->s_proto = cp;
|
||||
cp += n;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef YP
|
||||
@ -149,7 +179,7 @@ _getservbyport_yp(struct servent_data *sed)
|
||||
} else
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(sed->line, sizeof sed->line, "%.*s\n", resultlen, result);
|
||||
|
||||
@ -178,7 +208,7 @@ _getservbyname_yp(struct servent_data *sed)
|
||||
&result, &resultlen)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(sed->line, sizeof sed->line, "%.*s\n", resultlen, result);
|
||||
|
||||
@ -229,7 +259,7 @@ _getservent_yp(struct servent_data *sed)
|
||||
#endif
|
||||
|
||||
void
|
||||
setservent_r(int f, struct servent_data *sed)
|
||||
__setservent_p(int f, struct servent_data *sed)
|
||||
{
|
||||
if (sed->fp == NULL)
|
||||
sed->fp = fopen(_PATH_SERVICES, "r");
|
||||
@ -239,7 +269,7 @@ setservent_r(int f, struct servent_data *sed)
|
||||
}
|
||||
|
||||
void
|
||||
endservent_r(struct servent_data *sed)
|
||||
__endservent_p(struct servent_data *sed)
|
||||
{
|
||||
servent_data_clear(sed);
|
||||
sed->stayopen = 0;
|
||||
@ -250,7 +280,7 @@ endservent_r(struct servent_data *sed)
|
||||
}
|
||||
|
||||
int
|
||||
getservent_r(struct servent *se, struct servent_data *sed)
|
||||
__getservent_p(struct servent *se, struct servent_data *sed)
|
||||
{
|
||||
char *p;
|
||||
char *cp, **q, *endp;
|
||||
@ -273,7 +303,7 @@ again:
|
||||
if (sed->yp_name != NULL) {
|
||||
if (!_getservbyname_yp(sed))
|
||||
goto tryagain;
|
||||
}
|
||||
}
|
||||
else if (sed->yp_port != 0) {
|
||||
if (!_getservbyport_yp(sed))
|
||||
goto tryagain;
|
||||
@ -323,34 +353,53 @@ unpack:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
getservent_r(struct servent *sptr, char *buffer, size_t buflen,
|
||||
struct servent **result)
|
||||
{
|
||||
struct servent se;
|
||||
struct servent_data *sed;
|
||||
|
||||
if ((sed = __servent_data_init()) == NULL)
|
||||
return (-1);
|
||||
|
||||
if (__getservent_p(&se, sed) != 0)
|
||||
return (-1);
|
||||
if (__copy_servent(&se, sptr, buffer, buflen) != 0)
|
||||
return (-1);
|
||||
*result = sptr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
setservent(int f)
|
||||
{
|
||||
struct servdata *sd;
|
||||
struct servent_data *sed;
|
||||
|
||||
if ((sd = __servdata_init()) == NULL)
|
||||
if ((sed = __servent_data_init()) == NULL)
|
||||
return;
|
||||
setservent_r(f, &sd->data);
|
||||
__setservent_p(f, sed);
|
||||
}
|
||||
|
||||
void
|
||||
endservent(void)
|
||||
{
|
||||
struct servdata *sd;
|
||||
struct servent_data *sed;
|
||||
|
||||
if ((sd = __servdata_init()) == NULL)
|
||||
if ((sed = __servent_data_init()) == NULL)
|
||||
return;
|
||||
endservent_r(&sd->data);
|
||||
__endservent_p(sed);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservent(void)
|
||||
{
|
||||
struct servdata *sd;
|
||||
struct servent *rval;
|
||||
|
||||
if ((sd = __servdata_init()) == NULL)
|
||||
return (NULL);
|
||||
if (getservent_r(&sd->serv, &sd->data) != 0)
|
||||
if (getservent_r(&sd->serv, sd->data, sizeof(sd->data), &rval) != 0)
|
||||
return (NULL);
|
||||
return (&sd->serv);
|
||||
return (rval);
|
||||
}
|
||||
|
@ -30,14 +30,47 @@
|
||||
|
||||
#include <stdio.h> /* XXX: for FILE */
|
||||
|
||||
#define NETDB_THREAD_ALLOC(name) \
|
||||
static struct name name; \
|
||||
static thread_key_t name##_key; \
|
||||
static once_t name##_init_once = ONCE_INITIALIZER; \
|
||||
static int name##_thr_keycreated = 0; \
|
||||
\
|
||||
static void name##_free(void *); \
|
||||
\
|
||||
static void \
|
||||
name##_keycreate(void) \
|
||||
{ \
|
||||
name##_thr_keycreated = \
|
||||
(thr_keycreate(&name##_key, name##_free) == 0); \
|
||||
} \
|
||||
\
|
||||
struct name * \
|
||||
__##name##_init(void) \
|
||||
{ \
|
||||
struct name *he; \
|
||||
\
|
||||
if (thr_main() != 0) \
|
||||
return (&name); \
|
||||
if (thr_once(&name##_init_once, name##_keycreate) != 0 || \
|
||||
!name##_thr_keycreated) \
|
||||
return (NULL); \
|
||||
if ((he = thr_getspecific(name##_key)) != NULL) \
|
||||
return (he); \
|
||||
if ((he = calloc(1, sizeof(*he))) == NULL) \
|
||||
return (NULL); \
|
||||
if (thr_setspecific(name##_key, he) == 0) \
|
||||
return (he); \
|
||||
free(he); \
|
||||
return (NULL); \
|
||||
}
|
||||
|
||||
#define _MAXALIASES 35
|
||||
#define _MAXLINELEN 1024
|
||||
#define _MAXADDRS 35
|
||||
#define _HOSTBUFSIZE (8 * 1024)
|
||||
#define _NETBUFSIZE 1025
|
||||
|
||||
struct __res_state;
|
||||
|
||||
struct hostent_data {
|
||||
uint32_t host_addr[4]; /* IPv4 or IPv6 */
|
||||
char *h_addr_ptrs[_MAXADDRS + 1];
|
||||
@ -45,7 +78,6 @@ struct hostent_data {
|
||||
char hostbuf[_HOSTBUFSIZE];
|
||||
FILE *hostf;
|
||||
int stayopen;
|
||||
struct __res_state *res;
|
||||
#ifdef YP
|
||||
char *yp_domain;
|
||||
#endif
|
||||
@ -86,50 +118,44 @@ struct servent_data {
|
||||
|
||||
struct hostdata {
|
||||
struct hostent host;
|
||||
struct hostent_data data;
|
||||
char data[sizeof(struct hostent_data)];
|
||||
};
|
||||
|
||||
struct netdata {
|
||||
struct netent net;
|
||||
struct netent_data data;
|
||||
char data[sizeof(struct netent_data)];
|
||||
};
|
||||
|
||||
struct protodata {
|
||||
struct protoent proto;
|
||||
struct protoent_data data;
|
||||
char data[sizeof(struct protoent_data)];
|
||||
};
|
||||
|
||||
struct servdata {
|
||||
struct servent serv;
|
||||
struct servent_data data;
|
||||
char data[sizeof(struct servent_data)];
|
||||
};
|
||||
|
||||
#define endhostent_r __endhostent_r
|
||||
#define endnetent_r __endnetent_r
|
||||
#define endprotoent_r __endprotoent_r
|
||||
#define endservent_r __endservent_r
|
||||
#define gethostbyaddr_r __gethostbyaddr_r
|
||||
#define gethostbyname_r __gethostbyname_r
|
||||
#define gethostbyname2_r __gethostbyname2_r
|
||||
#define gethostent_r __gethostent_r
|
||||
#define getnetbyaddr_r __getnetbyaddr_r
|
||||
#define getnetbyname_r __getnetbyname_r
|
||||
#define getnetent_r __getnetent_r
|
||||
#define getprotobyname_r __getprotobyname_r
|
||||
#define getprotobynumber_r __getprotobynumber_r
|
||||
#define getprotoent_r __getprotoent_r
|
||||
#define getservbyname_r __getservbyname_r
|
||||
#define getservbyport_r __getservbyport_r
|
||||
#define getservent_r __getservent_r
|
||||
#define sethostent_r __sethostent_r
|
||||
#define setnetent_r __setnetent_r
|
||||
#define setprotoent_r __setprotoent_r
|
||||
#define setservent_r __setservent_r
|
||||
|
||||
struct hostdata *__hostdata_init(void);
|
||||
struct hostent *__hostent_init(void);
|
||||
struct hostent_data *__hostent_data_init(void);
|
||||
struct netdata *__netdata_init(void);
|
||||
struct netent_data *__netent_data_init(void);
|
||||
struct protodata *__protodata_init(void);
|
||||
struct protoent_data *__protoent_data_init(void);
|
||||
struct servdata *__servdata_init(void);
|
||||
struct servent_data *__servent_data_init(void);
|
||||
int __copy_hostent(struct hostent *, struct hostent *, char *, size_t);
|
||||
int __copy_netent(struct netent *, struct netent *, char *, size_t);
|
||||
int __copy_protoent(struct protoent *, struct protoent *, char *, size_t);
|
||||
int __copy_servent(struct servent *, struct servent *, char *, size_t);
|
||||
|
||||
void __endprotoent_p(struct protoent_data *);
|
||||
void __endservent_p(struct servent_data *);
|
||||
int __getprotoent_p(struct protoent *, struct protoent_data *);
|
||||
int __getservent_p(struct servent *, struct servent_data *);
|
||||
void __setprotoent_p(int, struct protoent_data *);
|
||||
void __setservent_p(int, struct servent_data *);
|
||||
void _endhostdnsent(void);
|
||||
void _endhosthtent(struct hostent_data *);
|
||||
void _endnetdnsent(void);
|
||||
@ -142,31 +168,5 @@ void _sethostdnsent(int);
|
||||
void _sethosthtent(int, struct hostent_data *);
|
||||
void _setnetdnsent(int);
|
||||
void _setnethtent(int, struct netent_data *);
|
||||
void endhostent_r(struct hostent_data *);
|
||||
void endnetent_r(struct netent_data *);
|
||||
void endprotoent_r(struct protoent_data *);
|
||||
void endservent_r(struct servent_data *);
|
||||
int gethostbyaddr_r(const char *, int, int, struct hostent *,
|
||||
struct hostent_data *);
|
||||
int gethostbyname_r(const char *, struct hostent *, struct hostent_data *);
|
||||
int gethostbyname2_r(const char *, int, struct hostent *,
|
||||
struct hostent_data *);
|
||||
int gethostent_r(struct hostent *, struct hostent_data *);
|
||||
int getnetbyaddr_r(uint32_t addr, int af, struct netent *,
|
||||
struct netent_data *);
|
||||
int getnetbyname_r(const char *, struct netent *, struct netent_data *);
|
||||
int getnetent_r(struct netent *, struct netent_data *);
|
||||
int getprotobyname_r(const char *, struct protoent *, struct protoent_data *);
|
||||
int getprotobynumber_r(int, struct protoent *, struct protoent_data *);
|
||||
int getprotoent_r(struct protoent *, struct protoent_data *);
|
||||
int getservbyname_r(const char *, const char *, struct servent *,
|
||||
struct servent_data *);
|
||||
int getservbyport_r(int, const char *, struct servent *,
|
||||
struct servent_data *);
|
||||
int getservent_r(struct servent *, struct servent_data *);
|
||||
void sethostent_r(int, struct hostent_data *);
|
||||
void setnetent_r(int, struct netent_data *);
|
||||
void setprotoent_r(int, struct protoent_data *);
|
||||
void setservent_r(int, struct servent_data *);
|
||||
|
||||
#endif /* _NETDB_PRIVATE_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user