Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jul 2005 14:21:49 GMT
From:      soc-bushman <soc-bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 79554 for review
Message-ID:  <200507041421.j64ELnu4085733@repoman.freebsd.org>

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

Change 79554 by soc-bushman@soc-bushman_stinger on 2005/07/04 14:21:36

	getservent work in progress

Affected files ...

.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservent.c#5 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getservent/getservent.c#3 edit

Differences ...

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


==== //depot/projects/soc2005/nsswitch_cached/tests/getservent/getservent.c#3 (text+ko) ====

@@ -57,7 +57,7 @@
 #include "netdb_private.h"
 
 /* debug part - begin */
-#define TRACE_WANTED 3
+#define TRACE_WANTED 1
 
 static int trace_level=0;
 static int trace_level_bk=0;
@@ -117,7 +117,7 @@
 	
 	if (trace_level<TRACE_WANTED)
 	{
-		for (j=0;i<trace_level-1;++j)
+		for (j=0;j<trace_level-1;++j)
 			printf("\t");
 
 		printf("= INT %s: %i, %s: %d\n",desc,i,f,l);	
@@ -169,6 +169,7 @@
 #include "nss_tls.h"
 #include <nsswitch.h>
 #include <errno.h>
+#include <sys/param.h>
 /* nsswitch part - end */
 
 /* nsswitch part - begin */
@@ -185,36 +186,44 @@
 	size_t buffer_size;
 };*/
 
+enum constants
+{
+	SETSERVENT,
+	ENDSERVENT,
+};
+
+struct servent_mdata 
+{
+	enum nss_lookup_type how;
+	int compat_mode;
+};
+
 static const ns_src defaultsrc[] = {
 	//{ NSSRC_COMPAT, NS_SUCCESS },
 	//{ NSSRC_FILES, NS_SUCCESS },
-	{ NSSRC_NIS, NS_SUCCESS },
+	{ NSSRC_FILES, NS_SUCCESS },
 	{ NULL, 0 }
 };
 
-static int servent_unpack(char *, struct servent *, char **, size_t);
+static int servent_unpack(char *, struct servent *, char **, size_t, int *);
 static void servent_init(struct servent *);
 
 struct files_state
 {
 	FILE *fp;
 	int stayopen;
+	
+	int compat_mode_active;
 };
 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 *);
 
 #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_servent(void *, void *, va_list);
 static int nis_setservent(void *, void *, va_list);
-static int nis_endservent(void *, void *, va_list);
 
 struct nis_state
 {
@@ -223,7 +232,7 @@
 //	char *yp_name;
 //	char *yp_proto;
 //	int yp_port;
-	char *yp_domain;
+	char	 yp_domain[MAXHOSTNAMELEN];
 	char *yp_key;
 	int yp_keylen;
 };
@@ -232,22 +241,13 @@
 
 #endif
 
-struct compat_state
-{
-	FILE	*fp;
-	int	 stayopen;
-};
-static void compat_endstate(void *);
-NSS_TLS_HANDLING(compat);
-
 static int compat_servent(void *, void *, va_list);
 static int compat_setservent(void *, void *, va_list);
-static int compat_setservent(void *, void *, va_list);
 	
 /* nsswitch part - end */
 
 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)
 {
 	TRACE_IN(servent_unpack);
 	
@@ -258,7 +258,9 @@
 		TRACE_POINT();
 		TRACE_OUT(servent_unpack);
 		return -1;
-	}
+	}	
+	memset(serv,0,sizeof(struct servent));
+	
 	cp = strpbrk(p, "#\n");
 	if (cp != NULL)
 		*cp = '\0';
@@ -302,10 +304,13 @@
 			TRACE_STR(serv->s_name);
 			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
+//			*q = '\0'; // my hack - should work - but will left the buffer in mess after the ending 0
 			TRACE_STR(serv->s_name);
+		} else {
+			*errnop = ERANGE;
+			return -1;
 		}
 		cp = strpbrk(cp, " \t");
 		if (cp != NULL)
@@ -361,37 +366,46 @@
 	TRACE_OUT(files_endstate);
 }
 
-//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 functionality are almost equal for
+	services, so all getserv* functions are managed by the same function for files and
+	compat sources */
+	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 }
+	};		
+	
 	struct files_state * st;
 	int rv;	
 	int stayopen;
