Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Jul 2005 13:42:18 GMT
From:      soc-bushman <soc-bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 80260 for review
Message-ID:  <200507151342.j6FDgIlA097598@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=80260

Change 80260 by soc-bushman@soc-bushman_stinger on 2005/07/15 13:42:14

	rpc finished - patch and testing

Affected files ...

.. //depot/projects/soc2005/nsswitch_cached/src/include/rpc/rpcent.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/rpc/getrpcent.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/Makefile#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/getrpcent.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/getrpcent.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/getrpcent_test.c#2 edit

Differences ...

==== //depot/projects/soc2005/nsswitch_cached/src/include/rpc/rpcent.h#2 (text+ko) ====

@@ -53,12 +53,13 @@
 };
 
 __BEGIN_DECLS
-extern struct rpcent *getrpcbyname_r(const char *, struct rpcent *,
-				     char *, int);
-extern struct rpcent *getrpcbynumber_r(int, struct rpcent *, char *, int);
-extern struct rpcent *getrpcent_r(struct rpcent *, char *, int);
-
-/* Old interfaces that return a pointer to a static area;  MT-unsafe */
+extern int getrpcbyname_r(const char *, struct rpcent *, char *, size_t, 
+	struct rpcent **);
+extern int getrpcbynumber_r(int, struct rpcent *, char *, size_t, 
+	struct rpcent **);
+extern int getrpcent_r(struct rpcent *, char *, size_t, struct rpcent **);
+		
+/* These interfaces are currently implemented through nsswitch and MT-safe */
 extern struct rpcent *getrpcbyname(char *);
 extern struct rpcent *getrpcbynumber(int);
 extern struct rpcent *getrpcent(void);

==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/rpc/getrpcent.c#2 (text+ko) ====

@@ -40,281 +40,740 @@
  * Copyright (c) 1984 by Sun Microsystems, Inc.
  */
 
-#include "namespace.h"
+#include "getrpcent.h"
+
+#include <sys/param.h>
 #include <sys/types.h>
-
-#include <netinet/in.h>
+#include <sys/socket.h>
 #include <arpa/inet.h>
-
 #include <assert.h>
-#include <netdb.h>
+#include <errno.h>
+#include <nsswitch.h>
+#include <netinet/in.h>
 #include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
 #include <stdlib.h>
-#include <string.h>
-
 #include <rpc/rpc.h>
 #ifdef YP
 #include <rpcsvc/yp_prot.h>
 #include <rpcsvc/ypclnt.h>
 #endif
+#include <unistd.h>
+#include "namespace.h"
+#include "reentrant.h"
 #include "un-namespace.h"
 #include "libc_private.h"
+#include "nss_tls.h"
+
+#define	RPCDB	"/etc/rpc"
+
+/* nsswitch declarations */
+enum constants 
+{
+	SETRPCENT = 1,
+	ENDRPCENT = 2,
+	RPCENT_STORAGE_INITIAL	= 1 << 10, /* 1 KByte */
+	RPCENT_STORAGE_MAX		= 1 << 20, /* 1 MByte */		
+};
+
+static const ns_src defaultsrc[] = {
+	{ NSSRC_FILES, NS_SUCCESS },
+#ifdef YP
+	{ NSSRC_NIS, NS_SUCCESS },
+#endif
+	{ NULL, 0 }
+};
 
-/*
- * Internet version.
- */
-static struct rpcdata {
-	FILE	*rpcf;
+/* files backend declarations */
+struct files_state {
+	FILE	*fp;
 	int	stayopen;
-#define	MAXALIASES	35
-	char	*rpc_aliases[MAXALIASES];
-	struct	rpcent rpc;
-	char	line[BUFSIZ+1];
-#ifdef	YP
-	char	*domain;
+};
+
+static	int	files_rpcent(void *, void *, va_list);
+static	int	files_setrpcent(void *, void *, va_list);
+
+static	void	files_endstate(void *);
+NSS_TLS_HANDLING(files);
+
+/* nis backend declarations */
+#ifdef YP
+struct nis_state {
+	char	domain[MAXHOSTNAMELEN];
 	char	*current;
 	int	currentlen;
+	int	stepping;
+	int	no_name_map;
+};
+
+static	int	nis_rpcent(void *, void *, va_list);
+static	int	nis_setrpcent(void *, void *, va_list);
+
+static	void	nis_endstate(void *);
+NSS_TLS_HANDLING(nis);
 #endif
-} *rpcdata;
 
