Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Jul 2005 08:30:36 GMT
From:      soc-bushman <soc-bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 79589 for review
Message-ID:  <200507050830.j658UaMM061010@repoman.freebsd.org>

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

Change 79589 by soc-bushman@soc-bushman_stinger on 2005/07/05 08:30:06

	services patch completed

Affected files ...

.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyname.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyport.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservent.c#6 edit
.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/netdb_private.h#2 edit

Differences ...

==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyname.c#4 (text+ko) ====

@@ -37,7 +37,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/lib/libc/net/getservbyname.c,v 1.7 2005/04/18 18:34:58 ume Exp $");
 
-#include <netdb.h>
+/*#include <netdb.h>
 #include <string.h>
 #include "netdb_private.h"
 
@@ -87,3 +87,4 @@
 		return (NULL);
 	return (&sd->serv);
 }
+*/

==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyport.c#4 (text+ko) ====

@@ -37,6 +37,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/lib/libc/net/getservbyport.c,v 1.7 2005/04/18 18:34:58 ume Exp $");
 
+/*
 #include <netdb.h>
 #include <string.h>
 #include "netdb_private.h"
@@ -81,3 +82,4 @@
 		return (NULL);
 	return (&sd->serv);
 }
+*/

==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservent.c#6 (text+ko) ====

@@ -37,9 +37,12 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/lib/libc/net/getservent.c,v 1.19 2005/04/28 15:32:55 ume Exp $");
 
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
+#include <errno.h>
+#include <nsswitch.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <string.h>
@@ -49,105 +52,113 @@
 #include <rpcsvc/yp_prot.h>
 #include <rpcsvc/ypclnt.h>
 #endif
+#include <unistd.h>
 #include "namespace.h"
 #include "reentrant.h"
 #include "un-namespace.h"
 #include "netdb_private.h"
-
-/* nsswitch part - begin */
 #include "libc_private.h"
 #include "nss_tls.h"
-#include <nsswitch.h>
-#include <errno.h>
-/* nsswitch part - end */
 
-/* nsswitch part - begin */
+enum constants
+{
+	SETSERVENT = 1,
+	ENDSERVENT = 2,
+	SERVENT_STORAGE_INITIAL	= 1 << 10, /* 1 KByte */
+	SERVENT_STORAGE_MAX		= 1 << 20, /* 1 MByte */	
+};
 
-// I guess, we'd better send this structure as the sequence of function arguments
-/*static struct servent_data
+struct servent_mdata 
 {
-//	char *aliases[_MAXALIASES];	
-//	char line[_MAXLINELEN + 1];
-	char **aliases;
-	size_t aliases_size;
-	
-	char * buffer;
-	size_t buffer_size;
-};*/
+	enum nss_lookup_type	how;
+	int 	compat_mode;
+};
 
 static const ns_src defaultsrc[] = {
 	{ NSSRC_COMPAT, NS_SUCCESS },
 	{ NULL, 0 }
 };
 
-static int servent_unpack(char *, struct servent *, char **, size_t);
-static void servent_init(struct servent *);
+static	int	servent_unpack(char *, struct servent *, char **, size_t, int *);
 
+/* files backend declarations */
 struct files_state
 {
-	FILE *fp;
-	int stayopen;
+	FILE	*fp;
+	int	stayopen;
+	
+	int	compat_mode_active;
 };
-static void files_endstate(void *);
+static	void	files_endstate(void *);
 NSS_TLS_HANDLING(files);
 
-static int files_servent(void *, void *, va_list);
-static int files_setservent(void *, void *, va_list);
-static int files_endservent(void *, void *, va_list);
-static void files_setent(int, struct files_state *);
-static void files_endent(struct files_state *);
+static	int	files_servent(void *, void *, va_list);
+static	int	files_setservent(void *, void *, va_list);
 