-	
-	enum nss_lookup_type how;	
+
+	struct servent_mdata * serv_mdata;	
 	char * name;
 	char * proto;
 	int port;
 	
 	struct servent * serv;
 	char * buffer;
-	size_t buffer_size;
+	size_t bufsize;
 	int * errnop;
 	
-	char **aliases;
-	char * line;
-	size_t line_size;
-
-	char *p;
+	char ** aliases;
+	int aliases_size;	
+	size_t linesize;
+	char *line;
 	char **cp;//, **q, *endp;
 //	long l;	
-			
-	TRACE_IN(files_servent);
-	rv = files_getstate(&st);
-	if (rv != 0)
-		return (NS_UNAVAIL);
-	
+				
 /*	aliases=_ALIGN((char **)buffer);
 	line=aliases+sizeof(char *)*_MAXALIASES;
 	if (line>=buffer+buffer_size)
@@ -402,10 +416,12 @@
 		return (NS_TRYAGAIN);*/
 
 	TRACE_POINT();
+	TRACE_INT(((struct servent_mdata *)mdata)->how);
+		
 	name = NULL;	
 	proto = NULL;
-	how = (enum nss_lookup_type)mdata;
-	switch (how)
+	serv_mdata = (struct servent_mdata *)mdata;
+	switch (serv_mdata->how)
 	{
 		case nss_lt_name:
 			name = va_arg(ap, char *);
@@ -430,36 +446,128 @@
 	
 	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 *);
 	
-	SERVENT_BUFFER_UNPACK(buffer, buffer_size,line,line_size,aliases)
+	TRACE_IN(files_servent);
+	*errnop = files_getstate(&st);
+	if (*errnop != 0)
+		return (NS_UNAVAIL);	
+	
+/*	SERVENT_BUFFER_UNPACK(buffer, buffer_size,line,line_size,aliases)
 	TRACE_PTR(buffer);
 	TRACE_PTR(line);
-	TRACE_PTR(aliases);
+	TRACE_PTR(aliases);*/
 
+	if (st->fp==NULL)
+		st->compat_mode_active=0;
+	
 	if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) {
+		*errnop=errno;
 		TRACE_OUT(files_servent);
 		return (NS_UNAVAIL);	
 	}
 	
-	if (stayopen==0)
-		files_setent(1,st);	
+/*	if (stayopen==0)
+		files_setent(1,st);	*/
+	if (serv_mdata->how == nss_lt_all)
+		stayopen = 1;
+	else {
+		rewind(st->fp);
+		stayopen = st->stayopen;
+	}
 	
 	TRACE_POINT();
-	rv=NS_NOTFOUND;
+	rv = NS_NOTFOUND;
 	do {
 		TRACE_PTR(serv);
-		memset(serv,0,sizeof(struct servent));
-		*aliases='\0';
+//		memset(serv,0,sizeof(struct servent));
+//		*aliases='\0';
+//		servent_init(serv);
+				
+		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);
+				line[linesize]='\0';										
+			}			
 		}
+		
+		
+/*		TRACE_POINT();
+		if (!st->compat_mode_active && *p=='+') {
+			st->compat_mode_active=1;
+			TRACE_POINT();
+		}*/
+		
+		if (st->compat_mode_active!=0) {
+			switch (serv_mdata->how) {
+				case nss_lt_name:
+					rv = nsdispatch(retval,compat_dtab,"services","getservbyname_r",
+						compat_src,name,proto,serv,buffer,bufsize,errnop);
+					break;
+				case nss_lt_id:
+					rv = nsdispatch(retval,compat_dtab,"services","getservbyport_r",
+						compat_src,port,proto,serv,buffer,bufsize,errnop);
+					break;
+				case nss_lt_all:
+					rv = nsdispatch(retval,compat_dtab,"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 ( !(rv & NS_TERMINATE) )
+				goto fin;
+			else
+				continue;*/
+/*			TRACE_INT(rv & NS_TERMINATE);
+			if ((!(rv & NS_TERMINATE)) || (how!=nss_lt_all))
+			{
+				st->compat_mode_active=0;
+				TRACE_POINT();
+			}*/
+			
+//			continue;
+		}
+
+		rv = servent_unpack(line,serv,aliases,aliases_size,errnop);
+		if (rv !=0 ) {
+			if (*errnop == 0)
+				continue;
+			else {
+				rv = NS_RETURN;
+				break;
+			}
+		}
+			
+//		if (servent_unpack(p,linesize,buffer,bufsize) == -1)
+	//		continue;
+		
+		
 /*		if (*p == '#')
 			continue;
 		cp = strpbrk(p, "#\n");
@@ -500,7 +608,7 @@
 		}		
 		*q = NULL;			*/
 		
-		switch (how)
+		switch (serv_mdata->how)
 		{
 			case nss_lt_name:
 				TRACE_STR(serv->s_name);
@@ -513,47 +621,54 @@
 				continue;
 			gotname:
 				if (proto == 0 || strcmp(serv->s_proto, proto) == 0)
-					rv=NS_SUCCESS;
+					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;
+					rv = NS_SUCCESS;
 				break;
 			case nss_lt_all:
-				rv = (NS_SUCCESS);
+				rv = NS_SUCCESS;
 				break;
 		};
 		
 	} while (!(rv & NS_TERMINATE));
 	
-	if (stayopen==0)
-		files_endent(st);
+//fin:	
+//	if (stayopen==0)
+//		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;
 	
 	TRACE_OUT(files_servent);
-	return rv;
+	return (rv);
 }
 