-static	struct rpcent *interpret(char *val, size_t len);
+/* get** wrappers for get**_r functions declarations */
+struct rpcent_state {
+	struct rpcent	rpc;
+	char		*buffer;
+	size_t	bufsize;
+};
+static	void	rpcent_endstate(void *);
+NSS_TLS_HANDLING(rpcent);
 
-#ifdef	YP
-static int	__yp_nomap = 0;
-#endif	/* YP */
+union key {
+	const char	*name;
+	int		number;
+};
 
-#define	RPCDB	"/etc/rpc"
+static	int	wrap_getrpcbyname_r(union key, struct rpcent *, char *, 
+			size_t, struct rpcent **);
+static	int	wrap_getrpcbynumber_r(union key, struct rpcent *, char *, 
+			size_t, struct rpcent **);
+static	int	wrap_getrpcent_r(union key, struct rpcent *, char *,
+			size_t, struct rpcent **);
+static	struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *, 
+			size_t, struct rpcent **), union key);
 
-static struct rpcdata *_rpcdata(void);
+static int
+rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
+	size_t aliases_size, int *errnop)
+{
+	char *cp, **q;
 
-static struct rpcdata *
-_rpcdata()
-{
-	struct rpcdata *d = rpcdata;
+	assert(p != NULL);
 
-	if (d == 0) {
-		d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
-		rpcdata = d;
+	if (*p == '#')
+		return (-1);
+	cp = strpbrk(p, "#\n");
+	if (cp == NULL)
+		return (-1);
+	*cp = '\0';
+	cp = strpbrk(p, " \t");
+	if (cp == NULL)
+		return (-1);
+	*cp++ = '\0';
+	/* THIS STUFF IS INTERNET SPECIFIC */
+	rpc->r_name = p;
+	while (*cp == ' ' || *cp == '\t')
+		cp++;
+	rpc->r_number = atoi(cp);
+	q = rpc->r_aliases = r_aliases;
+	cp = strpbrk(cp, " \t");
+	if (cp != NULL)
+		*cp++ = '\0';
+	while (cp && *cp) {
+		if (*cp == ' ' || *cp == '\t') {
+			cp++;
+			continue;
+		}
+		if (q < &(r_aliases[aliases_size - 1]))
+			*q++ = cp;
+		else {
+			*errnop = ERANGE;
+			return -1;
+		}
+			
+		cp = strpbrk(cp, " \t");
+		if (cp != NULL)
+			*cp++ = '\0';
 	}
-	return (d);
+	*q = NULL;
+	return 0;
+}
+
+/* files backend implementation */
+static	void
+files_endstate(void *p)
+{
+	FILE * f;
+	
+	if (p == NULL)
+		return;
+	
+	f = ((struct files_state *)p)->fp;
+	if (f != NULL)
+		fclose(f);
+	
+	free(p);
 }
 
-struct rpcent *
-getrpcbynumber(number)
-	int number;
+static int
+files_rpcent(void *retval, void *mdata, va_list ap)
 {
-#ifdef	YP
-	int reason;
-	char adrstr[16];
-#endif
-	struct rpcent *p;
-	struct rpcdata *d = _rpcdata();
+	char		*name;
+	int		number;
+	struct rpcent	*rpc;
+	char		*buffer;
+	size_t	bufsize;
+	int		*errnop;
+	
+	char		*line;
+	size_t	linesize;
+	char		**aliases;
+	int		aliases_size;
+	char		**rp;
+	
+	struct files_state	*st;
+	int		rv;
+	int		stayopen;
+	enum nss_lookup_type	how;
+	
+	how = (enum nss_lookup_type)mdata;
+	switch (how)
+	{
+	case nss_lt_name:
+		name = va_arg(ap, char *);
+		break;
+	case nss_lt_id:
+		number = va_arg(ap, int);
+		break;
+	case nss_lt_all:
+		break;
+	default:
+		return (NS_NOTFOUND);
+	}
+		
+	rpc = va_arg(ap, struct rpcent *);
+	buffer = va_arg(ap, char *);
+	bufsize = va_arg(ap, size_t);
+	errnop = va_arg(ap, int *);
+	
+	*errnop = files_getstate(&st);
+	if (*errnop != 0)
+		return (NS_UNAVAIL);
+	
+	if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
+		*errnop = errno;
+		return (NS_UNAVAIL);	
+	}
+	
+	if (how == nss_lt_all)
+		stayopen = 1;
+	else {
+		rewind(st->fp);
+		stayopen = st->stayopen;
+	}
+	
+	do {
+		if ((line = fgetln(st->fp, &linesize)) == NULL) {
+			*errnop = errno;
+			rv = NS_RETURN;
+			break;
+		}
+			
+		if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
+			*errnop = ERANGE;
+			rv = NS_RETURN;
+			break;
+		}
 
-	if (d == 0)
-		return (0);
-#ifdef	YP
-        if (!__yp_nomap && _yp_check(&d->domain)) {
-                sprintf(adrstr, "%d", number);
-                reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
-                                  &d->current, &d->currentlen);
-                switch(reason) {
-                case 0:
-                        break;
-                case YPERR_MAP:
-                        __yp_nomap = 1;
-                        goto no_yp;
-                        break;
-                default:
-                        return(0);
-                        break;
-                }
-                d->current[d->currentlen] = '\0';
-                p = interpret(d->current, d->currentlen);
-                (void) free(d->current);
-                return p;
-        }
-no_yp:
-#endif	/* YP */
+		aliases = (char **)_ALIGN(&buffer[linesize+1]);
+		aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *);
+		if (aliases_size < 1) {
+			*errnop = ERANGE;
+			rv = NS_RETURN;
+			break;
+		}
+				
+		memcpy(buffer, line, linesize);
+		buffer[linesize] = '\0';
 
