[PATCH 3/7] switch getservice to config parser

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


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

diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c
index 6d80a1b..03f5c29 100644
--- a/libc/inet/getservice.c
+++ b/libc/inet/getservice.c
@@ -1,271 +1,198 @@
+/* vi: set sw=4 ts=4: */
 /*
-** services.c                           /etc/services 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/services
+#   service-name   port/protocol   [aliases ...]
+discard               9/udp        sink null
+
+service-name: case sensitive friendly name of the service
+port: decimal port number
+protocol: protocols(5) compatible entry
+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 <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 *servf = NULL;
-static struct servent serv;
+static parser_t *servp = NULL;
+static struct servent serve;
 static char *servbuf = NULL;
 static smallint serv_stayopen;
 
-static void __initbuf(void)
-{
-    if (!servbuf) {
-	servbuf = malloc(SBUFSIZE);
-	if (!servbuf)
-	    abort();
-    }
-}
-
-void setservent(int f)
+void setservent(int stayopen)
 {
-    __UCLIBC_MUTEX_LOCK(mylock);
-    if (servf == NULL)
-	servf = fopen(_PATH_SERVICES, "r" );
-    else
-	rewind(servf);
-    if (f) serv_stayopen = 1;
-    __UCLIBC_MUTEX_UNLOCK(mylock);
+	__UCLIBC_MUTEX_LOCK(mylock);
+	if (servp)
+		config_close(servp);
+	servp = config_open(_PATH_SERVICES);
+	if (stayopen)
+		serv_stayopen = 1;
+	__UCLIBC_MUTEX_UNLOCK(mylock);
 }
 libc_hidden_def(setservent)
 
 void endservent(void)
 {
-    __UCLIBC_MUTEX_LOCK(mylock);
-    if (servf) {
-	fclose(servf);
-	servf = NULL;
-    }
-    serv_stayopen = 0;
-    __UCLIBC_MUTEX_UNLOCK(mylock);
+	__UCLIBC_MUTEX_LOCK(mylock);
+	if (servp) {
+		config_close(servp);
+		servp = NULL;
+	}
+	serv_stayopen = 0;
+	__UCLIBC_MUTEX_UNLOCK(mylock);
 }
 libc_hidden_def(endservent)
 
-int getservent_r(struct servent * result_buf,
-		 char * buf, size_t buflen,
-		 struct servent ** result)
+int getservent_r(struct servent *result_buf,
+				 char *buf, size_t buflen, struct servent **result)
 {
-    char *p;
-    register char *cp, **q;
-    char **serv_aliases;
-    char *line;
-    int rv;
-
-    *result=NULL;
-
-    if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
-	errno=ERANGE;
+	char **alias, *cp = NULL;
+	char **serv_aliases;
+	char **tok = NULL;
+	const size_t aliaslen = sizeof(*serv_aliases) * MAXALIASES;
+	int ret = ERANGE;
+
+	*result = NULL;
+	if (buflen < aliaslen
+		|| (buflen - aliaslen) < BUFSZ + 1)
+		goto DONE_NOUNLOCK;
+
+	__UCLIBC_MUTEX_LOCK(mylock);
+	ret = ENOENT;
+	if (servp == NULL)
+		setservent(serv_stayopen);
+	if (servp == NULL)
+		goto DONE;
+	servp->data = buf;
+	servp->data_len = aliaslen;
+	servp->line_len = buflen - aliaslen;
+	/* <name>[[:space:]]<port>/<proto>[[:space:]][<aliases>] */
+	if (!config_read(servp, &tok, 4, 3, "# \t/", PARSE_NORMAL)) {
+		goto DONE;
+	}
+	result_buf->s_name = *(tok++);
+	result_buf->s_port = htons((u_short) atoi(*(tok++)));
+	result_buf->s_proto = *(tok++);
+	result_buf->s_aliases = alias = serv_aliases = tok;
+	cp = *alias;
+	while (cp && *cp) {
+		if (alias < &serv_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;
-    }
-    __UCLIBC_MUTEX_LOCK(mylock);
-    serv_aliases=(char **)buf;
-    buf+=sizeof(*serv_aliases)*MAXALIASES;
-    buflen-=sizeof(*serv_aliases)*MAXALIASES;
-
-    if (buflen < BUFSIZ+1) {
-	errno=rv=ERANGE;
-	goto DONE;
-    }
-    line=buf;
-    buf+=BUFSIZ+1;
-    buflen-=BUFSIZ+1;
+}
+libc_hidden_def(getservent_r)
 
