OSDN Git Service

getnet: switch to config parser
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Sun, 28 Feb 2010 13:16:56 +0000 (14:16 +0100)
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Thu, 5 Aug 2010 21:42:40 +0000 (23:42 +0200)
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
include/netdb.h
libc/inet/Makefile.in
libc/inet/getnet.c [new file with mode: 0644]
libc/inet/getnetbyad.c [deleted file]
libc/inet/getnetbynm.c [deleted file]
libc/inet/getnetent.c [deleted file]
test/inet/getnetent.c [new file with mode: 0644]

index 9d3807d..07e1b0d 100644 (file)
@@ -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.  */
index 31b270f..abcf2f7 100644 (file)
@@ -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 (file)
index 0000000..c604b63
--- /dev/null
@@ -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 (file)
index a4af1a8..0000000
+++ /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 (file)
index eab0404..0000000
+++ /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 (file)
index e9b45ba..0000000
+++ /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 (file)
index 0000000..6607cea
--- /dev/null
@@ -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;
+}