summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2010-02-28 14:16:56 +0100
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2010-08-05 23:42:40 +0200
commit14c25c92be68a13d3ac94bdc46b16ba2590de4c9 (patch)
treea45ab103d0166a267e5a3a5e9f001f54e62bfc22
parent52f5c760d2a707c474cebc19d290f5a1f4ffb3d9 (diff)
getnet: switch to config parser
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
-rw-r--r--include/netdb.h11
-rw-r--r--libc/inet/Makefile.in2
-rw-r--r--libc/inet/getnet.c217
-rw-r--r--libc/inet/getnetbyad.c37
-rw-r--r--libc/inet/getnetbynm.c45
-rw-r--r--libc/inet/getnetent.c139
-rw-r--r--test/inet/getnetent.c17
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;
+}