-#ifdef YP
-static int nis_getservbyname_r(void *, void *, va_list);
-static int nis_getservbyport_t(void *, void *, va_list);
-static int nis_getservent_r(void *, void *, va_list);
-static int nis_setservent(void *, void *, va_list);
-static int nis_endservent(void *, void *, va_list);
+/* nis backend declarations */
+static 	int 	nis_servent(void *, void *, va_list);
+static 	int 	nis_setservent(void *, void *, va_list);
 
 struct nis_state
 {
-	/* this specification is not finished */
-	int yp_stepping;
-//	char *yp_name;
-//	char *yp_proto;
-//	int yp_port;
-	char *yp_domain;
-	char *yp_key;
-	int yp_keylen;
+	int	yp_stepping;
+	char	yp_domain[MAXHOSTNAMELEN];
+	char	*yp_key;
+	int	yp_keylen;
 };
-static void nis_endstate(void *);
+static	void	nis_endstate(void *);
 NSS_TLS_HANDLING(nis);
 
-#endif
+static	int	nis_servent(void *, void *, va_list);
+static	int	nis_setservent(void *, void *, va_list);
+
+/* compat backend declarations */
+static	int	compat_setservent(void *, void *, va_list);
+
+/* get** wrappers for get**_r functions declarations */
+struct servent_state {
+	struct servent serv;
+	char		*buffer;
+	size_t	bufsize;
+};
+static	void	servent_endstate(void *);
+NSS_TLS_HANDLING(servent);
 
-struct compat_state
-{
-	FILE	*fp;
-	int	 stayopen;
-/*	char	*name;
-	enum _compat {
-		COMPAT_MODE_OFF = 0,
-		COMPAT_MODE_ALL,
-		COMPAT_MODE_NAME
-	}	 compat;*/
+struct key {
+	const char *proto;
+	union {
+		const char *name;
+		int	port;
+	};
 };
-//static void compat_endstate(void *);
-//NSS_TLS_HANDLING(compat);
-	
-/* nsswitch part - end */
 
+static	int	wrap_getservbyname_r(struct key key, struct servent *serv, char *buffer, 
+			size_t bufsize, struct servent **res);
+static	int	wrap_getservbyport_r(struct key key, struct servent *serv, char *buffer, 
+			size_t bufsize, struct servent **res);
+static	int	wrap_getservent_r(struct key key, struct servent *serv, char *buffer,
+			size_t bufsize, struct servent **res);
+static	struct servent *getserv(int (*fn)(struct key, struct servent *, char *, 
+			size_t, struct servent **), struct key key);
+				
+			
 static int
-servent_unpack(char *p, struct servent * serv, char ** aliases, size_t aliases_size)
+servent_unpack(char *p, struct servent * serv, char ** aliases, size_t aliases_size,
+	int * errnop)
 {
-	char *cp, **q, *endp;
-	long l;		
+	char	*cp, **q, *endp;
+	long	l;		
 	
 	if (*p == '#')
 		return -1;
+
+	memset(serv, 0, sizeof(struct servent));
+	
 	cp = strpbrk(p, "#\n");
 	if (cp != NULL)
 		*cp = '\0';
 	serv->s_name = p;
+
 	p = strpbrk(p, " \t");
 	if (p == NULL)
 		return -1;
@@ -157,12 +168,14 @@
 	cp = strpbrk(p, ",/");
 	if (cp == NULL)
 		return -1;
+
 	*cp++ = '\0';
 	l = strtol(p, &endp, 10);
 	if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
 		return -1;
 	serv->s_port = htons((in_port_t)l);
 	serv->s_proto = cp;
+
 	q = serv->s_aliases = aliases;
 	cp = strpbrk(cp, " \t");
 	if (cp != NULL)
@@ -172,38 +185,24 @@
 			cp++;
 			continue;
 		}
-		if (q < &aliases[_MAXALIASES - 1]) {
+		if (q < &aliases[aliases_size - 1]) {
 			*q++ = cp;
-			*q++ = '\0'; // my hack - should work - but will left the buffer in mess after the ending 0
+		} else {
+			*q = NULL;
+			*errnop = ERANGE;
+			return -1;
 		}
 		cp = strpbrk(cp, " \t");
 		if (cp != NULL)
 			*cp++ = '\0';
 	}		
 	*q = NULL;
-	
+
 	return 0;
 }
 
