diff options
Diffstat (limited to 'lib/libc/net/getnetnamadr.c')
-rw-r--r-- | lib/libc/net/getnetnamadr.c | 133 |
1 files changed, 107 insertions, 26 deletions
diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c index eec3d9a..7b8aaa6 100644 --- a/lib/libc/net/getnetnamadr.c +++ b/lib/libc/net/getnetnamadr.c @@ -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); +} |