[PATCH 5/7] getproto: switch to config parser

Bernhard Reutner-Fischer rep.dot.nop at gmail.com
Fri Apr 16 09:35:53 UTC 2010


Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
---
 libc/inet/getproto.c |  349 ++++++++++++++++++++------------------------------
 1 files changed, 137 insertions(+), 212 deletions(-)

diff --git a/libc/inet/getproto.c b/libc/inet/getproto.c
index bf7c093..bcf507b 100644
--- a/libc/inet/getproto.c
+++ b/libc/inet/getproto.c
@@ -1,266 +1,191 @@
+/* vi: set sw=4 ts=4: */
 /*
-** protocols.c                           /etc/protocols access functions
-**
-** This file is part of the NYS Library.
-**
-** The NYS Library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Library General Public License as
-** published by the Free Software Foundation; either version 2 of the
-** License, or (at your option) any later version.
-**
-** The NYS Library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** Library General Public License for more details.
-**
-** You should have received a copy of the GNU Library General Public
-** License along with the NYS Library; see the file COPYING.LIB.  If
-** not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-** Cambridge, MA 02139, USA.
-**
-**
-** Copyright (c) 1983 Regents of the University of California.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions
-** are met:
-** 1. Redistributions of source code must retain the above copyright
-**    notice, this list of conditions and the following disclaimer.
-** 2. Redistributions in binary form must reproduce the above copyright
-**    notice, this list of conditions and the following disclaimer in the
-**    documentation and/or other materials provided with the distribution.
-** 3. All advertising materials mentioning features or use of this software
-**    must display the following acknowledgement:
-**	This product includes software developed by the University of
-**	California, Berkeley and its contributors.
-** 4. Neither the name of the University nor the names of its contributors
-**    may be used to endorse or promote products derived from this software
-**    without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-** ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-** SUCH DAMAGE.
+ * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc at uclibc.org>
+ *
+ * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+/* /etc/protocols
+#   protocol-name   number   [aliases ...]
+ip                  0        IP  # internet protocol, pseudo protocol number
+
+protocol-name: case sensitive friendly name of the IP protocol
+number: decimal protocol number
+aliases: case sensitive optional space or tab separated list of other names
 */
 
-#define __FORCE_GLIBC
 #include <features.h>
-#include <sys/types.h>
-#include <sys/socket.h>
 #include <netdb.h>
-#include <stdio.h>
-#include <stdlib.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	SBUFSIZE	(BUFSIZ + 1 + (sizeof(char *) * MAXALIASES))
+#define BUFSZ		(80) /* one line */
+#define SBUFSIZE	(BUFSZ + 1 + (sizeof(char *) * MAXALIASES))
 
-static FILE *protof = NULL;
-static struct protoent proto;
-static char *static_aliases = NULL;
+static parser_t *protop = NULL;
+static struct protoent protoe;
+static char *protobuf = NULL;
 static smallint proto_stayopen;
 