-static void files_setent(int f, struct files_state * st)
+/*static void files_setent(int f, struct files_state * st)
 {
 	TRACE_IN(files_setent);
-/*	struct files_state * st;
+/	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;
+	st->compat_mode_active=0;
 
 	TRACE_OUT(files_setent);
 	//return (NS_SUCCESS);	
@@ -561,21 +676,22 @@
 
 static void files_endent(struct files_state * st)
 {
-/*	struct files_state *st;
+/	struct files_state *st;
 	int rv;
 
 	rv = files_getstate(&st);
 	if (rv != 0)
 		return (NS_UNAVAIL);
-	*/
+	/
 	TRACE_IN(files_endent);
 //	if (st->fp != NULL)
 	//	fclose(st->fp);
 	st->stayopen = 0;
+	st->compat_mode_active = 0;
 	TRACE_OUT(files_endent);
 //	return (NS_SUCCESS);
 }
-
+*/
 /*static int 
 files_getservent_r(void * retval, void * mdata, va_list ap)
 {
@@ -611,35 +727,33 @@
 	int f;
 
 	TRACE_IN(files_setservent);
-	f=va_arg(ap,int);
 
 	rv = files_getstate(&st);
 	if (rv != 0) {
 		TRACE_OUT(files_setservent);
 		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);
 	TRACE_OUT(files_setservent);
-	return (NS_SUCCESS);
-}
-
-static 	int 
-files_endservent(void * retval, void * mdata, va_list ap)
-{
-	struct files_state *st;
-	int rv;
-	
-	TRACE_IN(files_endservent);
-	rv = files_getstate(&st);
-	if (rv != 0) {
-		TRACE_OUT(files_endservent);
-		return (NS_UNAVAIL);
-	}
-	
-	files_endent(st);
-	TRACE_OUT(files_endservent);
-	return (NS_SUCCESS);
+	return (NS_UNAVAIL);
 }
 
 /* files backend implementation - end */
@@ -664,9 +778,8 @@
 	int resultbuflen;
 	char buf[YPMAXRECORD + 2];
 	
-	struct nis_state * ns;
+	struct nis_state * st;
 	int rv;
-	int stayopen;
 	
 	enum nss_lookup_type how;	
 	char * name;
@@ -679,19 +792,32 @@
 	int * errnop;
 	
 	char **aliases;
-	char * line;
-	size_t line_size;
+	int aliases_size;
 
-	char *p;
-	char **cp;//, **q, *endp;
+//	char *p;
+//	char **cp;//, **q, *endp;
 //	long l;	
 			
 	TRACE_IN(nis_servent);
