- 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:
Hajimu UMEMOTO 2006-04-15 16:20:27 +00:00
parent 1b9518293e
commit d3ac2b30d4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157779
17 changed files with 1302 additions and 723 deletions

View File

@ -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 *);

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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 @@ getnetent_r(struct netent *ne, struct netent_data *ned)
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 @@ getnetent_r(struct netent *ne, struct netent_data *ned)
}
}
*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);
}

View File

@ -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 */
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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 @@ getprotoent_r(struct protoent *pe, struct protoent_data *ped)
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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 @@ getservent_r(struct servent *se, struct servent_data *sed)
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 @@ getservent_r(struct servent *se, struct servent_data *sed)
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);
}

View File

@ -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_ */