-static void
-servent_init(struct servent * serv)
-{
-}
-
-#define SERVENT_BUFFER_UNPACK(buffer, buffer_size, line, line_size, aliases) 	\
-	aliases=(char **)(_ALIGN((char **)buffer));										\
-	line=(char *)aliases+sizeof(char *)*_MAXALIASES;							\
-	if (line>buffer+buffer_size)												\
-		return (NS_UNAVAIL);													\
-	line_size=buffer+buffer_size-line;											\
-	if (line_size<_MAXLINELEN+1)												\
-		return (NS_TRYAGAIN);
-	/* TODO - must check the alignment here */
-
-#define SERVENT_BUFFER_SIZE sizeof(char*)*_MAXALIASES+_ALIGNBYTES+_MAXLINELEN
-
-/* files backend implementation - begin */
-static 	void
+/* files backend implementation */
+static	void
 files_endstate(void *p)
 {
 	FILE * f;
@@ -218,260 +217,223 @@
 	free(p);
 }
 
-//struct servent * serv, char * buffer, size_t buffer_size, int * errnop, struct files_state * st
-static 	int 
-files_servent(void * retval, void *mdata, va_list ap)
+/*
+ * compat structures. compat and files sources functionalities are almost equa, so
+ *	they all are managed by files_servent function 
+ */
+static	int 
+files_servent(void *retval, void *mdata, va_list ap)
 {
-	struct files_state * st;
-	int rv;	
-	int stayopen;
+	static const ns_src compat_src[] = {
+#ifdef YP
+		{ NSSRC_NIS, NS_SUCCESS },
+#endif
+		{ NULL, 0 }
+	};
+	ns_dtab compat_dtab[] = {
+#ifdef YP
+		{ NSSRC_NIS, nis_servent, (void *)((struct servent_mdata *)mdata)->how },
+#endif
+		{ NULL, NULL, NULL }
+	};		
 	
-	enum nss_lookup_type how;	
-	char * name;
-	char * proto;
-	int port;
-	
-	struct servent * serv;
-	char * buffer;
-	size_t buffer_size;
-	int * errnop;
-	
-	char **aliases;
-	char * line;
-	size_t line_size;
+	struct files_state *st;
+	int		rv;	
+	int		stayopen;
 
-	char *p;
-	char **cp;//, **q, *endp;
-//	long l;	
-			
-	rv = files_getstate(&st);
-	if (rv != 0)
-		return (NS_UNAVAIL);
+	struct servent_mdata *serv_mdata;	
+	char		*name;
+	char		*proto;
+	int		port;
 	
-	SERVENT_BUFFER_UNPACK(buffer, buffer_size,line,line_size,aliases)
-/*	aliases=_ALIGN((char **)buffer);
-	line=aliases+sizeof(char *)*_MAXALIASES;
-	if (line>=buffer+buffer_size)
-		return (NS_TRYAGAIN);
-	line_size=buffer+buffer_size-line;
+	struct servent *serv;
+	char		*buffer;
+	size_t	bufsize;
+	int		*errnop;
 	
-	if (line_size<_MAXLINELEN+1)
-		return (NS_TRYAGAIN);*/
-
+	char		**aliases;
+	int		aliases_size;	
+	size_t	linesize;
+	char		*line;
+	char		**cp;
+				
 	name = NULL;	
 	proto = NULL;
-	how = (enum nss_lookup_type)mdata;
-	switch (how)
-	{
-		case nss_lt_name:
-			name = va_arg(ap, char *);
-			proto = va_arg(ap, char *);
-			stayopen=0;
-			break;
-		case nss_lt_id:
-			port = va_arg(ap, int);
-			proto = va_arg(ap, char *);
-			stayopen=0;
-			break;
-		case nss_lt_all:
-			stayopen=1;
-			break;		
-		default:
-			return NS_NOTFOUND;
+	serv_mdata = (struct servent_mdata *)mdata;
+	switch (serv_mdata->how) {
+	case nss_lt_name:
+		name = va_arg(ap, char *);
+		proto = va_arg(ap, char *);
+		break;
+	case nss_lt_id:
+		port = va_arg(ap, int);
+		proto = va_arg(ap, char *);
+		break;
+	case nss_lt_all:
+		break;		
+	default:
+		return NS_NOTFOUND;
 	};
 	
 	serv = va_arg(ap, struct servent *);
 	buffer  = va_arg(ap, char *);
-	buffer_size = va_arg(ap, size_t);
+	bufsize = va_arg(ap, size_t);
 	errnop = va_arg(ap,int *);
 	
-	if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL)
+	*errnop = files_getstate(&st);
+	if (*errnop != 0)
+		return (NS_UNAVAIL);	
+	
+	if (st->fp == NULL)
+		st->compat_mode_active = 0;
+	
+	if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) {
+		*errnop = errno;
 		return (NS_UNAVAIL);	
+	}
 	