-	rv = nis_getstate(&ns);
-	if (rv != 0) {
-		TRACE_OUT(nis_servent);
-		return (NS_UNAVAIL);
-	}
+	
+	/*
+				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;
+				}
+				
+				memcpy(buffer,line,linesize);
+				line[linesize]='\0';										
+	
+	*/
 	
 /*	aliases=_ALIGN((char **)buffer);
 	line=aliases+sizeof(char *)*_MAXALIASES;
@@ -711,17 +837,17 @@
 		case nss_lt_name:
 			name = va_arg(ap, char *);
 			proto = va_arg(ap, char *);
-			stayopen=0;
+//			stayopen=0;
 			TRACE_POINT();
 			break;
 		case nss_lt_id:
 			port = va_arg(ap, int);
 			proto = va_arg(ap, char *);
-			stayopen=0;
+//			stayopen=0;
 			TRACE_POINT();
 			break;
 		case nss_lt_all:
-			stayopen=1;
+//			stayopen=1;
 			TRACE_POINT();
 			break;		
 		default:
@@ -734,13 +860,15 @@
 	bufsize = va_arg(ap, size_t);
 	errnop = va_arg(ap,int *);
 	
-	SERVENT_BUFFER_UNPACK(buffer, bufsize,line,line_size,aliases)
-	TRACE_PTR(buffer);
-	TRACE_PTR(line);
-	TRACE_PTR(aliases);
+	*errnop = nis_getstate(&st);
+	if (errnop != 0) {
+		TRACE_OUT(nis_servent);
+		return (NS_UNAVAIL);
+	}	
 	
-	if (!ns->yp_domain) {
-		if (yp_get_default_domain(&ns->yp_domain)) {
+	if (!st->yp_domain[0]) {
+		if (getdomainname(st->yp_domain,sizeof st->yp_domain)) {
+			*errnop=errno;
 			TRACE_OUT(nis_servent);
 			return (NS_UNAVAIL);
 		}
@@ -752,16 +880,14 @@
 		{
 			case nss_lt_name:
 					snprintf(buf, sizeof(buf), "%s/%s", name, proto);
-					if (yp_match(ns->yp_domain, "services.byname", buf, strlen(buf), &resultbuf, &resultbuflen)) {
-						TRACE_STR(ns->yp_domain);
-						TRACE_STR(buf);
-						TRACE_POINT();
-						rv = (NS_NOTFOUND);
-					} else {					
+					if (yp_match(st->yp_domain, "services.byname", buf, strlen(buf), &resultbuf, &resultbuflen)) {
+						rv = NS_NOTFOUND;
+						goto fin;
+					}/* else {					
 						snprintf(line, line_size, "%.*s\n", resultbuflen, resultbuf);	
 						rv = (servent_unpack(line,serv,aliases,_MAXALIASES)==-1) ? (NS_NOTFOUND) : (NS_SUCCESS);
 						free(resultbuf);				
-					}
+					}*/
 				break;
 			case nss_lt_id:
 				snprintf(buf, sizeof(buf), "%d/%s", ntohs(port), proto);	
@@ -775,68 +901,84 @@
 				 * 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),
+				if ((rv = yp_match(st->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))
-							rv = (NS_NOTFOUND);
-						else
-							rv = (NS_SUCCESS);
-					} else
-						rv = (NS_NOTFOUND);
-				} else
-					rv = (NS_SUCCESS);
-				/* TODO: eliminate rv = (NS_SUCCESS) from the above fragment - make it
-				look better */
-					
-				if (rv == NS_SUCCESS) {
-					snprintf(line, line_size, "%.*s\n", resultbuflen, resultbuf);	
-					rv = (servent_unpack(line,serv,aliases,_MAXALIASES)==-1) ? (NS_NOTFOUND) : (NS_SUCCESS);
-					free(resultbuf);				
+						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:
-				memset(serv,0,sizeof(*serv));
+/*				memset(serv,0,sizeof(*serv));
 				*aliases='\0';
-				
-				if (!ns->yp_stepping) {
-					free(ns->yp_key);
-					rv = yp_first(ns->yp_domain, "services.byname", &ns->yp_key,
-						&ns->yp_keylen, &resultbuf, &resultbuflen);
+	*/			
+				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) {
-						ns->yp_stepping = 0;
-						rv = (NS_RETURN);
-					} else
-						rv = (NS_SUCCESS);
-					ns->yp_stepping = 1;
+						st->yp_stepping = 0;
+						rv = NS_NOTFOUND;
+						goto fin;
+					}
+					st->yp_stepping = 1;
 				} else {
-					lastkey = ns->yp_key;
-					rv = yp_next(ns->yp_domain, "services.byname", ns->yp_key,
-						ns->yp_keylen, &ns->yp_key, &ns->yp_keylen, &resultbuf,
+					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) {
-						ns->yp_stepping = 0;
-						rv = (NS_RETURN);
-					} else
-						rv = (NS_SUCCESS);
-				}
-				/* TODO: same as above - eliminate rv = (NS_SUCCESS). Probably by
-				using labels */
-		
-				if (rv == NS_SUCCESS) {
-					snprintf(line, line_size, "%.*s\n", resultbuflen, resultbuf);	
-					rv = (servent_unpack(line,serv,aliases,_MAXALIASES)==-1) ? (NS_NOTFOUND) : (NS_SUCCESS);
-					free(resultbuf);				
-				}
+						st->yp_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;
+		}
+				
+		//snprintf(buffer, resultbuflen+1, "%.*s\n", resultbuflen, resultbuf);	
+		/* servent_unpack expects lines terminated with \n -- make it happy */
+		memcpy(buffer,resultbuf,resultbuflen);
+		buffer[resultbuflen]='\n';
+		buffer[resultbuflen+1]='\0';
 		
