diff options
| -rw-r--r-- | include/netdb.h | 11 | ||||
| -rw-r--r-- | libc/inet/Makefile.in | 2 | ||||
| -rw-r--r-- | libc/inet/getnet.c | 217 | ||||
| -rw-r--r-- | libc/inet/getnetbyad.c | 37 | ||||
| -rw-r--r-- | libc/inet/getnetbynm.c | 45 | ||||
| -rw-r--r-- | libc/inet/getnetent.c | 139 | ||||
| -rw-r--r-- | test/inet/getnetent.c | 17 | 
7 files changed, 239 insertions, 229 deletions
| diff --git a/include/netdb.h b/include/netdb.h index 9d3807d3a..07e1b0d0e 100644 --- a/include/netdb.h +++ b/include/netdb.h @@ -238,7 +238,6 @@ libc_hidden_proto(endnetent)     This function is a possible cancellation point and therefore not     marked with __THROW.  */  extern struct netent *getnetent (void); -libc_hidden_proto(getnetent)  /* Return entry from network data base which address match NET and     type TYPE. @@ -253,8 +252,6 @@ extern struct netent *getnetbyaddr (uint32_t __net, int __type);     marked with __THROW.  */  extern struct netent *getnetbyname (__const char *__name); -#if 0 -/* FIXME */  #ifdef	__USE_MISC  /* Reentrant versions of the functions above.  The additional     arguments specify a buffer of BUFLEN starting at BUF.  The last @@ -270,20 +267,20 @@ extern int getnetent_r (struct netent *__restrict __result_buf,  			char *__restrict __buf, size_t __buflen,  			struct netent **__restrict __result,  			int *__restrict __h_errnop); - +libc_hidden_proto(getnetent_r)  extern int getnetbyaddr_r (uint32_t __net, int __type,  			   struct netent *__restrict __result_buf,  			   char *__restrict __buf, size_t __buflen,  			   struct netent **__restrict __result,  			   int *__restrict __h_errnop); - +libc_hidden_proto(getnetbyaddr_r)  extern int getnetbyname_r (__const char *__restrict __name,  			   struct netent *__restrict __result_buf,  			   char *__restrict __buf, size_t __buflen,  			   struct netent **__restrict __result,  			   int *__restrict __h_errnop); -#endif	/* misc */ -#endif +libc_hidden_proto(getnetbyname_r) +#endif	/* __USE_MISC */  /* Description of data base entry for a single service.  */ diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in index 31b270f07..abcf2f7d7 100644 --- a/libc/inet/Makefile.in +++ b/libc/inet/Makefile.in @@ -17,7 +17,7 @@ CSRC-y :=  # des uses ntohl  CSRC-$(findstring y,$(UCLIBC_HAS_CRYPT_IMPL)$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += ntohl.c  CSRC-$(findstring y,$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += \ -	getservice.c getproto.c hostid.c getnetent.c getnetbynm.c getnetbyad.c \ +	getservice.c getproto.c getnet.c hostid.c \  	inet_net.c herror.c if_index.c gai_strerror.c getaddrinfo.c \  	ifaddrs.c ntop.c  CSRC-$(UCLIBC_HAS_IPV6) += in6_addr.c diff --git a/libc/inet/getnet.c b/libc/inet/getnet.c new file mode 100644 index 000000000..c604b63d3 --- /dev/null +++ b/libc/inet/getnet.c @@ -0,0 +1,217 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org> + * + * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + */ + +/* /etc/networks +#   network-name  number     [aliases ...] +loopback          127.0.0.0  # optional aliases + +network-name: symbolic name of the netwkork +number: official number of the network in dotted quad +aliases: case sensitive optional space or tab separated list of other names +*/ + +#include <features.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <unistd.h> +#include "internal/parse_config.h" + +#include <bits/uClibc_mutex.h> +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); + +#define	MAXALIASES	35 +#define BUFSZ		(80) /* one line */ +#define SBUFSIZE	(BUFSZ + 1 + (sizeof(char *) * MAXALIASES)) + +static parser_t *netp = NULL; +static struct netent nete; +static char *netbuf = NULL; +static smallint net_stayopen; + +void setnetent(int stayopen) +{ +	__UCLIBC_MUTEX_LOCK(mylock); +	if (netp) +		config_close(netp); +	netp = config_open(_PATH_NETWORKS); +	if (stayopen) +		net_stayopen = 1; +	__UCLIBC_MUTEX_UNLOCK(mylock); +} +libc_hidden_def(setnetent) + +void endnetent(void) +{ +	__UCLIBC_MUTEX_LOCK(mylock); +	if (netp) { +		config_close(netp); +		netp = NULL; +	} +	net_stayopen = 0; +	__UCLIBC_MUTEX_UNLOCK(mylock); +} +libc_hidden_def(endnetent) + +int getnetent_r(struct netent *result_buf, +				char *buf, size_t buflen, struct netent **result, +				int *h_errnop +				 ) +{ +	char **alias, *cp = NULL; +	char **net_aliases; +	char **tok = NULL; +	const size_t aliaslen = sizeof(*net_aliases) * MAXALIASES; +	int ret = ERANGE; + +	*result = NULL; +	if (buflen < aliaslen +		|| (buflen - aliaslen) < BUFSZ + 1) +		goto DONE_NOUNLOCK; + +	__UCLIBC_MUTEX_LOCK(mylock); +	ret = ENOENT; +	if (netp == NULL) +		setnetent(net_stayopen); +	if (netp == NULL) +		goto DONE; +	netp->data = buf; +	netp->data_len = aliaslen; +	netp->line_len = buflen - aliaslen; +	/* <name>[[:space:]]<netnumber>[[:space:]][<aliases>] */ +	if (!config_read(netp, &tok, 3, 2, "# \t/", PARSE_NORMAL)) { +		goto DONE; +	} +	result_buf->n_name = *(tok++); +	{ +		struct addrinfo hints, *addri; +# define sa4_to_uint32(sa) \ +	(ntohl(((struct sockaddr_in*)sa)->sin_addr.s_addr)) +#ifdef __UCLIBC_HAS_IPV6__ +# define sa6_to_uint8(sa) \ +	(ntohl(((struct sockaddr_in6*)sa)->sin6_addr.s6_addr)) +#endif +		memset(&hints, 0, sizeof(struct addrinfo)); +		hints.ai_family = AF_UNSPEC; +		hints.ai_flags = AI_NUMERICHOST; +		getaddrinfo(*(tok++), NULL, &hints, &addri); +		result_buf->n_addrtype = addri->ai_family; +		result_buf->n_net = +#if 0 /*FIXME: implement me! def __UCLIBC_HAS_IPV6__ */ +			addri->ai_family == AF_INET6 ? sa6_to_uint8(addri->ai_addr) : +#endif +			sa4_to_uint32(addri->ai_addr); +		freeaddrinfo(addri); +	} +	result_buf->n_aliases = alias = net_aliases = tok; +	cp = *alias; +	while (cp && *cp) { +		if (alias < &net_aliases[MAXALIASES - 1]) +			*alias++ = cp; +		cp = strpbrk(cp, " \t"); +		if (cp != NULL) +			*cp++ = '\0'; +	} +	*alias = NULL; +	*result = result_buf; +	ret = 0; + DONE: +	__UCLIBC_MUTEX_UNLOCK(mylock); + DONE_NOUNLOCK: +	errno = ret; +	return errno; +} +libc_hidden_def(getnetent_r) + +static void __initbuf(void) +{ +	if (!netbuf) { +		netbuf = malloc(SBUFSIZE); +		if (!netbuf) +			abort(); +	} +} + +struct netent *getnetent(void) +{ +	struct netent *result; +	int herrnop; + +	__initbuf(); +	getnetent_r(&nete, netbuf, SBUFSIZE, &result, &herrnop); +	return result; +} + +int getnetbyname_r(const char *name, +					struct netent *result_buf, char *buf, size_t buflen, +					struct netent **result, +					int *h_errnop +					) +{ +	register char **cp; +	int ret, herrnop; + +	__UCLIBC_MUTEX_LOCK(mylock); +	setnetent(net_stayopen); +	while (!(ret = getnetent_r(result_buf, buf, buflen, result, &herrnop))) { +		if (strcmp(name, result_buf->n_name) == 0) +			break; +		for (cp = result_buf->n_aliases; *cp; cp++) +			if (strcmp(name, *cp) == 0) +				goto gotname; +	} + gotname: +	if (!net_stayopen) +		endnetent(); +	__UCLIBC_MUTEX_UNLOCK(mylock); +	return *result ? 0 : ret; +} +libc_hidden_def(getnetbyname_r) + +struct netent *getnetbyname(const char *name) +{ +	struct netent *result; +	int herrnop; + +	__initbuf(); +	getnetbyname_r(name, &nete, netbuf, SBUFSIZE, &result, &herrnop); +	return result; +} + +int getnetbyaddr_r(uint32_t net, int type, +					struct netent *result_buf, char *buf, +					size_t buflen, struct netent **result, +					int *h_errnop) +{ +	int ret, herrnop; + +	__UCLIBC_MUTEX_LOCK(mylock); +	setnetent(net_stayopen); +	while (!(ret = getnetent_r(result_buf, buf, buflen, result, &herrnop))) { +		if (net == result_buf->n_net && type == result_buf->n_addrtype) +			break; +	} +	if (!net_stayopen) +		endnetent(); +	__UCLIBC_MUTEX_UNLOCK(mylock); +	return *result ? 0 : ret; +} +libc_hidden_def(getnetbyaddr_r) + +struct netent *getnetbyaddr(uint32_t net, int type) +{ +	struct netent *result; +	int herrnop; + +	__initbuf(); +	getnetbyaddr_r(net, type, &nete, netbuf, SBUFSIZE, &result, &herrnop); +	return result; +} + diff --git a/libc/inet/getnetbyad.c b/libc/inet/getnetbyad.c deleted file mode 100644 index a4af1a844..000000000 --- a/libc/inet/getnetbyad.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley.  The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define __FORCE_GLIBC -#include <features.h> -#include <netdb.h> -#include <unistd.h> - - -extern smallint _net_stayopen attribute_hidden; - -struct netent *getnetbyaddr (uint32_t net, int type) -{ -	register struct netent *p; - -	setnetent(_net_stayopen); -	while ((p = getnetent())) -		if (p->n_addrtype == type && p->n_net == net) -			break; -	if (!_net_stayopen) -		endnetent(); -	return (p); -} diff --git a/libc/inet/getnetbynm.c b/libc/inet/getnetbynm.c deleted file mode 100644 index eab04045b..000000000 --- a/libc/inet/getnetbynm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley.  The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define __FORCE_GLIBC -#include <features.h> -#include <netdb.h> -#include <string.h> -#include <unistd.h> - - -extern smallint _net_stayopen attribute_hidden; - -struct netent * -getnetbyname(const char *name) -{ -	register struct netent *p; -	register char **cp; - -	setnetent(_net_stayopen); -	while ((p = getnetent())) { -		if (strcmp(p->n_name, name) == 0) -			break; -		for (cp = p->n_aliases; *cp != 0; cp++) -			if (strcmp(*cp, name) == 0) -				goto found; -	} -found: -	if (!_net_stayopen) -		endnetent(); -	return (p); -} diff --git a/libc/inet/getnetent.c b/libc/inet/getnetent.c deleted file mode 100644 index e9b45ba7e..000000000 --- a/libc/inet/getnetent.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley.  The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define __FORCE_GLIBC -#include <features.h> -#include <stdio.h> -#include <stdlib.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <unistd.h> - - -#include <bits/uClibc_mutex.h> -__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - - -#define	MAXALIASES	35 -static const char NETDB[] = _PATH_NETWORKS; -static FILE *netf = NULL; -static char *line = NULL; -static struct netent net; -static char *net_aliases[MAXALIASES]; - -smallint _net_stayopen attribute_hidden; - -void setnetent(int f) -{ -    __UCLIBC_MUTEX_LOCK(mylock); -    if (netf == NULL) -	netf = fopen(NETDB, "r" ); -    else -	rewind(netf); -    if (f) _net_stayopen = 1; -    __UCLIBC_MUTEX_UNLOCK(mylock); -    return; -} -libc_hidden_def(setnetent) - -void endnetent(void) -{ -    __UCLIBC_MUTEX_LOCK(mylock); -    if (netf) { -	fclose(netf); -	netf = NULL; -    } -    _net_stayopen = 0; -    __UCLIBC_MUTEX_UNLOCK(mylock); -} -libc_hidden_def(endnetent) - -static char * any(register char *cp, char *match) -{ -    register char *mp, c; - -    while ((c = *cp)) { -	for (mp = match; *mp; mp++) -	    if (*mp == c) -		return (cp); -	cp++; -    } -    return ((char *)0); -} - -struct netent *getnetent(void) -{ -    char *p; -    register char *cp, **q; -    struct netent *rv = NULL; - -    __UCLIBC_MUTEX_LOCK(mylock); -    if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL) { -	goto DONE; -    } -again: - -    if (!line) { -	line = malloc(BUFSIZ + 1); -	if (!line) -	    abort(); -    } - -    p = fgets(line, BUFSIZ, netf); -    if (p == NULL) { -	goto DONE; -    } -    if (*p == '#') -	goto again; -    cp = any(p, "#\n"); -    if (cp == NULL) -	goto again; -    *cp = '\0'; -    net.n_name = p; -    cp = any(p, " \t"); -    if (cp == NULL) -	goto again; -    *cp++ = '\0'; -    while (*cp == ' ' || *cp == '\t') -	cp++; -    p = any(cp, " \t"); -    if (p != NULL) -	*p++ = '\0'; -    net.n_net = inet_network(cp); -    net.n_addrtype = AF_INET; -    q = net.n_aliases = net_aliases; -    if (p != NULL) -	cp = p; -    while (cp && *cp) { -	if (*cp == ' ' || *cp == '\t') { -	    cp++; -	    continue; -	} -	if (q < &net_aliases[MAXALIASES - 1]) -	    *q++ = cp; -	cp = any(cp, " \t"); -	if (cp != NULL) -	    *cp++ = '\0'; -    } -    *q = NULL; -    rv = &net; -DONE: -    __UCLIBC_MUTEX_UNLOCK(mylock); -    return rv; -} -libc_hidden_def(getnetent) diff --git a/test/inet/getnetent.c b/test/inet/getnetent.c new file mode 100644 index 000000000..6607cea9a --- /dev/null +++ b/test/inet/getnetent.c @@ -0,0 +1,17 @@ +#include <stdio.h> +#include <netdb.h> +int main(void) +{ +	struct netent *net; +	setnetent(0); +	while ((net = getnetent())) { +		while (net->n_net && !((net->n_net >> 24) & 0xff)) { +			net->n_net <<= 8; +		} +		printf("%lu.%lu.%lu.%lu\n", +			   (net->n_net >> 24) & 0xff, (net->n_net >> 16) & 0xff, +			   (net->n_net >> 8) & 0xff, net->n_net & 0xff); +	} +	endnetent(); +	return 0; +} | 