-	if (stayopen==1)
-		files_setent(1,st);	
+	if (serv_mdata->how == nss_lt_all)
+		stayopen = 1;
+	else {
+		rewind(st->fp);
+		stayopen = st->stayopen;
+	}
 	
-	rv=NS_NOTFOUND;
-	do {
-		memset(serv,0,sizeof(*serv));
-		*aliases='\0';
+	rv = NS_NOTFOUND;
+	do {			
+		if (!st->compat_mode_active) {
+			if ((line = fgetln(st->fp, &linesize)) == NULL) {
+				*errnop = errno;
+				rv = NS_RETURN;
+				break;
+			}
+
+			if (*line=='+')
+				st->compat_mode_active = 1;
+			else {			
+				if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
+					*errnop = ERANGE;
+					rv = NS_RETURN;
+					break;
+				}
+				aliases = (char **)_ALIGN(&buffer[linesize+1]);
+				aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *);
+				if (aliases_size < 1) {
+					*errnop = ERANGE;
+					rv = NS_RETURN;
+					break;
+				}
 				
-		if ((p = fgets(line,line_size, st->fp)) == NULL) {
-			rv=(NS_RETURN);
-			break;
+				memcpy(buffer, line, linesize);
+				buffer[linesize] = '\0';										
+			}			
 		}
+		
+		if (st->compat_mode_active != 0) {
+			switch (serv_mdata->how) {
+			case nss_lt_name:
+				rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyname_r",
+					compat_src, name, proto, serv, buffer, bufsize, errnop);
+				break;
+			case nss_lt_id:
+				rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyport_r",
+					compat_src, port, proto, serv, buffer, bufsize, errnop);
+				break;
+			case nss_lt_all:
+				rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES, "getservent_r",
+					compat_src, serv, buffer, bufsize, errnop);
+				break;
+			}
+			
+			if ( ( !(rv & NS_TERMINATE) ) || (serv_mdata->how != nss_lt_all))
+				st->compat_mode_active = 0;
 
-		if (servent_unpack(p,serv,aliases,_MAXALIASES) == -1)
 			continue;