-static void __initbuf(void)
+void setprotoent(int stayopen)
 {
-    if (!static_aliases) {
-	static_aliases = malloc(SBUFSIZE);
-	if (!static_aliases)
-	    abort();
-    }
-}
-
-void setprotoent(int f)
-{
-    __UCLIBC_MUTEX_LOCK(mylock);
-    if (protof == NULL)
-	protof = fopen(_PATH_PROTOCOLS, "r" );
-    else
-	rewind(protof);
-    if (f) proto_stayopen = 1;
-    __UCLIBC_MUTEX_UNLOCK(mylock);
+	__UCLIBC_MUTEX_LOCK(mylock);
+	if (protop)
+		config_close(protop);
+	protop = config_open(_PATH_PROTOCOLS);
+	if (stayopen)
+		proto_stayopen = 1;
+	__UCLIBC_MUTEX_UNLOCK(mylock);
 }
 libc_hidden_def(setprotoent)
 
 void endprotoent(void)
 {
-    __UCLIBC_MUTEX_LOCK(mylock);
-    if (protof) {
-	fclose(protof);
-	protof = NULL;
-    }
-    proto_stayopen = 0;
-    __UCLIBC_MUTEX_UNLOCK(mylock);
+	__UCLIBC_MUTEX_LOCK(mylock);
+	if (protop) {
+		config_close(protop);
+		protop = NULL;
+	}
+	proto_stayopen = 0;
+	__UCLIBC_MUTEX_UNLOCK(mylock);
 }
 libc_hidden_def(endprotoent)
 
 int getprotoent_r(struct protoent *result_buf,
-		  char *buf, size_t buflen,
-		  struct protoent **result)
+				 char *buf, size_t buflen, struct protoent **result)
 {
-    char *p;
-    register char *cp, **q;
-    char **proto_aliases;
-    char *line;
-    int rv;
-
-    *result = NULL;
-
-    if (buflen < sizeof(*proto_aliases)*MAXALIASES) {
-	errno=ERANGE;
-	return errno;
-    }
-    __UCLIBC_MUTEX_LOCK(mylock);
-    proto_aliases=(char **)buf;
-    buf+=sizeof(*proto_aliases)*MAXALIASES;
-    buflen-=sizeof(*proto_aliases)*MAXALIASES;
-
-    if (buflen < BUFSIZ+1) {
-	errno=rv=ERANGE;
-	goto DONE;
-    }
-    line=buf;
-    buf+=BUFSIZ+1;
-    buflen-=BUFSIZ+1;
-
-    if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) {
-	rv=errno;
-	goto DONE;
-    }
-again:
-    if ((p = fgets(line, BUFSIZ, protof)) == NULL) {
-	rv=ENOENT;
-	goto DONE;
-    }
-
-    if (*p == '#')
-	goto again;
-    cp = strpbrk(p, "#\n");
-    if (cp == NULL)
-	goto again;
-    *cp = '\0';
-    result_buf->p_name = p;
-    cp = strpbrk(p, " \t");
-    if (cp == NULL)
-	goto again;
-    *cp++ = '\0';
-    while (*cp == ' ' || *cp == '\t')
-	cp++;
-    p = strpbrk(cp, " \t");
-    if (p != NULL)
-	*p++ = '\0';
-    result_buf->p_proto = atoi(cp);
-    q = result_buf->p_aliases = proto_aliases;
-    if (p != NULL) {
-	cp = p;
+	char **alias, *cp = NULL;
+	char **proto_aliases;
+	char **tok = NULL;
+	const size_t aliaslen = sizeof(*proto_aliases) * MAXALIASES;
+	int ret = ERANGE;
+
+	*result = NULL;
+	if (buflen < aliaslen
+		|| (buflen - aliaslen) < BUFSZ + 1)
+		goto DONE_NOUNLOCK;
+
+	__UCLIBC_MUTEX_LOCK(mylock);
+	//tok = (char **) buf;
+	ret = ENOENT;
+	if (protop == NULL)
+		setprotoent(proto_stayopen);
+	if (protop == NULL)
+		goto DONE;
+	protop->data = buf;
+	protop->data_len = aliaslen;
+	protop->line_len = buflen - aliaslen;
+	/* <name>[[:space:]]<protonumber>[[:space:]][<aliases>] */
+	if (!config_read(protop, &tok, 3, 2, "# \t/", PARSE_NORMAL)) {
+		goto DONE;
+	}
+	result_buf->p_name = *(tok++);
+	result_buf->p_proto = atoi(*(tok++));
+	result_buf->p_aliases = alias = proto_aliases = tok;
+	cp = *alias;
 	while (cp && *cp) {
-	    if (*cp == ' ' || *cp == '\t') {
-		cp++;
-		continue;
-	    }
-	    if (q < &proto_aliases[MAXALIASES - 1])
-		*q++ = cp;
-	    cp = strpbrk(cp, " \t");
-	    if (cp != NULL)
-		*cp++ = '\0';
+		if (alias < &proto_aliases[MAXALIASES - 1])
+			*alias++ = cp;
+		cp = strpbrk(cp, " \t");
+		if (cp != NULL)
+			*cp++ = '\0';
 	}
-    }
-    *q = NULL;
-    *result=result_buf;
-    rv = 0;
-DONE:
-    __UCLIBC_MUTEX_UNLOCK(mylock);
-    return rv;
+	*alias = NULL;
+	*result = result_buf;
+	ret = 0;
+ DONE:
+	__UCLIBC_MUTEX_UNLOCK(mylock);
+ DONE_NOUNLOCK:
+	errno = ret;
+	return errno;
 }
 libc_hidden_def(getprotoent_r)
 