-	setrpcent(0);
-	while ((p = getrpcent()) != NULL) {
-		if (p->r_number == number)
+		rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
+		if (rv != 0) {
+			if (*errnop == 0) {
+				rv = NS_NOTFOUND;
+				continue;
+			}
+			else {
+				rv = NS_RETURN;
+				break;
+			}
+		}
+		
+		switch (how)
+		{
+		case nss_lt_name:
+			if (strcmp(rpc->r_name, name) == 0)
+				goto done;
+			for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+				if (strcmp(*rp, name) == 0)
+					goto done;
+			}
+			rv = NS_NOTFOUND;
+			continue;			
+done:
+			rv = NS_SUCCESS;
+			break;
+		case nss_lt_id:
+			rv = (rpc->r_number == number) ? NS_SUCCESS : NS_NOTFOUND;
+			break;
+		case nss_lt_all:
+			rv = NS_SUCCESS;
 			break;
+		}
+		
+	} while (!(rv & NS_TERMINATE));
+
+	if (!stayopen && st->fp!=NULL) {
+		fclose(st->fp);
+		st->fp = NULL;
 	}
-	endrpcent();
-	return (p);
+	
+	if ((rv == NS_SUCCESS) && (retval != NULL))
+		*((struct rpcent **)retval) = rpc;
+			
+	return (rv);
+}
+
+static int
+files_setrpcent(void *retval, void *mdata, va_list ap)
+{
+	struct files_state	*st;
+	int	rv;
+	int	f;
+	
+	rv = files_getstate(&st);
+	if (rv != 0)
+		return (NS_UNAVAIL);
+	
+	switch ((enum constants)mdata)
+	{
+	case SETRPCENT:
+		f = va_arg(ap,int);
+		if (st->fp == NULL)
+			st->fp = fopen(RPCDB, "r");
+		else
+			rewind(st->fp);
+		st->stayopen |= f;
+		break;
+	case ENDRPCENT:
+		if (st->fp != NULL) {
+			fclose(st->fp);
+			st->fp = NULL;
+		}		
+		st->stayopen = 0;		
+		break;
+	default:
+		break;	
+	}
+	
+	return (NS_UNAVAIL);
 }
 
