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; +} |