-struct protoent * getprotoent(void)
+static void __initbuf(void)
 {
-    struct protoent *result;
-
-    __initbuf();
-    getprotoent_r(&proto, static_aliases, SBUFSIZE, &result);
-    return result;
+	if (!protobuf) {
+		protobuf = malloc(SBUFSIZE);
+		if (!protobuf)
+			abort();
+	}
 }
 
+struct protoent *getprotoent(void)
+{
+	struct protoent *result;
+
+	__initbuf();
+	getprotoent_r(&protoe, protobuf, SBUFSIZE, &result);
+	return result;
+}
 
 int getprotobyname_r(const char *name,
-		    struct protoent *result_buf,
-		    char *buf, size_t buflen,
-		    struct protoent **result)
+					struct protoent *result_buf, char *buf, size_t buflen,
+					struct protoent **result)
 {
-    register char **cp;
-    int ret;
-
-    __UCLIBC_MUTEX_LOCK(mylock);
-    setprotoent(proto_stayopen);
-    while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) {
-	if (strcmp(result_buf->p_name, name) == 0)
-	    break;
-	for (cp = result_buf->p_aliases; *cp != 0; cp++)
-	    if (strcmp(*cp, name) == 0)
-		goto found;
-    }
-found:
-    if (!proto_stayopen)
-	endprotoent();
-    __UCLIBC_MUTEX_UNLOCK(mylock);
-    return *result?0:ret;
+	register char **cp;
+	int ret;
+
+	__UCLIBC_MUTEX_LOCK(mylock);
+	setprotoent(proto_stayopen);
+	while (!(ret = getprotoent_r(result_buf, buf, buflen, result))) {
+		if (strcmp(name, result_buf->p_name) == 0)
+			break;
+		for (cp = result_buf->p_aliases; *cp; cp++)
+			if (strcmp(name, *cp) == 0)
+				goto gotname;
+	}
+ gotname:
+	if (!proto_stayopen)
+		endprotoent();
+	__UCLIBC_MUTEX_UNLOCK(mylock);
+	return *result ? 0 : ret;
 }
 libc_hidden_def(getprotobyname_r)
 
-
-struct protoent * getprotobyname(const char *name)
+struct protoent *getprotobyname(const char *name)
 {
-    struct protoent *result;
+	struct protoent *result;
 
-    __initbuf();
-    getprotobyname_r(name, &proto, static_aliases, SBUFSIZE, &result);
-    return result;
+	__initbuf();
+	getprotobyname_r(name, &protoe, protobuf, SBUFSIZE, &result);
+	return result;
 }
 
-
-int getprotobynumber_r (int proto_num,
-			struct protoent *result_buf,
-			char *buf, size_t buflen,
-			struct protoent **result)
+int getprotobynumber_r(int proto,
+					struct protoent *result_buf, char *buf,
+					size_t buflen, struct protoent **result)
 {
-    int ret;
+	int ret;
 
-    __UCLIBC_MUTEX_LOCK(mylock);
-    setprotoent(proto_stayopen);
-    while (!(ret=getprotoent_r(result_buf, buf, buflen, result)))
-	if (result_buf->p_proto == proto_num)
-	    break;
-    if (!proto_stayopen)
-	endprotoent();
-    __UCLIBC_MUTEX_UNLOCK(mylock);
-    return *result?0:ret;
+	__UCLIBC_MUTEX_LOCK(mylock);
+	setprotoent(proto_stayopen);
+	while (!(ret = getprotoent_r(result_buf, buf, buflen, result))) {
+		if (proto == result_buf->p_proto)
+			break;
+	}
+	if (!proto_stayopen)
+		endprotoent();
+	__UCLIBC_MUTEX_UNLOCK(mylock);
+	return *result ? 0 : ret;
 }
 libc_hidden_def(getprotobynumber_r)
 
-struct protoent * getprotobynumber(int proto_num)
+struct protoent *getprotobynumber(int proto)
 {
-    struct protoent *result;
+	struct protoent *result;
 
-    __initbuf();
-    getprotobynumber_r(proto_num, &proto, static_aliases,
-                       SBUFSIZE, &result);
-    return result;
+	__initbuf();
+	getprotobynumber_r(proto, &protoe, protobuf, SBUFSIZE, &result);
+	return result;
 }
 
-- 
1.7.0



More information about the uClibc mailing list