-struct rpcent *
-getrpcbyname(name)
-	char *name;
+/* nis backend implementation */
+#ifdef YP
+static 	void
+nis_endstate(void *p)
 {
-	struct rpcent *rpc = NULL;
-	char **rp;
+	if (p == NULL)
+		return;
 
-	assert(name != NULL);
+	free(((struct nis_state *)p)->current);	
+	free(p);
+}
 
-	setrpcent(0);
-	while ((rpc = getrpcent()) != NULL) {
-		if (strcmp(rpc->r_name, name) == 0)
-			goto done;
-		for (rp = rpc->r_aliases; *rp != NULL; rp++) {
-			if (strcmp(*rp, name) == 0)
-				goto done;
+static int
+nis_rpcent(void *retval, void *mdata, va_list ap)
+{
+	char		*name;
+	int		number;
+	struct rpcent	*rpc;
+	char		*buffer;
+	size_t	bufsize;
+	int		*errnop;
+	
+	char		**rp;
+	char		**aliases;
+	int		aliases_size;
+	
+	char	*lastkey;
+	char	*resultbuf;
+	int	resultbuflen;
+	char	buf[YPMAXRECORD + 2];		
+	
+	struct nis_state	*st;
+	int		rv;
+	enum nss_lookup_type	how;
+	int	no_name_active;
+	
+	how = (enum nss_lookup_type)mdata;
+	switch (how)
+	{
+	case nss_lt_name:
+		name = va_arg(ap, char *);
+		break;
+	case nss_lt_id:
+		number = va_arg(ap, int);
+		break;
+	case nss_lt_all:
+		break;
+	default:
+		return (NS_NOTFOUND);
+	}
+	
+	rpc = va_arg(ap, struct rpcent *);
+	buffer = va_arg(ap, char *);
+	bufsize = va_arg(ap, size_t);
+	errnop = va_arg(ap, int *);
+	
+	*errnop = nis_getstate(&st);
+	if (*errnop != 0)
+		return (NS_UNAVAIL);
+	
+	if (st->domain[0] == '\0') {
+		if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
+			*errnop = errno;
+			return (NS_UNAVAIL);
 		}
 	}
+
+	no_name_active = 0;
+	do {
+		switch (how)
+		{
+		case nss_lt_name:
+			if (!st->no_name_map)
+			{
+				snprintf(buf, sizeof buf, "%s", name);
+				rv = yp_match(st->domain, "rpc.byname", buf, strlen(buf),
+					&resultbuf, &resultbuflen);
+		
+				switch (rv) {
+				case 0:
+					break;
+				case YPERR_MAP:
+					st->stepping = 0;
+					no_name_active = 1;
+					how = nss_lt_all;
+				
+					rv = NS_NOTFOUND;
+					continue;
+				default:
+					rv = NS_NOTFOUND;	
+					goto fin;					
+				}
+			} else {
+				st->stepping = 0;
+				no_name_active = 1;
+				how = nss_lt_all;
+				
+				rv = NS_NOTFOUND;
+				continue;
+			}
+		break;
+		case nss_lt_id:
+			snprintf(buf, sizeof buf, "%d", number);
+			if (yp_match(st->domain, "rpc.bynumber", buf, strlen(buf),
+				&resultbuf, &resultbuflen)) {
+				rv = NS_NOTFOUND;
+				goto fin;
+			}			
+			break;
+		case nss_lt_all:
+				if (!st->stepping) {
+					rv = yp_first(st->domain, "rpc.bynumber", &st->current,
+						&st->currentlen, &resultbuf, &resultbuflen);
+					if (rv) {
+						rv = NS_NOTFOUND;
+						goto fin;
+					}
+					st->stepping = 1;
+				} else {
+					lastkey = st->current;
+					rv = yp_next(st->domain, "rpc.bynumber", st->current,
+						st->currentlen, &st->current, &st->currentlen, &resultbuf,
+						&resultbuflen);
+					free(lastkey);
+					if (rv) {
+						st->stepping = 0;
+						rv = NS_NOTFOUND;
+						goto fin;
+					}
+				}
+			break;
+		}
+		
+		/* we need a room for additional \n symbol */
+		if (bufsize <= resultbuflen +1 + _ALIGNBYTES + sizeof(char *)) {
+			*errnop = ERANGE;
+			rv = NS_RETURN;
+			break;
+		}
+		
+		aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
+		aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *);
+		if (aliases_size < 1) {
+			*errnop = ERANGE;
+			rv = NS_RETURN;
+			break;
+		}
+				
+		/* rpcent_unpack expects lines terminated with \n -- make it happy */
+		memcpy(buffer, resultbuf, resultbuflen);
+		buffer[resultbuflen] = '\n';
+		buffer[resultbuflen+1] = '\0';
+		free(resultbuf);
+		
+		if (rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop) != 0) {
+			if (*errnop == 0)
+				rv = NS_NOTFOUND;
+			else
+				rv = NS_RETURN;
+		} else {
+			if ((how == nss_lt_all) && (no_name_active != 0)) {
+				if (strcmp(rpc->r_name, name) == 0)
+					goto done;
+				for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+					if (strcmp(*rp, name) == 0)
+						goto done;
+				}
+				rv = NS_NOTFOUND;
+				continue;
 done:
-	endrpcent();
-	return (rpc);
+				rv = NS_SUCCESS;
+			} else
+				rv = NS_SUCCESS;
+		}
+		
+	} while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
+	
+fin:
+	if ((rv == NS_SUCCESS) && (retval != NULL))
+		*((struct rpcent **)retval) = rpc;
+			
+	return (rv);
+}
+
+static int
+nis_setrpcent(void *retval, void *mdata, va_list ap)
+{
+	struct nis_state	*st;
+	int	rv;
+	
+	rv = nis_getstate(&st);
+	if (rv != 0)
+		return (NS_UNAVAIL);
+	
+	switch ((enum constants)mdata)
+	{
+	case SETRPCENT:
+	case ENDRPCENT:
+		free(st->current);
+		st->current = NULL;
+		st->stepping = 0;
+		break;
+	default:
+		break;
+	}
+	
+	return (NS_UNAVAIL);	
+}
+#endif
+
+/* get**_r functions implementation */
+int
+getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer, 
+	size_t bufsize, struct rpcent **result)
+{
+	static const ns_dtab dtab[] = {
+		{ NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
+#ifdef YP
+		{ NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
+#endif
+		{ NULL, NULL, NULL }
+	};
+	
+	int	rv, ret_errno;
+
+	ret_errno = 0;
+	*result = NULL;
+	rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc,
+	    name, rpc, buffer, bufsize, &ret_errno);
+	
+	if (rv == NS_SUCCESS)
+		return (0);
+	else
+		return (ret_errno);	
+}
+
+int 
+getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer, 
+	size_t bufsize, struct rpcent **result)
+{
+	static const ns_dtab dtab[] = {
+		{ NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
+#ifdef YP
+		{ NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
+#endif
+		{ NULL, NULL, NULL }
+	};
+	int	rv, ret_errno;
+
+	ret_errno = 0;
+	*result = NULL;
+	rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc,
+	    number, rpc, buffer, bufsize, &ret_errno);
+	
+	if (rv == NS_SUCCESS)
+		return (0);
+	else
+		return (ret_errno);		
 }
 
-void
-setrpcent(f)
-	int f;
+int
+getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
+	struct rpcent **result)
 {
-	struct rpcdata *d = _rpcdata();
+	static const ns_dtab dtab[] = {
+		{ NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
+#ifdef YP
+		{ NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
+#endif
+		{ NULL, NULL, NULL }
+	};
+	int	rv, ret_errno;
+
+	ret_errno = 0;
+	*result = NULL;
+	rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc,
+	    rpc, buffer, bufsize, &ret_errno);
 
-	if (d == 0)
-		return;
-#ifdef	YP
-        if (!__yp_nomap && _yp_check(NULL)) {
-                if (d->current)
-                        free(d->current);
-                d->current = NULL;
-                d->currentlen = 0;
-                return;
-        }
-        __yp_nomap = 0;
-#endif	/* YP */
-	if (d->rpcf == NULL)
-		d->rpcf = fopen(RPCDB, "r");
+	if (rv == NS_SUCCESS)
+		return (0);
 	else
-		rewind(d->rpcf);
-	d->stayopen |= f;
+		return (ret_errno);		
+}
+
+void 
+setrpcent(int stayopen)
+{
+	static const ns_dtab dtab[] = {
+		{ NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
+#ifdef YP
+		{ NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
+#endif
+		{ NULL, NULL, NULL }
+	};
+
+	(void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, stayopen);
 }
 
-void
+void 
 endrpcent()
 {
-	struct rpcdata *d = _rpcdata();
+	static const ns_dtab dtab[] = {
+		{ NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
+#ifdef YP
+		{ NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
+#endif
+		{ NULL, NULL, NULL }
+	};
+
+	(void)nsdispatch(NULL, dtab, NSDB_SERVICES, "endrpcent", defaultsrc);
+}
 
-	if (d == 0)
+/* get** wrappers for get**_r functions implementation */
+static 	void
+rpcent_endstate(void *p)
+{
+	if (p == NULL)
 		return;
-#ifdef	YP
-        if (!__yp_nomap && _yp_check(NULL)) {
-        	if (d->current && !d->stayopen)
-                        free(d->current);
-                d->current = NULL;
-                d->currentlen = 0;
-                return;
-        }
-        __yp_nomap = 0;
-#endif	/* YP */
-	if (d->rpcf && !d->stayopen) {
-		fclose(d->rpcf);
-		d->rpcf = NULL;
-	}
+
+	free(((struct rpcent_state *)p)->buffer);	
+	free(p);
+}
+
+static	int
+wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer, size_t bufsize,
+    struct rpcent **res)
+{
+	return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res));
 }
 
-struct rpcent *
-getrpcent()
+static	int
+wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer, size_t bufsize,
+    struct rpcent **res)
 {
-	struct rpcdata *d = _rpcdata();
-#ifdef	YP
-	struct rpcent *hp;
-	int reason;
-	char *val = NULL;
-	int vallen;
-#endif
+	return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
+}
 
-	if (d == 0)
-		return(NULL);
-#ifdef	YP
-        if (!__yp_nomap && _yp_check(&d->domain)) {
-                if (d->current == NULL && d->currentlen == 0) {
-                        reason = yp_first(d->domain, "rpc.bynumber",
-                                          &d->current, &d->currentlen,
-                                          &val, &vallen);
-                } else {
-                        reason = yp_next(d->domain, "rpc.bynumber",
-                                         d->current, d->currentlen,
-                                         &d->current, &d->currentlen,
-                                         &val, &vallen);
-                }
-                switch(reason) {
-                case 0:
-                        break;
-                case YPERR_MAP:
-                        __yp_nomap = 1;
-                        goto no_yp;
-                        break;
-                default:
-                        return(0);
-                        break;
-                }
-                val[vallen] = '\0';
-                hp = interpret(val, vallen);
-                (void) free(val);
-                return hp;
-        }
-no_yp:
-#endif	/* YP */
-	if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
-		return (NULL);
-	/* -1 so there is room to append a \n below */
-        if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
-		return (NULL);
-	return (interpret(d->line, strlen(d->line)));
+static	int
+wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer, size_t bufsize,
+    struct rpcent **res)
+{
+	return (getrpcent_r(rpc, buffer, bufsize, res));
 }
 
 static struct rpcent *