-/*		if (*p == '#')
-			continue;
-		cp = strpbrk(p, "#\n");
-		if (cp != NULL)
-			*cp = '\0';
-		serv->s_name = p;
-		p = strpbrk(p, " \t");
-		if (p == NULL)
-			continue;
-		*p++ = '\0';
-		while (*p == ' ' || *p == '\t')
-			p++;
-		cp = strpbrk(p, ",/");
-		if (cp == NULL)
-			continue;
-		*cp++ = '\0';
-		l = strtol(p, &endp, 10);
-		if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
-			continue;
-		serv->s_port = htons((in_port_t)l);
-		serv->s_proto = cp;
-		q = serv->s_aliases = aliases;
-		cp = strpbrk(cp, " \t");
-		if (cp != NULL)
-			*cp++ = '\0';
-		while (cp && *cp) {
-			if (*cp == ' ' || *cp == '\t') {
-				cp++;
+		}
+
+		rv = servent_unpack(line, serv, aliases, aliases_size, errnop);
+		if (rv !=0 ) {
+			if (*errnop == 0) {
+				rv = NS_NOTFOUND;
 				continue;
 			}
-			if (q < &st->aliases[_MAXALIASES - 1]) {
-				*q++ = cp;
-				*q++ = '\0'; // my hack - should work - but will left the buffer in mess after the ending 0
+			else {
+				rv = NS_RETURN;
+				break;
 			}
-			cp = strpbrk(cp, " \t");
-			if (cp != NULL)
-				*cp++ = '\0';
-		}		
-		*q = NULL;			*/
-		
-		switch (how)
-		{
-			case nss_lt_name:
-				if (strcmp(name, serv->s_name) == 0)
+		}
+			
+		switch (serv_mdata->how) {
+		case nss_lt_name:
+			if (strcmp(name, serv->s_name) == 0)
+				goto gotname;
+			for (cp = serv->s_aliases; *cp; cp++)
+				if (strcmp(name, *cp) == 0)
 					goto gotname;
-				for (cp = serv->s_aliases; *cp; cp++)
-					if (strcmp(name, *cp) == 0)
-						goto gotname;
-					
+				
+			continue;
+		gotname:
+			if (proto == 0 || strcmp(serv->s_proto, proto) == 0)
+				rv = NS_SUCCESS;
+			break;
+		case nss_lt_id:
+			if (port != serv->s_port)
 				continue;
-			gotname:
-				if (proto == 0 || strcmp(serv->s_proto, proto) == 0)
-					rv=NS_SUCCESS;
-				break;
-			case nss_lt_id:
-				if (port != serv->s_port)
-					continue;
 
-				if (proto == 0 || strcmp(serv->s_proto, proto) == 0)
-					rv=NS_SUCCESS;
-				break;
-			case nss_lt_all:
-				rv = (NS_SUCCESS);
-				break;
-		};
+			if (proto == 0 || strcmp(serv->s_proto, proto) == 0)
+				rv = NS_SUCCESS;
+			break;
+		case nss_lt_all:
+			rv = NS_SUCCESS;
+			break;
+		}
 		
 	} while (!(rv & NS_TERMINATE));
 	
-	if (stayopen==1)
-		files_endent(st);
-		
-	if (rv==NS_SUCCESS)
+	if (!stayopen && st->fp!=NULL) {
+		fclose(st->fp);
+		st->fp = NULL;
+	}
+	
+	if ((rv ==NS_SUCCESS) && (retval != NULL))
 		*(struct servent **)retval=serv;
 	
-	return rv;
+	return (rv);
 }
 
-static void files_setent(int f, struct files_state * st)
+static	int 
+files_setservent(void *retval, void *mdata, va_list ap)
 {
-/*	struct files_state * st;
-	int rv;
-	
-	rv = files_getstate(&st);
-	if (rv != 0)
-		return (NS_UNAVAIL);
-	*/
-	if (st->fp == NULL)
-		st->fp = fopen(_PATH_SERVICES, "r");
-	else
-		rewind(st->fp);
-	st->stayopen |= f;
-
-	//return (NS_SUCCESS);	
-}
+	struct files_state *st;
+	int		rv;
+	int		f;
 