+		if (servent_unpack(buffer,serv,aliases,aliases_size,errnop) != 0) {
+			if (*errnop == 0)
+				rv = NS_NOTFOUND;
+			else
+				rv = NS_RETURN;
+		}
+		free(resultbuf);								
+
 		TRACE_INT(rv);
 		TRACE_INT(!(rv & NS_TERMINATE));
 	} while (!(rv & NS_TERMINATE) && (how==nss_lt_all));
 	
-	if (rv==NS_SUCCESS) {
+fin:
+	if ((rv==NS_SUCCESS) && (retval != NULL)) {
 		*(struct servent **)retval=serv;
 		TRACE_POINT();
 	}
@@ -845,7 +987,38 @@
 	return rv;
 }
 
-static int 
+static int
+nis_setservent(void * result, void * mdata, va_list ap)
+{
+	struct nis_state *st;
+	int rv;
+
+	TRACE_IN(nis_setservent);
+
+	rv = nis_getstate(&st);
+	if (rv != 0) {
+		TRACE_OUT(nis_setservent);
+		return (NS_UNAVAIL);	
+	}
+	
+	switch ((enum constants) mdata)
+	{
+		case SETSERVENT:
+		case ENDSERVENT:
+			free(st->yp_key);
+			st->yp_key = NULL;	
+			st->yp_stepping = 0;
+		break;
+		default:
+			break;
+	};
+//	st->compat_mode_active = 0;
+		
+	TRACE_OUT(nis_setservent);
+	return (NS_UNAVAIL);
+}
+
+/*static int 
 nis_getservbyname_r(void * result, void * mdata, va_list ap)
 {
 	struct nis_state * ns;
@@ -879,9 +1052,9 @@
 	
 	SERVENT_BUFFER_UNPACK(buffer,bufsize,line,line_size,aliases)
 	
-	/* TODO: do we need this ? */
-/*	if (bufsize < _MAXLINELEN+1)
-		return (NS_TRYAGAIN);*/
+	/ TODO: do we need this ? /
+/	if (bufsize < _MAXLINELEN+1)
+		return (NS_TRYAGAIN);/
 	
 	if(!ns->yp_domain) {
 		if(yp_get_default_domain(&ns->yp_domain))
@@ -899,7 +1072,7 @@
 		return (NS_NOTFOUND);
 	}
 		
-	/* getservent() expects lines terminated with \n -- make it happy */
+	/ 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);
@@ -942,7 +1115,7 @@
 
 	SERVENT_BUFFER_UNPACK(buffer,bufsize,line,line_size,aliases);
 	
-	/* TODO - do we need this? */
+	/ TODO - do we need this? /
 //	if (bufsize<_MAXLINELEN+1)
 //		return (NS_TRYAGAIN);
 	
@@ -958,7 +1131,7 @@
 			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
@@ -966,7 +1139,7 @@
 	 * 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) {
@@ -1048,7 +1221,7 @@
 		free(resultbuf);
 	} while (!(rv & NS_TERMINATE ));
 
-	/* getservent() expects lines terminated with \n -- make it happy */
+	/ getservent() expects lines terminated with \n -- make it happy /
 	return rv == NS_RETURN ? NS_NOTFOUND : rv;	
 }
 
