diff options
| author | Hajimu UMEMOTO <ume@FreeBSD.org> | 2005-05-16 16:29:04 +0000 |
|---|---|---|
| committer | Hajimu UMEMOTO <ume@FreeBSD.org> | 2005-05-16 16:29:04 +0000 |
| commit | b051132820f8ecb2e976c7952a196d648a7df620 (patch) | |
| tree | bd924ea3a348948109cc8284a89a5b8b5b2f3ff8 /lib/libc | |
| parent | 2507ae8a572d9d1e832cdab859ab97d018ed5ce3 (diff) | |
Notes
Diffstat (limited to 'lib/libc')
| -rw-r--r-- | lib/libc/net/getservbyname.c | 50 | ||||
| -rw-r--r-- | lib/libc/net/getservbyport.c | 49 | ||||
| -rw-r--r-- | lib/libc/net/getservent.c | 246 | ||||
| -rw-r--r-- | lib/libc/net/netdb_private.h | 106 |
4 files changed, 222 insertions, 229 deletions
diff --git a/lib/libc/net/getservbyname.c b/lib/libc/net/getservbyname.c index 79769f6ab32c..efc3c26b79da 100644 --- a/lib/libc/net/getservbyname.c +++ b/lib/libc/net/getservbyname.c @@ -39,43 +39,51 @@ __FBSDID("$FreeBSD$"); #include <netdb.h> #include <string.h> +#include "netdb_private.h" -extern int _serv_stayopen; - -struct servent * -getservbyname(name, proto) - const char *name, *proto; +int +getservbyname_r(const char *name, const char *proto, struct servent *se, + struct servent_data *sed) { - struct servent *p; char **cp; + int error; #ifdef YP - extern char *___getservbyname_yp; - extern char *___getservbyproto_yp; - - ___getservbyname_yp = (char *)name; - ___getservbyproto_yp = (char *)proto; + sed->yp_name = (char *)name; + sed->yp_proto = (char *)proto; #endif - setservent(_serv_stayopen); - while ( (p = getservent()) ) { - if (strcmp(name, p->s_name) == 0) + setservent_r(sed->stayopen, sed); + while ((error = getservent_r(se, sed)) == 0) { + if (strcmp(name, se->s_name) == 0) goto gotname; - for (cp = p->s_aliases; *cp; cp++) + for (cp = se->s_aliases; *cp; cp++) if (strcmp(name, *cp) == 0) goto gotname; continue; gotname: - if (proto == 0 || strcmp(p->s_proto, proto) == 0) + if (proto == 0 || strcmp(se->s_proto, proto) == 0) break; } - if (!_serv_stayopen) - endservent(); + if (!sed->stayopen) + endservent_r(sed); #ifdef YP - ___getservbyname_yp = NULL; - ___getservbyproto_yp = NULL; + sed->yp_name = NULL; + sed->yp_proto = NULL; #endif - return (p); + return (error); +} + +struct servent * +getservbyname(const char *name, const char *proto) +{ + struct servdata *sd; + + if ((sd = __servdata_init()) == NULL) + return (NULL); + if (getservbyname_r(name, proto, &sd->serv, &sd->data) != 0) + return (NULL); + return (&sd->serv); } diff --git a/lib/libc/net/getservbyport.c b/lib/libc/net/getservbyport.c index 2efb60f881c7..33524a2756ba 100644 --- a/lib/libc/net/getservbyport.c +++ b/lib/libc/net/getservbyport.c @@ -39,38 +39,45 @@ __FBSDID("$FreeBSD$"); #include <netdb.h> #include <string.h> +#include "netdb_private.h" -extern int _serv_stayopen; - -struct servent * -getservbyport(port, proto) - int port; - const char *proto; +int +getservbyport_r(int port, const char *proto, struct servent *se, + struct servent_data *sed) { - struct servent *p; + int error; #ifdef YP - extern int ___getservbyport_yp; - extern char *___getservbyproto_yp; - - ___getservbyport_yp = port; - ___getservbyproto_yp = (char *)proto; + sed->yp_port = port; + sed->yp_proto = (char *)proto; #endif - setservent(_serv_stayopen); - while ( (p = getservent()) ) { - if (p->s_port != port) + setservent_r(sed->stayopen, sed); + while ((error = getservent_r(se, sed)) == 0) { + if (se->s_port != port) continue; - if (proto == 0 || strcmp(p->s_proto, proto) == 0) + if (proto == 0 || strcmp(se->s_proto, proto) == 0) break; } - if (!_serv_stayopen) - endservent(); + if (!sed->stayopen) + endservent_r(sed); #ifdef YP - ___getservbyport_yp = 0; - ___getservbyproto_yp = NULL; + sed->yp_port = 0; + sed->yp_proto = NULL; #endif - return (p); + return (error); +} + +struct servent * +getservbyport(int port, const char *proto) +{ + struct servdata *sd; + + if ((sd = __servdata_init()) == NULL) + return (NULL); + if (getservbyport_r(port, proto, &sd->serv, &sd->data) != 0) + return (NULL); + return (&sd->serv); } diff --git a/lib/libc/net/getservent.c b/lib/libc/net/getservent.c index 7e4423534339..b4f603d936f2 100644 --- a/lib/libc/net/getservent.c +++ b/lib/libc/net/getservent.c @@ -48,41 +48,85 @@ __FBSDID("$FreeBSD$"); #include <rpc/rpc.h> #include <rpcsvc/yp_prot.h> #include <rpcsvc/ypclnt.h> -static int serv_stepping_yp = 0; #endif -#include "libc_private.h" +#include "namespace.h" +#include "reentrant.h" +#include "un-namespace.h" +#include "netdb_private.h" -#define MAXALIASES 35 - -static FILE *servf = NULL; -static char line[BUFSIZ+1]; -static struct servent serv; -static char *serv_aliases[MAXALIASES]; -int _serv_stayopen; +static struct servdata servdata; +static thread_key_t servdata_key; +static once_t servdata_init_once = ONCE_INITIALIZER; +static int servdata_thr_keycreated = 0; +static void +servent_data_clear(struct servent_data *sed) +{ + if (sed->fp) { + fclose(sed->fp); + sed->fp = NULL; + } #ifdef YP -char *___getservbyname_yp = NULL; -char *___getservbyproto_yp = NULL; -int ___getservbyport_yp = 0; -static char *yp_domain = NULL; + free(sed->yp_key); + sed->yp_key = NULL; +#endif +} + +static void +servdata_free(void *ptr) +{ + struct servdata *sd = ptr; + + if (sd == NULL) + return; + servent_data_clear(&sd->data); + free(sd); +} + +static void +servdata_keycreate(void) +{ + servdata_thr_keycreated = + (thr_keycreate(&servdata_key, servdata_free) == 0); +} + +struct servdata * +__servdata_init(void) +{ + struct servdata *sd; + 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); +} + +#ifdef YP static int -_getservbyport_yp(line) - char *line; +_getservbyport_yp(struct servent_data *sed) { char *result; int resultlen; char buf[YPMAXRECORD + 2]; int rv; - snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp), - ___getservbyproto_yp); + snprintf(buf, sizeof(buf), "%d/%s", ntohs(sed->yp_port), + sed->yp_proto); - ___getservbyport_yp = 0; - ___getservbyproto_yp = NULL; + sed->yp_port = 0; + sed->yp_proto = NULL; - if(!yp_domain) { - if(yp_get_default_domain(&yp_domain)) + if (!sed->yp_domain) { + if (yp_get_default_domain(&sed->yp_domain)) return (0); } @@ -95,10 +139,10 @@ _getservbyport_yp(line) * possibilities here: if there is no services.byport map, we try * services.byname instead. */ - if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf), + if ((rv = yp_match(sed->yp_domain, "services.byport", buf, strlen(buf), &result, &resultlen))) { if (rv == YPERR_MAP) { - if (yp_match(yp_domain, "services.byname", buf, + if (yp_match(sed->yp_domain, "services.byname", buf, strlen(buf), &result, &resultlen)) return(0); } else @@ -106,80 +150,76 @@ _getservbyport_yp(line) } /* getservent() expects lines terminated with \n -- make it happy */ - snprintf(line, BUFSIZ, "%.*s\n", resultlen, result); + snprintf(sed->line, BUFSIZ, "%.*s\n", resultlen, result); free(result); return(1); } static int -_getservbyname_yp(line) - char *line; +_getservbyname_yp(struct servent_data *sed) { char *result; int resultlen; char buf[YPMAXRECORD + 2]; - if(!yp_domain) { - if(yp_get_default_domain(&yp_domain)) + if(!sed->yp_domain) { + if(yp_get_default_domain(&sed->yp_domain)) return (0); } - snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp, - ___getservbyproto_yp); + snprintf(buf, sizeof(buf), "%s/%s", sed->yp_name, sed->yp_proto); - ___getservbyname_yp = 0; - ___getservbyproto_yp = NULL; + sed->yp_name = 0; + sed->yp_proto = NULL; - if (yp_match(yp_domain, "services.byname", buf, strlen(buf), - &result, &resultlen)) { + if (yp_match(sed->yp_domain, "services.byname", buf, strlen(buf), + &result, &resultlen)) { return(0); } /* getservent() expects lines terminated with \n -- make it happy */ - snprintf(line, BUFSIZ, "%.*s\n", resultlen, result); + snprintf(sed->line, BUFSIZ, "%.*s\n", resultlen, result); free(result); return(1); } static int -_getservent_yp(line) - char *line; +_getservent_yp(struct servent_data *sed) { - static char *key = NULL; - static int keylen; char *lastkey, *result; int resultlen; int rv; - if(!yp_domain) { - if(yp_get_default_domain(&yp_domain)) + if (!sed->yp_domain) { + if (yp_get_default_domain(&sed->yp_domain)) return (0); } - if (!serv_stepping_yp) { - if (key) - free(key); - if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen, - &result, &resultlen))) { - serv_stepping_yp = 0; + if (!sed->yp_stepping) { + free(sed->yp_key); + rv = yp_first(sed->yp_domain, "services.byname", &sed->yp_key, + &sed->yp_keylen, &result, &resultlen); + if (rv) { + sed->yp_stepping = 0; return(0); } - serv_stepping_yp = 1; + sed->yp_stepping = 1; } else { - lastkey = key; - rv = yp_next(yp_domain, "services.byname", key, keylen, &key, - &keylen, &result, &resultlen); + lastkey = sed->yp_key; + rv = yp_next(sed->yp_domain, "services.byname", sed->yp_key, + sed->yp_keylen, &sed->yp_key, &sed->yp_keylen, &result, + &resultlen); free(lastkey); if (rv) { - serv_stepping_yp = 0; + sed->yp_stepping = 0; return (0); } } /* getservent() expects lines terminated with \n -- make it happy */ - snprintf(line, BUFSIZ, "%.*s\n", resultlen, result); + snprintf(sed->line, BUFSIZ, "%.*s\n", resultlen, result); free(result); @@ -188,55 +228,56 @@ _getservent_yp(line) #endif void -setservent(f) - int f; +setservent_r(int f, struct servent_data *sed) { - if (servf == NULL) - servf = fopen(_PATH_SERVICES, "r" ); + if (sed->fp == NULL) + sed->fp = fopen(_PATH_SERVICES, "r"); else - rewind(servf); - _serv_stayopen |= f; + rewind(sed->fp); + sed->stayopen |= f; } void -endservent() +endservent_r(struct servent_data *sed) { - if (servf) { - fclose(servf); - servf = NULL; - } - _serv_stayopen = 0; + servent_data_clear(sed); + sed->stayopen = 0; +#ifdef YP + sed->yp_stepping = 0; + sed->yp_domain = NULL; +#endif } -struct servent * -getservent() +int +getservent_r(struct servent *se, struct servent_data *sed) { char *p; - char *cp, **q; + char *cp, **q, *endp; + long l; #ifdef YP - if (serv_stepping_yp && _getservent_yp(line)) { - p = (char *)&line; + if (sed->yp_stepping && _getservent_yp(sed)) { + p = sed->line; goto unpack; } tryagain: #endif - if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) - return (NULL); + if (sed->fp == NULL && (sed->fp = fopen(_PATH_SERVICES, "r")) == NULL) + return (-1); again: - if ((p = fgets(line, BUFSIZ, servf)) == NULL) - return (NULL); + if ((p = fgets(sed->line, BUFSIZ, sed->fp)) == NULL) + return (-1); #ifdef YP if (*p == '+' && _yp_check(NULL)) { - if (___getservbyname_yp != NULL) { - if (!_getservbyname_yp(line)) + if (sed->yp_name != NULL) { + if (!_getservbyname_yp(sed)) goto tryagain; } - else if (___getservbyport_yp != 0) { - if (!_getservbyport_yp(line)) + else if (sed->yp_port != 0) { + if (!_getservbyport_yp(sed)) goto tryagain; } - else if (!_getservent_yp(line)) + else if (!_getservent_yp(sed)) goto tryagain; } unpack: @@ -246,7 +287,7 @@ unpack: cp = strpbrk(p, "#\n"); if (cp != NULL) *cp = '\0'; - serv.s_name = p; + se->s_name = p; p = strpbrk(p, " \t"); if (p == NULL) goto again; @@ -257,9 +298,12 @@ unpack: if (cp == NULL) goto again; *cp++ = '\0'; - serv.s_port = htons((u_short)atoi(p)); - serv.s_proto = cp; - q = serv.s_aliases = serv_aliases; + l = strtol(p, &endp, 10); + if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX) + goto again; + se->s_port = htons((in_port_t)l); + se->s_proto = cp; + q = se->s_aliases = sed->aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; @@ -268,12 +312,44 @@ unpack: cp++; continue; } - if (q < &serv_aliases[MAXALIASES - 1]) + if (q < &sed->aliases[SERVENT_MAXALIASES - 1]) *q++ = cp; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; } *q = NULL; - return (&serv); + return (0); +} + +void +setservent(int f) +{ + struct servdata *sd; + + if ((sd = __servdata_init()) == NULL) + return; + setservent_r(f, &sd->data); +} + +void +endservent(void) +{ + struct servdata *sd; + + if ((sd = __servdata_init()) == NULL) + return; + endservent_r(&sd->data); +} + +struct servent * +getservent(void) +{ + struct servdata *sd; + + if ((sd = __servdata_init()) == NULL) + return (NULL); + if (getservent_r(&sd->serv, &sd->data) != 0) + return (NULL); + return (&sd->serv); } diff --git a/lib/libc/net/netdb_private.h b/lib/libc/net/netdb_private.h index 0b3278015ab0..a7cd4c9f55da 100644 --- a/lib/libc/net/netdb_private.h +++ b/lib/libc/net/netdb_private.h @@ -28,48 +28,15 @@ #ifndef _NETDB_PRIVATE_H_ #define _NETDB_PRIVATE_H_ -#include <stdio.h> /* XXX: for FILE */ +#include <stdio.h> /* XXX: for BUFSIZ */ -#define _MAXALIASES 35 -#define _MAXLINELEN 1024 -#define _MAXADDRS 35 -#define _HOSTBUFSIZE (8 * 1024) -#define _NETBUFSIZE 1025 - -struct hostent_data { - uint32_t host_addr[4]; /* IPv4 or IPv6 */ - char *h_addr_ptrs[_MAXADDRS + 1]; - char *host_aliases[_MAXALIASES]; - char hostbuf[_HOSTBUFSIZE]; - FILE *hostf; - int stayopen; -#ifdef YP - char *yp_domain; -#endif -}; - -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[_MAXALIASES]; - int stayopen; - char line[_MAXLINELEN + 1]; -}; +#define SERVENT_MAXALIASES 35 struct servent_data { FILE *fp; - char *aliases[_MAXALIASES]; + char *aliases[SERVENT_MAXALIASES]; int stayopen; - char line[_MAXLINELEN + 1]; + char line[BUFSIZ + 1]; #ifdef YP int yp_stepping; char *yp_name; @@ -81,89 +48,24 @@ struct servent_data { #endif }; -struct hostdata { - struct hostent host; - struct hostent_data data; -}; - -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 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 netdata *__netdata_init(void); -struct protodata *__protodata_init(void); struct servdata *__servdata_init(void); -void _endhostdnsent(void); -void _endhosthtent(struct hostent_data *); -void _endnetdnsent(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 *); -void _map_v4v6_hostent(struct hostent *, char **, char *); -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_ */ |