-static void files_endent(struct files_state * st)
-{
-/*	struct files_state *st;
-	int rv;
-
-	rv = files_getstate(&st);
-	if (rv != 0)
-		return (NS_UNAVAIL);
-	*/
-	st->stayopen = 0;
-//	return (NS_SUCCESS);
-}
-
-/*static int 
-files_getservent_r(void * retval, void * mdata, va_list ap)
-{
-	struct files_state * st;
-	struct servent * serv;
-	char * buffer;
-	size_t buffer_size;
-	int * errnop;
-	int rv;
-	
 	rv = files_getstate(&st);
 	if (rv != 0)
 		return (NS_UNAVAIL);	
 	
-	serv = va_arg(ap, struct servent *);
-	buffer  = va_arg(ap, char *);
-	buffer_size = va_arg(ap, size_t);
-	errnop = va_arg(ap,int *);
-	
-	rv=files_servent(se,buffer,buffer_size,errnop);
-	if (rv==NS_SUCCESS)
-		*(struct servent **)retval=se;
-	
-	return rv;
-}	*/
-
-
-static int 
-files_setservent(void * retval, void * mdata, va_list ap)
-{
-	struct files_state *st;
-	int rv;
-	int f;
-
-	f=va_arg(ap,int);
-
-	rv = files_getstate(&st);
-	if (rv != 0)
-		return (NS_UNAVAIL);	
+	switch ((enum constants)mdata) {
+	case SETSERVENT:
+		f = va_arg(ap,int);
+		if (st->fp == NULL)
+			st->fp = fopen(_PATH_SERVICES, "r");
+		else
+			rewind(st->fp);
+		st->stayopen |= f;
+		break;
+	case ENDSERVENT:
+			st->stayopen = 0;
+		break;
+	default:
+		break;
+	};
+	st->compat_mode_active = 0;
 		
-	files_setent(f,st);
-	return (NS_SUCCESS);
+	return (NS_UNAVAIL);
 }
 
-static 	int 
-files_endservent(void * retval, void * mdata, va_list ap)
-{
-	struct files_state *st;
-	int rv;
-	
-	rv = files_getstate(&st);
-	if (rv != 0)
-		return (NS_UNAVAIL);
-	
-	files_endent(st);	
-	return (NS_SUCCESS);
-}
-
-/* files backend implementation - end */
-
-/* nis backend implementation - begin */
+/* nis backend implementation */
+#ifdef YP
 static 	void
 nis_endstate(void *p)
 {
@@ -482,331 +444,249 @@
 	free(p);
 }
 