-    if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
-	errno=rv=EIO;
-	goto DONE;
-    }
-again:
-    if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
-	errno=rv=EIO;
-	goto DONE;
-    }
-    if (*p == '#')
-	goto again;
-    cp = strpbrk(p, "#\n");
-    if (cp == NULL)
-	goto again;
-    *cp = '\0';
-    result_buf->s_name = p;
-    p = strpbrk(p, " \t");
-    if (p == NULL)
-	goto again;
-    *p++ = '\0';
-    while (*p == ' ' || *p == '\t')
-	p++;
-    cp = strpbrk(p, ",/");
-    if (cp == NULL)
-	goto again;
-    *cp++ = '\0';
-    result_buf->s_port = htons((u_short)atoi(p));
-    result_buf->s_proto = cp;
-    q = result_buf->s_aliases = serv_aliases;
-    cp = strpbrk(cp, " \t");
-    if (cp != NULL)
-	*cp++ = '\0';
-    while (cp && *cp) {
-	if (*cp == ' ' || *cp == '\t') {
-	    cp++;
-	    continue;
+static void __initbuf(void)
+{
+	if (!servbuf) {
+		servbuf = malloc(SBUFSIZE);
+		if (!servbuf)
+			abort();
 	}
-	if (q < &serv_aliases[MAXALIASES - 1])
-	    *q++ = cp;
-	cp = strpbrk(cp, " \t");
-	if (cp != NULL)
-	    *cp++ = '\0';
-    }
-    *q = NULL;
-    *result=result_buf;
-    rv = 0;
-DONE:
-    __UCLIBC_MUTEX_UNLOCK(mylock);
-    return rv;
 }
-libc_hidden_def(getservent_r)
 
-struct servent * getservent(void)
+struct servent *getservent(void)
 {
-    struct servent *result;
+	struct servent *result;
 
-    __initbuf();
-    getservent_r(&serv, servbuf, SBUFSIZE, &result);
-    return result;
+	__initbuf();
+	getservent_r(&serve, servbuf, SBUFSIZE, &result);
+	return result;
 }
 
 int getservbyname_r(const char *name, const char *proto,
-	struct servent * result_buf, char * buf, size_t buflen,
-	struct servent ** result)
+					struct servent *result_buf, char *buf, size_t buflen,
+					struct servent **result)
 {
-    register char **cp;
-    int ret;
-
-    __UCLIBC_MUTEX_LOCK(mylock);
-    setservent(serv_stayopen);
-    while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
-	if (strcmp(name, result_buf->s_name) == 0)
-	    goto gotname;
-	for (cp = result_buf->s_aliases; *cp; cp++)
-	    if (strcmp(name, *cp) == 0)
-		goto gotname;
-	continue;
-gotname:
-	if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
-	    break;
-    }
-    if (!serv_stayopen)
-	endservent();
-    __UCLIBC_MUTEX_UNLOCK(mylock);
-    return *result?0:ret;
+	register char **cp;
+	int ret;
+
+	__UCLIBC_MUTEX_LOCK(mylock);
+	setservent(serv_stayopen);
+	while (!(ret = getservent_r(result_buf, buf, buflen, result))) {
+		if (strcmp(name, result_buf->s_name) == 0)
+			goto gotname;
+		for (cp = result_buf->s_aliases; *cp; cp++)
+			if (strcmp(name, *cp) == 0)
+				goto gotname;
+		continue;
+ gotname:
+		if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+			break;
+	}
+	if (!serv_stayopen)
+		endservent();
+	__UCLIBC_MUTEX_UNLOCK(mylock);
+	return *result ? 0 : ret;
 }
 libc_hidden_def(getservbyname_r)
 
 struct servent *getservbyname(const char *name, const char *proto)
 {
-    struct servent *result;
+	struct servent *result;
 
-    __initbuf();
-    getservbyname_r(name, proto, &serv, servbuf, SBUFSIZE, &result);
-    return result;
+	__initbuf();
+	getservbyname_r(name, proto, &serve, servbuf, SBUFSIZE, &result);
+	return result;
 }
 
 
 int getservbyport_r(int port, const char *proto,
-	struct servent * result_buf, char * buf,
-	size_t buflen, struct servent ** result)
+					struct servent *result_buf, char *buf,
+					size_t buflen, struct servent **result)
 {
-    int ret;
-
-    __UCLIBC_MUTEX_LOCK(mylock);
-    setservent(serv_stayopen);
-    while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
-	if (result_buf->s_port != port)
-	    continue;
-	if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
-	    break;
-    }
-    if (!serv_stayopen)
-	endservent();
-    __UCLIBC_MUTEX_UNLOCK(mylock);
-    return *result?0:ret;
+	int ret;
+
+	__UCLIBC_MUTEX_LOCK(mylock);
+	setservent(serv_stayopen);
+	while (!(ret = getservent_r(result_buf, buf, buflen, result))) {
+		if (result_buf->s_port != port)
+			continue;
+		if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+			break;
+	}
+	if (!serv_stayopen)
+		endservent();
+	__UCLIBC_MUTEX_UNLOCK(mylock);
+	return *result ? 0 : ret;
 }
 libc_hidden_def(getservbyport_r)
 
-struct servent * getservbyport(int port, const char *proto)
+struct servent *getservbyport(int port, const char *proto)
 {
-    struct servent *result;
+	struct servent *result;
 
-    __initbuf();
-    getservbyport_r(port, proto, &serv, servbuf, SBUFSIZE, &result);
-    return result;
+	__initbuf();
+	getservbyport_r(port, proto, &serve, servbuf, SBUFSIZE, &result);
+	return result;
 }
 libc_hidden_def(getservbyport)
-- 
1.7.0



More information about the uClibc mailing list