-interpret(val, len)
-	char *val;
-	size_t len;
+getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **),
+    union key key)
+{
+	int		 rv;
+	struct rpcent	*res;
+	struct rpcent_state * st;
+		
+	rv=rpcent_getstate(&st);
+	if (rv != 0) {
+		errno = rv;
+		return NULL;
+	}
+
+	if (st->buffer == NULL) {
+		st->buffer = malloc(RPCENT_STORAGE_INITIAL);
+		if (st->buffer == NULL)
+			return (NULL);
+		st->bufsize = RPCENT_STORAGE_INITIAL;
+	}
+	do {
+		rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res);
+		if (res == NULL && rv == ERANGE) {
+			free(st->buffer);
+			if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) {
+				st->buffer = NULL;
+				errno = ERANGE;
+				return (NULL);
+			}
+			st->bufsize <<= 1;
+			st->buffer = malloc(st->bufsize);
+			if (st->buffer == NULL)
+				return (NULL);
+		}
+	} while (res == NULL && rv == ERANGE);
+	if (rv != 0)
+		errno = rv;
+	
+	return (res);
+}
+
+struct rpcent *
+getrpcbyname(char *name)
 {
-	struct rpcdata *d = _rpcdata();
-	char *p;
-	char *cp, **q;
+	union key key;
 
-	assert(val != NULL);
+	key.name = name;
+	
+	return (getrpc(wrap_getrpcbyname_r, key));
+}
 