-static int 
-nis_getservbyname_r(void * result, void * mdata, va_list ap)
+static	int
+nis_servent(void *retval, void *mdata, va_list ap)
 {
-	struct nis_state * ns;
-	int rv;
+	char	*resultbuf, *lastkey;
+	int	resultbuflen;
+	char	buf[YPMAXRECORD + 2];
+	
+	struct nis_state *st;
+	int	rv;
 	
-	struct servent * serv;
-	char **aliases;
-	char * line;
-	size_t line_size;	
+	enum nss_lookup_type how;	
+	char		*name;
+	char		*proto;
+	int		port;
 	
-	char * name;
-	char * proto;
-	char * buffer;
-	size_t bufsize;
-	int * errnop;
+	struct servent *serv;
+	char		*buffer;
+	size_t	bufsize;
+	int		*errnop;
 	
-	char *resultbuf;
-	int resultbuflen;
-	char buf[YPMAXRECORD + 2];
+	char		**aliases;
+	int		aliases_size;
 
-	rv = nis_getstate(&ns);
-	if (rv != 0)
-		return (NS_UNAVAIL);	
+	name = NULL;	
+	proto = NULL;
+	how = (enum nss_lookup_type)mdata;
+	switch (how) {
+		case nss_lt_name:
+			name = va_arg(ap, char *);
+			proto = va_arg(ap, char *);
+			break;
+		case nss_lt_id:
+			port = va_arg(ap, int);
+			proto = va_arg(ap, char *);
+			break;
+		case nss_lt_all:
+			break;		
+		default:
+			return NS_NOTFOUND;
+	};
 	
-	name = va_arg(ap, char *);
-	proto = va_arg(ap, char *);
 	serv = va_arg(ap, struct servent *);
-	buffer = va_arg(ap, char *);
+	buffer  = va_arg(ap, char *);
 	bufsize = va_arg(ap, size_t);
 	errnop = va_arg(ap, int *);
 	
-	SERVENT_BUFFER_UNPACK(buffer,bufsize,line,line_size,aliases)
+	*errnop = nis_getstate(&st);
+	if (*errnop != 0)
+		return (NS_UNAVAIL);
 	
-	/* TODO: do we need this ? */
-/*	if (bufsize < _MAXLINELEN+1)
-		return (NS_TRYAGAIN);*/
-	
-	if(!ns->yp_domain) {
-		if(yp_get_default_domain(&ns->yp_domain))
+	if (st->yp_domain[0] == '\0') {
+		if (getdomainname(st->yp_domain, sizeof st->yp_domain)) {
+			*errnop=errno;
 			return (NS_UNAVAIL);
+		}
 	}
 
-	//snprintf(buf, sizeof(buf), "%s/%s", ns->yp_name, ns->yp_proto);
-	snprintf(buf, sizeof(buf), "%s/%s", name, proto);
+	do {
+		switch (how)
+		{
+			case nss_lt_name:
+					snprintf(buf, sizeof(buf), "%s/%s", name, proto);
+					if (yp_match(st->yp_domain, "services.byname", buf, strlen(buf), 
+						&resultbuf, &resultbuflen)) {
+						rv = NS_NOTFOUND;
+						goto fin;
+					}
+				break;
+			case nss_lt_id:
+				snprintf(buf, sizeof(buf), "%d/%s", ntohs(port), proto);	
+			
+				/*
+				 * We have to be a little flexible here. Ideally you're supposed
+				 * to have both a services.byname and a services.byport map, but
+				 * some systems have only services.byname. FreeBSD cheats a little
+				 * by putting the services.byport information in the same map as
+				 * services.byname so that either case will work. We allow for both
+				 * possibilities here: if there is no services.byport map, we try
+				 * services.byname instead.
+				 */
+				if ((rv = yp_match(st->yp_domain, "services.byport", buf, strlen(buf),
+									&resultbuf, &resultbuflen))) {
+					if (rv == YPERR_MAP) {
+						if (yp_match(st->yp_domain, "services.byname", buf,strlen(buf), &resultbuf, &resultbuflen)) {
+							rv = NS_NOTFOUND;
+							goto fin;
+						}
+					} else {
+						rv = NS_NOTFOUND;
+						goto fin;
+					}
+				}
+				
+				break;
+			case nss_lt_all:
+				if (!st->yp_stepping) {
+					free(st->yp_key);
+					rv = yp_first(st->yp_domain, "services.byname", &st->yp_key,
+						&st->yp_keylen, &resultbuf, &resultbuflen);
+					if (rv) {
+						st->yp_stepping = 0;
+						rv = NS_NOTFOUND;
+						goto fin;
+					}
+					st->yp_stepping = 1;
+				} else {
+					lastkey = st->yp_key;
+					rv = yp_next(st->yp_domain, "services.byname", st->yp_key,
+						st->yp_keylen, &st->yp_key, &st->yp_keylen, &resultbuf,
+						&resultbuflen);
+					free(lastkey);
+					if (rv) {
+						st->yp_stepping = 0;
+						rv = NS_NOTFOUND;
+						goto fin;
+					}
+				}		
+				break;
+		};
 
-//	ns->yp_name = 0;
-//	ns->yp_proto = NULL;
-
-	if (yp_match(ns->yp_domain, "services.byname", buf, strlen(buf),
-	    &resultbuf, &resultbuflen)) {
-		return (NS_NOTFOUND);
-	}
+		/* we need a room for additional \n symbol */
+		if (bufsize <= resultbuflen +1 + _ALIGNBYTES + sizeof(char *)) {
+			*errnop = ERANGE;
+			rv = NS_RETURN;
+			break;
+		}
 		
-	/* getservent() expects lines terminated with \n -- make it happy */
-	//snprintf(sed->line, sizeof sed->line, "%.*s\n", resultbuflen, resultbuf);
-	snprintf(buffer, bufsize, "%.*s\n", resultbuflen, resultbuf);	
-	rv = (servent_unpack(buffer,serv,aliases,_MAXALIASES)==-1) ? (NS_NOTFOUND) : (NS_SUCCESS);
-
-	free(resultbuf);
-	return rv;	
-}
-
-static int 
-nis_getservbyport_t(void * result, void * mdata, va_list ap)
-{
-	struct nis_state * ns;
-	
-	struct servent * serv;
-	char ** aliases;
-	char * line;
-	size_t line_size;
-	
-	int port;
-	char * proto;
-	char * buffer;
-	size_t bufsize;
-	int * errnop;
-
-	char *resultbuf;
-	int resultbuflen;
-	char buf[YPMAXRECORD + 2];
-	int rv;
-	
-	rv = nis_getstate(&ns);
-	if (rv != 0)
-		return (NS_UNAVAIL);	
-	
-	port = va_arg(ap, int);
-	proto = va_arg(ap, char *);
-	serv = va_arg(ap, struct servent *);
-	buffer = va_arg(ap, char *);
-	bufsize = va_arg(ap, size_t);
-	errnop = va_arg(ap, int *);	
-
-	SERVENT_BUFFER_UNPACK(buffer,bufsize,line,line_size,aliases);
-	
-	/* TODO - do we need this? */
-//	if (bufsize<_MAXLINELEN+1)
-//		return (NS_TRYAGAIN);
-	
-//	snprintf(buf, sizeof(buf), "%d/%s", ntohs(sed->yp_port),
-//	    sed->yp_proto);
-	snprintf(buf, sizeof(buf), "%d/%s", ntohs(port),
-	    proto);	
-
-//	sed->yp_port = 0;
-//	sed->yp_proto = NULL;
-
-	if (!ns->yp_domain) {
-		if (yp_get_default_domain(&ns->yp_domain))
-			return (NS_UNAVAIL);
-	}
-
-	/*
-	 * We have to be a little flexible here. Ideally you're supposed
-	 * to have both a services.byname and a services.byport map, but
-	 * some systems have only services.byname. FreeBSD cheats a little
-	 * by putting the services.byport information in the same map as
-	 * services.byname so that either case will work. We allow for both
-	 * possibilities here: if there is no services.byport map, we try
-	 * services.byname instead.
-	 */
-	if ((rv = yp_match(ns->yp_domain, "services.byport", buf, strlen(buf),
-						&resultbuf, &resultbuflen))) {
-		if (rv == YPERR_MAP) {
-			if (yp_match(ns->yp_domain, "services.byname", buf,
-					strlen(buf), &resultbuf, &resultbuflen))
-			return(NS_NOTFOUND);
-		} else
-			return(NS_NOTFOUND);
-	}
+		aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
+		aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *);
+		if (aliases_size < 1) {
+			*errnop = ERANGE;
+			rv = NS_RETURN;
+			break;
+		}
+				
+		/* servent_unpack expects lines terminated with \n -- make it happy */
+		memcpy(buffer, resultbuf, resultbuflen);
+		buffer[resultbuflen] = '\n';
+		buffer[resultbuflen+1] = '\0';
 		
-	snprintf(buffer, bufsize, "%.*s\n", resultbuflen, resultbuf);	
-	rv = (servent_unpack(buffer,serv,aliases,_MAXALIASES)==-1) ? (NS_NOTFOUND) : (NS_SUCCESS);
+		if (servent_unpack(buffer, serv, aliases, aliases_size, errnop) != 0) {
+			if (*errnop == 0)
+				rv = NS_NOTFOUND;
+			else
+				rv = NS_RETURN;
+		}

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



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