make getnetby*() thread-safe.
This commit is contained in:
parent
96fe138431
commit
f9eaa37c6e
@ -82,13 +82,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdarg.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
#include "netdb_private.h"
|
||||
#include "res_config.h"
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
#define BYADDR 0
|
||||
#define BYNAME 1
|
||||
#define MAXALIASES 35
|
||||
|
||||
#define MAXPACKET (64*1024)
|
||||
|
||||
@ -158,11 +158,9 @@ ipreverse(char *in, char *out)
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
static struct netent *
|
||||
getnetanswer(answer, anslen, net_i)
|
||||
querybuf *answer;
|
||||
int anslen;
|
||||
int net_i;
|
||||
static int
|
||||
getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
struct netent_data *ned)
|
||||
{
|
||||
|
||||
HEADER *hp;
|
||||
@ -171,10 +169,8 @@ getnetanswer(answer, anslen, net_i)
|
||||
u_char *eom;
|
||||
int type, class, ancount, qdcount, haveanswer;
|
||||
char aux[MAXHOSTNAMELEN];
|
||||
char ans[MAXHOSTNAMELEN];
|
||||
char *in, *bp, *ep, **ap;
|
||||
static struct netent net_entry;
|
||||
static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
|
||||
static char ans[MAXHOSTNAMELEN];
|
||||
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
@ -194,21 +190,21 @@ static char ans[MAXHOSTNAMELEN];
|
||||
hp = &answer->hdr;
|
||||
ancount = ntohs(hp->ancount); /* #/records in the answer section */
|
||||
qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
|
||||
bp = netbuf;
|
||||
ep = netbuf + sizeof(netbuf);
|
||||
bp = ned->netbuf;
|
||||
ep = ned->netbuf + sizeof(ned->netbuf);
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (!qdcount) {
|
||||
if (hp->aa)
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
else
|
||||
h_errno = TRY_AGAIN;
|
||||
return (NULL);
|
||||
return -1;
|
||||
}
|
||||
while (qdcount-- > 0)
|
||||
cp += __dn_skipname(cp, eom) + QFIXEDSZ;
|
||||
ap = net_aliases;
|
||||
ap = ned->net_aliases;
|
||||
*ap = NULL;
|
||||
net_entry.n_aliases = net_aliases;
|
||||
ne->n_aliases = ned->net_aliases;
|
||||
haveanswer = 0;
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
@ -226,14 +222,13 @@ static char ans[MAXHOSTNAMELEN];
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !res_hnok(bp)) {
|
||||
cp += n;
|
||||
return (NULL);
|
||||
return -1;
|
||||
}
|
||||
cp += n;
|
||||
*ap++ = bp;
|
||||
n = strlen(bp) + 1;
|
||||
bp += n;
|
||||
net_entry.n_addrtype =
|
||||
(class == C_IN) ? AF_INET : AF_UNSPEC;
|
||||
ne->n_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
|
||||
haveanswer++;
|
||||
}
|
||||
}
|
||||
@ -241,26 +236,33 @@ static char ans[MAXHOSTNAMELEN];
|
||||
*ap = NULL;
|
||||
switch (net_i) {
|
||||
case BYADDR:
|
||||
net_entry.n_name = *net_entry.n_aliases;
|
||||
net_entry.n_net = 0L;
|
||||
ne->n_name = *ne->n_aliases;
|
||||
ne->n_net = 0L;
|
||||
break;
|
||||
case BYNAME:
|
||||
in = *net_entry.n_aliases;
|
||||
net_entry.n_name = &ans[0];
|
||||
in = *ne->n_aliases;
|
||||
n = strlen(ans) + 1;
|
||||
if (ep - bp < n) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, ans, ep - bp);
|
||||
ne->n_name = bp;
|
||||
if (strlen(in) + 1 > sizeof(aux)) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
errno = ENOBUFS;
|
||||
return (NULL);
|
||||
return -1;
|
||||
}
|
||||
ipreverse(in, aux);
|
||||
net_entry.n_net = inet_network(aux);
|
||||
ne->n_net = inet_network(aux);
|
||||
break;
|
||||
}
|
||||
net_entry.n_aliases++;
|
||||
return (&net_entry);
|
||||
ne->n_aliases++;
|
||||
return 0;
|
||||
}
|
||||
h_errno = TRY_AGAIN;
|
||||
return (NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -268,17 +270,18 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
unsigned long net;
|
||||
int net_type;
|
||||
struct netent *ne;
|
||||
struct netent_data *ned;
|
||||
unsigned int netbr[4];
|
||||
int nn, anslen;
|
||||
int nn, anslen, error;
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME];
|
||||
unsigned long net2;
|
||||
struct netent *net_entry;
|
||||
|
||||
net = va_arg(ap, unsigned long);
|
||||
net_type = va_arg(ap, int);
|
||||
|
||||
*(struct netent **)rval = NULL;
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
if (net_type != AF_INET)
|
||||
return NS_UNAVAIL;
|
||||
@ -321,16 +324,15 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
net_entry = getnetanswer(buf, anslen, BYADDR);
|
||||
error = getnetanswer(buf, anslen, BYADDR, ne, ned);
|
||||
free(buf);
|
||||
if (net_entry) {
|
||||
if (error == 0) {
|
||||
unsigned u_net = net; /* maybe net should be unsigned ? */
|
||||
|
||||
/* Strip trailing zeros */
|
||||
while ((u_net & 0xff) == 0 && u_net != 0)
|
||||
u_net >>= 8;
|
||||
net_entry->n_net = u_net;
|
||||
*(struct netent **)rval = net_entry;
|
||||
ne->n_net = u_net;
|
||||
return NS_SUCCESS;
|
||||
}
|
||||
return NS_NOTFOUND;
|
||||
@ -340,13 +342,15 @@ int
|
||||
_dns_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *net;
|
||||
int anslen;
|
||||
struct netent *ne;
|
||||
struct netent_data *ned;
|
||||
int anslen, error;
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME];
|
||||
|
||||
net = va_arg(ap, const char *);
|
||||
|
||||
*(struct netent**)rval = NULL;
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
@ -374,9 +378,9 @@ _dns_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
*(struct netent**)rval = getnetanswer(buf, anslen, BYNAME);
|
||||
error = getnetanswer(buf, anslen, BYNAME, ne, ned);
|
||||
free(buf);
|
||||
return (*(struct netent**)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -58,68 +58,72 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static FILE *netf;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct netent net;
|
||||
static char *net_aliases[MAXALIASES];
|
||||
static int _net_stayopen;
|
||||
#include "netdb_private.h"
|
||||
|
||||
void
|
||||
_setnethtent(f)
|
||||
int f;
|
||||
_setnethtent(int f, struct netent_data *ned)
|
||||
{
|
||||
|
||||
if (netf == NULL)
|
||||
netf = fopen(_PATH_NETWORKS, "r" );
|
||||
if (ned->netf == NULL)
|
||||
ned->netf = fopen(_PATH_NETWORKS, "r");
|
||||
else
|
||||
rewind(netf);
|
||||
_net_stayopen |= f;
|
||||
rewind(ned->netf);
|
||||
ned->stayopen |= f;
|
||||
}
|
||||
|
||||
void
|
||||
_endnethtent()
|
||||
_endnethtent(struct netent_data *ned)
|
||||
{
|
||||
|
||||
if (netf) {
|
||||
fclose(netf);
|
||||
netf = NULL;
|
||||
if (ned->netf) {
|
||||
fclose(ned->netf);
|
||||
ned->netf = NULL;
|
||||
}
|
||||
_net_stayopen = 0;
|
||||
ned->stayopen = 0;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetent()
|
||||
int
|
||||
getnetent_r(struct netent *ne, struct netent_data *ned)
|
||||
{
|
||||
char *p;
|
||||
char *p, *bp, *ep;
|
||||
char *cp, **q;
|
||||
int len;
|
||||
char line[BUFSIZ + 1];
|
||||
|
||||
if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
|
||||
return (NULL);
|
||||
if (ned->netf == NULL &&
|
||||
(ned->netf = fopen(_PATH_NETWORKS, "r")) == NULL)
|
||||
return -1;
|
||||
again:
|
||||
p = fgets(line, sizeof line, netf);
|
||||
p = fgets(line, sizeof line, ned->netf);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
return -1;
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
net.n_name = p;
|
||||
bp = ned->netbuf;
|
||||
ep = ned->netbuf + sizeof ned->netbuf;
|
||||
ne->n_name = bp;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
len = strlen(p) + 1;
|
||||
if (ep - bp < len) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, p, ep - bp);
|
||||
bp += len;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
net.n_net = inet_network(cp);
|
||||
net.n_addrtype = AF_INET;
|
||||
q = net.n_aliases = net_aliases;
|
||||
ne->n_net = inet_network(cp);
|
||||
ne->n_addrtype = AF_INET;
|
||||
q = ne->n_aliases = ned->net_aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
@ -127,39 +131,61 @@ getnetent()
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &net_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
if (q >= &ned->net_aliases[_MAXALIASES - 1])
|
||||
break;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
len = strlen(cp) + 1;
|
||||
if (ep - bp < len)
|
||||
break;
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
*q++ = bp;
|
||||
bp += len;
|
||||
cp = p;
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
return (&net);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetent(void)
|
||||
{
|
||||
struct netdata *nd;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (getnetent_r(&nd->net, &nd->data) != 0)
|
||||
return NULL;
|
||||
return &nd->net;
|
||||
}
|
||||
|
||||
int
|
||||
_ht_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *name;
|
||||
struct netent *p;
|
||||
struct netent *ne;
|
||||
struct netent_data *ned;
|
||||
char **cp;
|
||||
int error;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while ( (p = getnetent()) ) {
|
||||
if (strcasecmp(p->n_name, name) == 0)
|
||||
setnetent_r(ned->stayopen, ned);
|
||||
while ((error = getnetent_r(ne, ned)) == 0) {
|
||||
if (strcasecmp(ne->n_name, name) == 0)
|
||||
break;
|
||||
for (cp = p->n_aliases; *cp != 0; cp++)
|
||||
for (cp = ne->n_aliases; *cp != 0; cp++)
|
||||
if (strcasecmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
*(struct netent **)rval = p;
|
||||
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
if (!ned->stayopen)
|
||||
endnetent_r(ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
}
|
||||
|
||||
int
|
||||
@ -167,17 +193,20 @@ _ht_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
unsigned long net;
|
||||
int type;
|
||||
struct netent *p;
|
||||
struct netent *ne;
|
||||
struct netent_data *ned;
|
||||
int error;
|
||||
|
||||
net = va_arg(ap, unsigned long);
|
||||
type = va_arg(ap, int);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while ( (p = getnetent()) )
|
||||
if (p->n_addrtype == type && p->n_net == net)
|
||||
setnetent_r(ned->stayopen, ned);
|
||||
while ((error = getnetent_r(ne, ned)) == 0)
|
||||
if (ne->n_addrtype == type && ne->n_net == net)
|
||||
break;
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
*(struct netent **)rval = p;
|
||||
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
if (!ned->stayopen)
|
||||
endnetent_r(ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
}
|
||||
|
@ -44,22 +44,18 @@ __FBSDID("$FreeBSD$");
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
#include "netdb_private.h"
|
||||
|
||||
#ifdef YP
|
||||
static char *host_aliases[MAXALIASES];
|
||||
|
||||
static struct netent *
|
||||
_getnetbynis(const char *name, char *map, int af)
|
||||
static int
|
||||
_getnetbynis(const char *name, char *map, int af, struct netent *ne,
|
||||
struct netent_data *ned)
|
||||
{
|
||||
char *p, *bp, *ep;
|
||||
char *cp, **q;
|
||||
static char *result;
|
||||
int resultlen;
|
||||
static struct netent h;
|
||||
static char *domain = (char *)NULL;
|
||||
static char ypbuf[YPMAXRECORD + 2];
|
||||
char *result;
|
||||
int resultlen, len;
|
||||
char ypbuf[YPMAXRECORD + 2];
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
@ -67,15 +63,16 @@ _getnetbynis(const char *name, char *map, int af)
|
||||
default:
|
||||
case AF_INET6:
|
||||
errno = EAFNOSUPPORT;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&domain))
|
||||
return (NULL);
|
||||
if (ned->yp_domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&ned->yp_domain))
|
||||
return -1;
|
||||
|
||||
if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
|
||||
return (NULL);
|
||||
if (yp_match(ned->yp_domain, map, name, strlen(name), &result,
|
||||
&resultlen))
|
||||
return -1;
|
||||
|
||||
bcopy((char *)result, (char *)&ypbuf, resultlen);
|
||||
ypbuf[resultlen] = '\0';
|
||||
@ -87,15 +84,24 @@ _getnetbynis(const char *name, char *map, int af)
|
||||
|
||||
cp = strpbrk(result, " \t");
|
||||
*cp++ = '\0';
|
||||
h.n_name = result;
|
||||
bp = ned->netbuf;
|
||||
ep = ned->netbuf + sizeof ned->netbuf;
|
||||
len = strlen(result) + 1;
|
||||
if (ep - bp < len) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, result, ep - bp);
|
||||
ne->n_name = bp;
|
||||
bp += len;
|
||||
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
|
||||
h.n_net = inet_network(cp);
|
||||
h.n_addrtype = AF_INET;
|
||||
ne->n_net = inet_network(cp);
|
||||
ne->n_addrtype = AF_INET;
|
||||
|
||||
q = h.n_aliases = host_aliases;
|
||||
q = ne->n_aliases = ned->net_aliases;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
@ -104,14 +110,21 @@ _getnetbynis(const char *name, char *map, int af)
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
if (q > &ned->net_aliases[_MAXALIASES - 1])
|
||||
break;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
len = strlen(cp) + 1;
|
||||
if (ep - bp < len)
|
||||
break;
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
*q++ = bp;
|
||||
bp += len;
|
||||
cp = p;
|
||||
}
|
||||
*q = NULL;
|
||||
return (&h);
|
||||
return 0;
|
||||
}
|
||||
#endif /* YP */
|
||||
|
||||
@ -120,11 +133,16 @@ _nis_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
#ifdef YP
|
||||
const char *name;
|
||||
struct netent *ne;
|
||||
struct netent_data *ned;
|
||||
int error;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
|
||||
*(struct netent **)rval = _getnetbynis(name, "networks.byname", AF_INET);
|
||||
return (*(struct netent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
error = _getnetbynis(name, "networks.byname", AF_INET, ne, ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
#endif
|
||||
@ -137,16 +155,19 @@ _nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
#ifdef YP
|
||||
unsigned long addr;
|
||||
int af;
|
||||
struct netent *ne;
|
||||
struct netent_data *ned;
|
||||
char *str, *cp;
|
||||
unsigned long net2;
|
||||
int nn;
|
||||
unsigned int netbr[4];
|
||||
char buf[MAXDNAME];
|
||||
int error;
|
||||
|
||||
addr = va_arg(ap, unsigned long);
|
||||
af = va_arg(ap, int);
|
||||
|
||||
*(struct netent **)rval = NULL;
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
if (af != AF_INET) {
|
||||
errno = EAFNOSUPPORT;
|
||||
@ -181,8 +202,8 @@ _nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
cp = str + (strlen(str) - 2);
|
||||
}
|
||||
|
||||
*(struct netent **)rval = _getnetbynis(str, "networks.byaddr", af);
|
||||
return (*(struct netent**)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
error = _getnetbynis(str, "networks.byaddr", af, ne, ned);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
#endif /* YP */
|
||||
|
@ -167,7 +167,7 @@ functions appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
The data space used by
|
||||
these functions is static; if future use requires the data, it should be
|
||||
these functions is a thread-specific; if future use requires the data, it should be
|
||||
copied before any subsequent calls to these functions overwrite it.
|
||||
Only Internet network
|
||||
numbers are currently understood.
|
||||
|
@ -27,6 +27,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "namespace.h"
|
||||
#include "reentrant.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <nsswitch.h>
|
||||
@ -54,10 +56,53 @@ static const ns_src default_src[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct netent *
|
||||
getnetbyname(const char *name)
|
||||
static struct netdata netdata;
|
||||
static thread_key_t netdata_key;
|
||||
static once_t netdata_init_once = ONCE_INITIALIZER;
|
||||
static int netdata_thr_keycreated = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
getnetbyname_r(const char *name, struct netent *ne, struct netent_data *ned)
|
||||
{
|
||||
struct netent *hp = 0;
|
||||
int rval;
|
||||
|
||||
|
||||
@ -66,21 +111,17 @@ getnetbyname(const char *name)
|
||||
{ NSSRC_DNS, _dns_getnetbyname, NULL },
|
||||
NS_NIS_CB(_nis_getnetbyname, NULL) /* force -DHESIOD */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
rval = _nsdispatch((void *)&hp, dtab, NSDB_NETWORKS, "getnetbyname",
|
||||
default_src, name);
|
||||
};
|
||||
|
||||
if (rval != NS_SUCCESS)
|
||||
return NULL;
|
||||
else
|
||||
return hp;
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyname",
|
||||
default_src, name, ne, ned);
|
||||
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(u_long addr, int af)
|
||||
int
|
||||
getnetbyaddr_r(u_long addr, int af, struct netent *ne, struct netent_data *ned)
|
||||
{
|
||||
struct netent *hp = 0;
|
||||
int rval;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
@ -88,28 +129,68 @@ getnetbyaddr(u_long addr, int af)
|
||||
{ NSSRC_DNS, _dns_getnetbyaddr, NULL },
|
||||
NS_NIS_CB(_nis_getnetbyaddr, NULL) /* force -DHESIOD */
|
||||
{ 0 }
|
||||
};
|
||||
};
|
||||
|
||||
rval = _nsdispatch((void *)&hp, dtab, NSDB_NETWORKS, "getnetbyaddr",
|
||||
default_src, addr, af);
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyaddr",
|
||||
default_src, addr, af, ne, ned);
|
||||
|
||||
if (rval != NS_SUCCESS)
|
||||
return NULL;
|
||||
else
|
||||
return hp;
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
void
|
||||
setnetent(stayopen)
|
||||
int stayopen;
|
||||
setnetent_r(int stayopen, struct netent_data *ned)
|
||||
{
|
||||
_setnethtent(stayopen);
|
||||
_setnethtent(stayopen, ned);
|
||||
_setnetdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endnetent()
|
||||
endnetent_r(struct netent_data *ned)
|
||||
{
|
||||
_endnethtent();
|
||||
_endnethtent(ned);
|
||||
_endnetdnsent();
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname(const char *name)
|
||||
{
|
||||
struct netdata *nd;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (getnetbyname_r(name, &nd->net, &nd->data) != 0)
|
||||
return NULL;
|
||||
return &nd->net;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(u_long addr, int af)
|
||||
{
|
||||
struct netdata *nd;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (getnetbyaddr_r(addr, af, &nd->net, &nd->data) != 0)
|
||||
return NULL;
|
||||
return &nd->net;
|
||||
}
|
||||
|
||||
void
|
||||
setnetent(int stayopen)
|
||||
{
|
||||
struct netdata *nd;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return;
|
||||
setnetent_r(stayopen, &nd->data);
|
||||
}
|
||||
|
||||
void
|
||||
endnetent(void)
|
||||
{
|
||||
struct netdata *nd;
|
||||
|
||||
if ((nd = __netdata_init()) == NULL)
|
||||
return;
|
||||
endnetent_r(&nd->data);
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ getprotoent_r(struct protoent *pe, struct protoent_data *ped)
|
||||
if (ped->fp == NULL && (ped->fp = fopen(_PATH_PROTOCOLS, "r")) == NULL)
|
||||
return (-1);
|
||||
again:
|
||||
if ((p = fgets(ped->line, BUFSIZ, ped->fp)) == NULL)
|
||||
if ((p = fgets(ped->line, sizeof ped->line, ped->fp)) == NULL)
|
||||
return (-1);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
@ -159,7 +159,7 @@ getprotoent_r(struct protoent *pe, struct protoent_data *ped)
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &ped->aliases[PROTOENT_MAXALIASES - 1])
|
||||
if (q < &ped->aliases[_MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
|
@ -150,7 +150,7 @@ _getservbyport_yp(struct servent_data *sed)
|
||||
}
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(sed->line, BUFSIZ, "%.*s\n", resultlen, result);
|
||||
snprintf(sed->line, sizeof sed->line, "%.*s\n", resultlen, result);
|
||||
|
||||
free(result);
|
||||
return(1);
|
||||
@ -179,7 +179,7 @@ _getservbyname_yp(struct servent_data *sed)
|
||||
}
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(sed->line, BUFSIZ, "%.*s\n", resultlen, result);
|
||||
snprintf(sed->line, sizeof sed->line, "%.*s\n", resultlen, result);
|
||||
|
||||
free(result);
|
||||
return(1);
|
||||
@ -219,7 +219,7 @@ _getservent_yp(struct servent_data *sed)
|
||||
}
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(sed->line, BUFSIZ, "%.*s\n", resultlen, result);
|
||||
snprintf(sed->line, sizeof sed->line, "%.*s\n", resultlen, result);
|
||||
|
||||
free(result);
|
||||
|
||||
@ -265,7 +265,7 @@ getservent_r(struct servent *se, struct servent_data *sed)
|
||||
if (sed->fp == NULL && (sed->fp = fopen(_PATH_SERVICES, "r")) == NULL)
|
||||
return (-1);
|
||||
again:
|
||||
if ((p = fgets(sed->line, BUFSIZ, sed->fp)) == NULL)
|
||||
if ((p = fgets(sed->line, sizeof sed->line, sed->fp)) == NULL)
|
||||
return (-1);
|
||||
#ifdef YP
|
||||
if (*p == '+' && _yp_check(NULL)) {
|
||||
@ -312,7 +312,7 @@ getservent_r(struct servent *se, struct servent_data *sed)
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &sed->aliases[SERVENT_MAXALIASES - 1])
|
||||
if (q < &sed->aliases[_MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
|
@ -28,28 +28,35 @@
|
||||
#ifndef _NETDB_PRIVATE_H_
|
||||
#define _NETDB_PRIVATE_H_
|
||||
|
||||
#include <stdio.h> /* XXX: for BUFSIZ */
|
||||
#include <stdio.h> /* XXX: for FILE */
|
||||
|
||||
#define PROTOENT_MAXALIASES 35
|
||||
#define SERVENT_MAXALIASES 35
|
||||
#define _MAXALIASES 35
|
||||
#define _MAXLINELEN 1024
|
||||
#define _MAXADDRS 35
|
||||
#define _NETBUFSIZE 1025
|
||||
|
||||
struct netent_data {
|
||||
char *net_aliases[_MAXALIASES];
|
||||
char netbuf[_NETBUFSIZE];
|
||||
FILE *netf;
|
||||
int stayopen;
|
||||
#ifdef YP
|
||||
char *yp_domain;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct protoent_data {
|
||||
FILE *fp;
|
||||
char *aliases[PROTOENT_MAXALIASES];
|
||||
char *aliases[_MAXALIASES];
|
||||
int stayopen;
|
||||
char line[BUFSIZ + 1];
|
||||
};
|
||||
|
||||
struct protodata {
|
||||
struct protoent proto;
|
||||
struct protoent_data data;
|
||||
char line[_MAXLINELEN + 1];
|
||||
};
|
||||
|
||||
struct servent_data {
|
||||
FILE *fp;
|
||||
char *aliases[SERVENT_MAXALIASES];
|
||||
char *aliases[_MAXALIASES];
|
||||
int stayopen;
|
||||
char line[BUFSIZ + 1];
|
||||
char line[_MAXLINELEN + 1];
|
||||
#ifdef YP
|
||||
int yp_stepping;
|
||||
char *yp_name;
|
||||
@ -61,28 +68,44 @@ struct servent_data {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct netdata {
|
||||
struct netent net;
|
||||
struct netent_data data;
|
||||
};
|
||||
|
||||
struct protodata {
|
||||
struct protoent proto;
|
||||
struct protoent_data data;
|
||||
};
|
||||
|
||||
struct servdata {
|
||||
struct servent serv;
|
||||
struct servent_data data;
|
||||
};
|
||||
|
||||
#define endnetent_r __endnetent_r
|
||||
#define endprotoent_r __endprotoent_r
|
||||
#define endservent_r __endservent_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 setnetent_r __setnetent_r
|
||||
#define setprotoent_r __setprotoent_r
|
||||
#define setservent_r __setservent_r
|
||||
|
||||
struct netdata *__netdata_init(void);
|
||||
struct protodata *__protodata_init(void);
|
||||
struct servdata *__servdata_init(void);
|
||||
void _endhostdnsent(void);
|
||||
void _endhosthtent(void);
|
||||
void _endnetdnsent(void);
|
||||
void _endnethtent(void);
|
||||
void _endnethtent(struct netent_data *);
|
||||
struct hostent *_gethostbynisaddr(const char *, int, int);
|
||||
struct hostent *_gethostbynisname(const char *, int);
|
||||
void _map_v4v6_address(const char *, char *);
|
||||
@ -90,9 +113,14 @@ void _map_v4v6_hostent(struct hostent *, char **, char **);
|
||||
void _sethostdnsent(int);
|
||||
void _sethosthtent(int);
|
||||
void _setnetdnsent(int);
|
||||
void _setnethtent(int);
|
||||
void _setnethtent(int, struct netent_data *);
|
||||
void endnetent_r(struct netent_data *);
|
||||
void endprotoent_r(struct protoent_data *);
|
||||
void endservent_r(struct servent_data *);
|
||||
int getnetbyaddr_r(unsigned long 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 *);
|
||||
@ -101,6 +129,7 @@ int getservbyname_r(const char *, const char *, struct servent *,
|
||||
int getservbyport_r(int, const char *, struct servent *,
|
||||
struct servent_data *);
|
||||
int getservent_r(struct servent *, struct servent_data *);
|
||||
void setnetent_r(int, struct netent_data *);
|
||||
void setprotoent_r(int, struct protoent_data *);
|
||||
void setservent_r(int, struct servent_data *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user