-	if (d == 0)
-		return (0);
-	(void) strncpy(d->line, val, BUFSIZ);
-	d->line[BUFSIZ] = '\0';
-	p = d->line;
-	p[len] = '\n';
-	if (*p == '#')
-		return (getrpcent());
-	cp = strpbrk(p, "#\n");
-	if (cp == NULL)
-		return (getrpcent());
-	*cp = '\0';
-	cp = strpbrk(p, " \t");
-	if (cp == NULL)
-		return (getrpcent());
-	*cp++ = '\0';
-	/* THIS STUFF IS INTERNET SPECIFIC */
-	d->rpc.r_name = d->line;
-	while (*cp == ' ' || *cp == '\t')
-		cp++;
-	d->rpc.r_number = atoi(cp);
-	q = d->rpc.r_aliases = d->rpc_aliases;
-	cp = strpbrk(cp, " \t");
-	if (cp != NULL)
-		*cp++ = '\0';
-	while (cp && *cp) {
-		if (*cp == ' ' || *cp == '\t') {
-			cp++;
-			continue;
-		}
-		if (q < &(d->rpc_aliases[MAXALIASES - 1]))
-			*q++ = cp;
-		cp = strpbrk(cp, " \t");
-		if (cp != NULL)
-			*cp++ = '\0';
-	}
-	*q = NULL;
-	return (&d->rpc);
+struct rpcent *
+getrpcbynumber(int number)
+{
+	union key key;
+		
+	key.number = number;
+	
+	return (getrpc(wrap_getrpcbynumber_r, key));
 }
 
+struct rpcent *
+getrpcent()
+{
+	union key key;
+	 
+	key.number = 0;	/* not used */
+	
+	return (getrpc(wrap_getrpcent_r, key));
+}

==== //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/Makefile#2 (text+ko) ====


>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507151342.j6FDgIlA097598>