@@ -1068,8 +1241,8 @@
 	if (rv != 0)
 		return (NS_UNAVAIL);
 	
-	/* these 2 lines possibly should be moved into the function 
-	or nis_endstate should be called */
+	/ these 2 lines possibly should be moved into the function 
+	or nis_endstate should be called /
 	free(ns->yp_key);
 	ns->yp_key = NULL;
 	
@@ -1077,62 +1250,70 @@
 	ns->yp_domain = NULL;
 	
 	return (NS_SUCCESS);
-}
+}*/
 
 #endif
 
 /* nis backend implementation - end */
 
 /* compat backend implementation - begin */
-static 	void
-compat_endstate(void *p)
+static int
+compat_setservent(void * retval, void * mdata, va_list ap)
 {
-	TRACE_IN(compat_endstate);
+	static const ns_src compat_src[] = {
+#ifdef YP
+		{ NSSRC_NIS, NS_SUCCESS },
+#endif
+		{ NULL, 0 }
+	};
+	ns_dtab compat_dtab[] = {
+#ifdef YP
+		{ NSSRC_NIS, nis_setservent, mdata },
+#endif
+		{ NULL, NULL, NULL }
+	};		
 	
-	FILE * f;
+	int f;	
+	(void)files_setservent(retval,mdata,ap);
 	
-	if (p == NULL)
-		return;
-	
-	f = ((struct files_state *)p)->fp;
-	if (f != NULL)
-		fclose(f);
-	
-	free(p);
-	TRACE_OUT(compat_endstate);
-}
-
-static int
-compat_servent(void * retval, void * mdata, va_list ap)
-{
+	switch ((enum constants)mdata)
+	{
+		case SETSERVENT:			
+			f=va_arg(ap,int);
+			(void)nsdispatch(retval,compat_dtab,"services","setservent",compat_src,f);
+		break;
+		case ENDSERVENT:
+			(void)nsdispatch(retval,compat_dtab,"services","endservent",compat_src);
+			break;
+		default:
+			break;
+	}
+		
+	return (NS_UNAVAIL);
 }
 
-static int
-compat_setservent(void * retval, void * mdata, va_list ap)
-{
-}
-
-compat_endservent(void * retval, void * mdata, va_list ap)
-{
-}
 /* compat backend implementation - end */
 
 int 
 my_getservbyname_r(const char * name, const char * proto, 
 	struct servent * serv, char * buffer, size_t bufsize, struct servent ** result)
 {
+	static const struct servent_mdata mdata = { nss_lt_name, 0 };
+	static const struct servent_mdata compat_mdata = { nss_lt_name, 1 };
+
 	static const ns_dtab dtab[] = {
-		{ NSSRC_FILES, files_servent, (void *)nss_lt_name },
+		{ NSSRC_FILES, files_servent, (void *)&mdata },
 #ifdef YP
 		{ NSSRC_NIS, nis_servent, (void *)nss_lt_name },
 #endif
-//		{ NSSRC_COMPAT, compat_passwd, (void *)nss_lt_all },
+		{ NSSRC_COMPAT, files_servent, (void *)&compat_mdata },
 		{ NULL, NULL, NULL }
 	};
+	
 	int	rv, ret_errno;
 
 	TRACE_IN(my_getservbyname_r);
-	servent_init(serv);
+//	servent_init(serv);
 	ret_errno = 0;
 	*result = NULL;
 	rv = nsdispatch(result, dtab, NSDB_SERVICES, "getservbyname_r", defaultsrc,
@@ -1152,17 +1333,20 @@
 my_getservbyport_r(int port, const char * proto, struct servent * serv, char * buffer, 
 	size_t bufsize, struct servent ** result)
 {
+	static const struct servent_mdata mdata = { nss_lt_id, 0 };
+	static const struct servent_mdata compat_mdata = { nss_lt_id, 1 };
+	
 	static const ns_dtab dtab[] = {
-		{ NSSRC_FILES, files_servent, (void *)nss_lt_id },
+		{ NSSRC_FILES, files_servent, (void *)&mdata },
 #ifdef YP
 		{ NSSRC_NIS, nis_servent, (void *)nss_lt_id },
 #endif
-//		{ NSSRC_COMPAT, compat_passwd, (void *)nss_lt_all },

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



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