Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Oct 2004 14:17:49 +0400
From:      Michael Bushkov <bushman@rsu.ru>
To:        hackers@freebsd.org
Cc:        "Christian S.J. Peron" <csjp@freebsd.org>
Subject:   nsdispatch services patch + lookupd
Message-ID:  <1098785868.61417.39.camel@localhost>

next in thread | raw e-mail | index | archive | help

--=-NBIlVcBobXF4E8EHBWGR
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hello!
I've been asking to commit nsdispatch services patch (the patch, which
makes getserv* functions run over nsdispatch interface) since the middle
of summer. And it's still not committed. The problem is that the next
release of the lookupd daemon (which i support) depends on this patch,
as it implements 'services' data source.

I've included the patch once again here. Is it possible to commit it in
the nearest future?

P.S.
Patch should be applied in /usr/src/lib/libc/net.

-- 
Michael Bushkov <bushman@rsu.ru>
Rostov State University

--=-NBIlVcBobXF4E8EHBWGR
Content-Disposition: attachment; filename=getserv.patch
Content-Type: text/x-patch; name=getserv.patch; charset=KOI8-R
Content-Transfer-Encoding: 7bit

*** ./initial/getservent.c	Wed Jul 14 18:06:32 2004
--- getservent.c	Thu Jul 15 13:21:01 2004
***************
*** 29,44 ****
--- 29,49 ----
   * 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.
   */
  
+  /* 
+   * getserv* functions implementation was adapted to nsswitch model by Michael Bushkov
+   */
+ 
  #if defined(LIBC_SCCS) && !defined(lint)
  static char sccsid[] = "@(#)getservent.c	8.1 (Berkeley) 6/4/93";
  #endif /* LIBC_SCCS and not lint */
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD: src/lib/libc/net/getservent.c,v 1.12 2003/02/27 13:40:00 nectar Exp $");
  
+ #include "namespace.h"
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <arpa/inet.h>
  #include <netdb.h>
  #include <stdio.h>
***************
*** 46,91 ****
  #include <stdlib.h>
  #ifdef YP
  #include <rpc/rpc.h>
  #include <rpcsvc/yp_prot.h>
  #include <rpcsvc/ypclnt.h>
- static int serv_stepping_yp = 0;
  #endif
  #include "libc_private.h"
  
  #define	MAXALIASES	35
  
! static FILE *servf = NULL;
! static char line[BUFSIZ+1];
! static struct servent serv;
! static char *serv_aliases[MAXALIASES];
! int _serv_stayopen;
  
  #ifdef YP
! char *___getservbyname_yp = NULL;
! char *___getservbyproto_yp = NULL;
! int ___getservbyport_yp = 0;
! static char *yp_domain = NULL;
  
  static int
! _getservbyport_yp(line)
! 	char *line;
  {
  	char *result;
  	int resultlen;
  	char buf[YPMAXRECORD + 2];
  	int rv;
  
! 	snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),
! 						___getservbyproto_yp);
  
! 	___getservbyport_yp = 0;
! 	___getservbyproto_yp = NULL;
  
! 	if(!yp_domain) {
! 		if(yp_get_default_domain(&yp_domain))
! 			return (0);
  	}
  
  	/*
  	 * We have to be a little flexible here. Ideally you're supposed
  	 * to have both a services.byname and a services.byport map, but
--- 51,602 ----
  #include <stdlib.h>
  #ifdef YP
  #include <rpc/rpc.h>
  #include <rpcsvc/yp_prot.h>
  #include <rpcsvc/ypclnt.h>
  #endif
+ #include <errno.h>
+ #include <pthread.h>
+ #include <pthread_np.h>
+ #include <nss.h>
  #include "libc_private.h"
+ #include "nss_tls.h"
  
  #define	MAXALIASES	35
  
! /* 
!  * declarations' beginning
!  */
! #define _SERVENT_UNPACK_AGAIN -1
! #define _SERVENT_UNPACK_RETURN 0
! 
! static const ns_src defaultsrc[] = { 
!         { NSSRC_COMPAT, NS_SUCCESS },
!         { 0 }
! };
! 
! 
! struct files_state {
! 	FILE * servf;
! 	char line[BUFSIZ+1];
! 	struct servent serv;
! 	char *serv_aliases[MAXALIASES];
! 	int _serv_stayopen;
! 	
! 	int _notfound_block;
! };
! 
! static	void	files_endstate(void * files_state);
! NSS_TLS_HANDLING(files);
! 
! static	int	 _files_setservent(void *, void *, va_list);
! static	int	 _files_endservent(void *, void *, va_list);
! static	int	 _files_getservent(void *, void *, va_list);
! static	int	 _files_getservbyname(void *, void *, va_list);
! static	int	 _files_getservbyport(void *, void *, va_list);
! 
! #ifdef YP
! struct nis_state {
! 	char *yp_domain;
! 	int serv_stepping_yp;
! 	
! 	char *key;
! 	int keylen;
! 
! 	char line[BUFSIZ+1];
! 	struct servent serv;
! 	char *serv_aliases[MAXALIASES];
! 
! 	int _notfound_block;
! };
! 
! static	void	nis_endstate(void * nis_state);
! NSS_TLS_HANDLING(nis);
! 
! static	int	 _nis_setservent(void *, void *, va_list);
! static	int	 _nis_endservent(void *, void *, va_list);
! static	int	 _nis_getservent(void *, void *, va_list);
! static	int	 _nis_getservbyname(void *, void *, va_list);
! static	int	 _nis_getservbyport(void *, void *, va_list);
! #endif
! 
! /*
!  * indicates what source is currently used by compat mode
!  */
! enum compat_condition {
! 	FILES_STATE = 0
! #ifdef YP	
! 	, NIS_STATE = 1
! #endif
! };
! 
! /*
!  * compat mode uses existing files_state and nis_state structures, because it
!  * should combine files and nis modules functionality
!  */
! struct compat_state {
! 	struct files_state files_st;
! #ifdef YP
! 	struct nis_state nis_st;
! #endif
! 	
! 	enum compat_condition current_condition;
! };
! 
! static	void	compat_endstate(void * compat_state);
! NSS_TLS_HANDLING(compat);
! 
! static	int	 _compat_setservent(void *, void *, va_list);
! static	int	 _compat_endservent(void *, void *, va_list);
! static	int	 _compat_getservent(void *, void *, va_list);
! static	int	 _compat_getservbyname(void *, void *, va_list);
! static	int	 _compat_getservbyport(void *, void *, va_list);
! 
! /*
!  * declarations' ending
!  */
! 
! /*
!  * processes the line, pointed by p and fills the dest structure
!  * q is the pointer, which should be kept during one service entry 
!  * traversal 
!  */
! static int
! _servent_unpack(struct servent * dest,char ** serv_aliases, char *p, char *** q)
! {
! 	char *cp;
! 
! 	if (*p == '#')
! 		return _SERVENT_UNPACK_AGAIN;
! 	cp = strpbrk(p, "#\n");
! 	if (cp == NULL)
! 		return _SERVENT_UNPACK_AGAIN;
! 	*cp = '\0';
! 	dest->s_name = p;
! 	p = strpbrk(p, " \t");
! 	if (p == NULL)
! 		return _SERVENT_UNPACK_AGAIN;
! 	*p++ = '\0';
! 	while (*p == ' ' || *p == '\t')
! 		p++;
! 	cp = strpbrk(p, ",/");
! 	if (cp == NULL)
! 		return _SERVENT_UNPACK_AGAIN;
! 	*cp++ = '\0';
! 	dest->s_port = htons((u_short)atoi(p));
! 	dest->s_proto = cp;
! 	*q = dest->s_aliases = serv_aliases;
! 	cp = strpbrk(cp, " \t");
! 	if (cp != NULL)
! 		*cp++ = '\0';
! 	while (cp && *cp) {
! 		if (*cp == ' ' || *cp == '\t') {
! 			cp++;
! 			continue;
! 		}
! 		if (*q < &(serv_aliases)[MAXALIASES - 1])
! 			*(*q)++ = cp;
! 		cp = strpbrk(cp, " \t");
! 		if (cp != NULL)
! 			*cp++ = '\0';
! 	}
! 	
! 	*(*q) = NULL;
! 	return _SERVENT_UNPACK_RETURN;
! }
! 
! 
! static void
! files_endstate(void * p)
! {
! 	FILE * f;
! 	
! 	if (p == NULL)
! 		return;
! 	f = ((struct files_state *)p)->servf;
! 	if (f != NULL)
! 		fclose(f);
! 	free(p);	
! }
!  
!  /*
!   * gets compat's files state if we are in compat mode and global files state otherwise
!   */
!  static int
! _get_compat_files_state(struct files_state ** state,void * mdata)
! {
! 	int rv;
! 	enum compat_condition * current_condition;
! 
! 	current_condition=(enum compat_condition *)mdata;	
! 	if (current_condition==NULL) {
! 		rv=files_getstate(state);
! 		if (rv != 0)
! 			return -1;
! 	} else {
! 		struct compat_state * c_st;
! 
! 		rv=compat_getstate(&c_st);		
! 		if (rv !=0)
! 			return -1;
! 		
! 		*state=&c_st->files_st;
! 	}
! 	return 0;
! }
! 
! /*
!  * changes compat_condition state, passed as mdata pointer
!  */
! static int
! _redispatch_to_nis(void * mdata)
! {
! #ifdef YP
! 	if (mdata==NULL)
! 		return -1;
! 	else {
! 		enum compat_condition * current_condition;
! 		current_condition=(enum compat_condition *)mdata;	
! 		*current_condition=NIS_STATE;
! 		return 0;
! 	}
! #else
! 	return -1;
! #endif
! }
! 
! static int
! _files_setservent(void *retval, void *mdata, va_list ap)
! {
! 	struct files_state * st;	
! 	int f, rv;
! 	
! 	f = va_arg(ap, int);	
! 	rv=_get_compat_files_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 			
! 	if (st->servf == NULL)
! 		st->servf = fopen(_PATH_SERVICES, "r" );
! 	else
! 		rewind(st->servf);
! 	st->_serv_stayopen |= f;
! 	st->_notfound_block = 0;
! 	
! 	return (NS_UNAVAIL);
! }
! 
! static int
! _files_endservent(void *retval, void *mdata, va_list ap)
! {
! 	int rv;
! 	struct files_state * st;
! 	
! 	rv=_get_compat_files_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 	
! 	if (st->servf) {
! 		fclose(st->servf);
! 		st->servf = NULL;
! 	}
! 	st->_serv_stayopen = 0;
! 	st->_notfound_block=0;
! 	
! 	return (NS_UNAVAIL);
! }
! 
! static int
! _files_getservent(void *retval, void *mdata, va_list ap)
! {
! 	int rv;
! 	struct files_state * st;
! 	
! 	char *p, **q;
! 	int parse_retval=_SERVENT_UNPACK_RETURN;
! 
! 	rv=_get_compat_files_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 		
! 	if (st->_notfound_block!=0)
! 		return (NS_NOTFOUND);
! 		
! 	if (st->servf == NULL && (st->servf = fopen(_PATH_SERVICES, "r" )) == NULL)
! 		return (NS_UNAVAIL);
! 
! 	do {
! 		if ((p = fgets(st->line, BUFSIZ, st->servf)) == NULL) 	{
! 			st->_notfound_block=1;
! 			return (NS_NOTFOUND);
! 		}
! 	
! 		if (*p=='+') {
! 			if (_redispatch_to_nis(mdata)==0)
! 				return (NS_UNAVAIL);
! 			else {
! 				parse_retval=_SERVENT_UNPACK_AGAIN;
! 				continue;
! 			}
! 		}
! 		
! 		parse_retval=_servent_unpack(&st->serv,st->serv_aliases,p,&q);
! 	} while (parse_retval==_SERVENT_UNPACK_AGAIN);
! 
! 	*(struct servent **)retval=&st->serv;
! 	return (NS_SUCCESS);
! }
! 
! static int
! _files_getservbyname(void *retval, void *mdata, va_list ap)
! {
! 	struct files_state * st;
! 	int rv;
! 	
! 	char *curline, **q;
! 	int parse_retval=_SERVENT_UNPACK_RETURN;
! 	
! 	struct servent *p;
! 	char **cp;
! 
! 	const char * name;
! 	const char * proto;
! 	
!  	name = va_arg(ap, const char *);
!  	proto = va_arg(ap, const char *);
! 	
! 	rv=_get_compat_files_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);	
! 	
! 	/* setservent analog */
! 	if (st->servf == NULL)
! 		st->servf = fopen(_PATH_SERVICES, "r" );
! 	else
! 		rewind(st->servf);
! 	
! 	for (;;) {
! 		do {
! 			if ((curline = fgets(st->line, BUFSIZ, st->servf)) == NULL)
! 				return (NS_NOTFOUND);
! 		
! 			if (*curline=='+') {
! 				if ((mdata!=NULL) && (_nis_getservbyname(retval,mdata,ap)==(NS_SUCCESS))) {
! 					if (!st->_serv_stayopen)
! 						_files_endservent(retval,mdata,ap);
! 					return (NS_SUCCESS);
! 				} else
! 					continue;
! 			}
! 			
! 			parse_retval=_servent_unpack(&st->serv,st->serv_aliases,curline,&q);
! 		} while (parse_retval==_SERVENT_UNPACK_AGAIN);
! 		
! 		p=&(st->serv);
! 
! 		if (strcmp(name, p->s_name) == 0)
! 			goto gotname;
! 		for (cp = p->s_aliases; *cp; cp++)
! 			if (strcmp(name, *cp) == 0)
! 				goto gotname;
! 
! 			continue;
! 		
! 		gotname:				
! 		if (proto == 0 || strcmp(p->s_proto, proto) == 0)
! 			break;
! 	}
! 	
! 	if (!st->_serv_stayopen)
! 		_files_endservent(retval,mdata,ap);
! 
! 	if (p==NULL)
! 		return (NS_NOTFOUND);
! 	else {
! 		*(struct servent **)retval=&st->serv;
! 		return (NS_SUCCESS);
! 	}
! }
! 
! static int
! _files_getservbyport(void *retval, void *mdata, va_list ap)
! {
! 	struct files_state * st;
! 	int rv;
! 	
! 	char *curline, **q;
! 	int parse_retval=_SERVENT_UNPACK_RETURN;
! 
! 	int port;
! 	const char * proto;
! 		
! 	struct servent *p;
! 
!  	port = va_arg(ap, int);
!  	proto = va_arg(ap, const char *);	
! 	
! 	rv=_get_compat_files_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);	
! 	
! 	/* setservent analog */
! 	if (st->servf == NULL)
! 		st->servf = fopen(_PATH_SERVICES, "r" );
! 	else
! 		rewind(st->servf);
! 	
! 	for (;;) {
! 		do {
! 			if ((curline = fgets(st->line, BUFSIZ, st->servf)) == NULL)
! 				return (NS_NOTFOUND);
! 		
! 			if (*curline=='+') {
! 				if ((mdata!=NULL) && (_nis_getservbyport(retval,mdata,ap)==(NS_SUCCESS))) {
! 					if (!st->_serv_stayopen)
! 						_files_endservent(retval,mdata,ap);
! 					return (NS_SUCCESS);
! 				} else
! 					continue;
! 			}
! 		
! 			parse_retval=_servent_unpack(&st->serv,st->serv_aliases,curline,&q);
! 		} while (parse_retval==_SERVENT_UNPACK_AGAIN);
! 
! 		
! 		p=&(st->serv);
! 
! 		if (p->s_port != port)
! 			continue;
! 		if (proto == 0 || strcmp(p->s_proto, proto) == 0)
! 			break;
! 	}
! 
! 	if (!st->_serv_stayopen)
! 		_files_endservent(retval,mdata,ap);
! 
! 	if (p==NULL)
! 		return (NS_NOTFOUND);
! 	else {
! 		*(struct servent **)retval=&(st->serv);
! 		return (NS_SUCCESS);
! 	}	
! }
! 
  
  #ifdef YP
! 
! static void
! nis_endstate(void * p)
! {
! 	struct nis_state * st;
! 	if (p == NULL)
! 		return;
! 
! 
! 	st=(struct nis_state *)p;	
! 	if (st->key)
! 	        free(st->key);
! 	free(p);
! }
! 
!  /*
!   * gets compat's nis state if we are in compat mode and global nis state otherwise
!   */
! static int
! _get_compat_nis_state(struct nis_state ** state,void * mdata)
! {
! 	int rv;
! 	enum compat_condition * current_condition;
! 
! 	current_condition=(enum compat_condition *)mdata;	
! 	if (current_condition==NULL) {
! 		rv=nis_getstate(state);
! 		if (rv != 0)
! 			return -1;
! 	} else {
! 		struct compat_state * c_st;
! 
! 		rv=compat_getstate(&c_st);		
! 		if (rv !=0)
! 			return -1;
! 		
! 		*state=&c_st->nis_st;
! 	}
! 	return 0;
! }
  
  static int
! _nis_getservbyname(void *retval, void *mdata, va_list ap)
  {
+ 	char ** q;
  	char *result;
  	int resultlen;
  	char buf[YPMAXRECORD + 2];
+ 
+ 	const char * name;
+ 	const char * proto;
+ 	
+ 	struct nis_state * st;
  	int rv;
  
! 	rv=_get_compat_nis_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 
!     	name = va_arg(ap, const char *);
!     	proto = va_arg(ap, const char *);
!     
! 	if(!st->yp_domain) {
! 		if(yp_get_default_domain(&st->yp_domain))
! 			return (NS_UNAVAIL);
! 	}
  
! 	snprintf(buf, sizeof(buf), "%s/%s", name, proto);
  
! 	if (yp_match(st->yp_domain, "services.byname", buf, strlen(buf),
! 						&result, &resultlen)) {
! 		return(NS_NOTFOUND);
! 	}
! 		
! 	/* getservent() expects lines terminated with \n -- make it happy */
! 	snprintf(st->line, BUFSIZ, "%.*s\n", resultlen, result);
! 	free(result);
! 
! 	if (_servent_unpack(&st->serv,st->serv_aliases,st->line,&q)!=_SERVENT_UNPACK_RETURN)
! 		return (NS_UNAVAIL);
! 
! 	*(struct servent **)retval=&st->serv;	
! 	return (NS_SUCCESS);
! }
! 
! static int
! _nis_getservbyport(void *retval, void *mdata, va_list ap)
! {
! 	char ** q;
! 	
! 	int port;
! 	const char * proto;
! 
! 	char *result;
! 	int resultlen;
! 	char buf[YPMAXRECORD + 2];
! 	int rv;
! 
! 	struct nis_state * st;
! 	rv=_get_compat_nis_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 
!     port = va_arg(ap, int);
!     proto = va_arg(ap, const char *);	
! 
! 	snprintf(buf, sizeof(buf), "%d/%s", ntohs(port),
! 						proto);
! 
! 	if(!st->yp_domain) {
! 		if(yp_get_default_domain(&st->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
***************
*** 93,280 ****
  	 * 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(yp_domain, "services.byport", buf, strlen(buf),
  						&result, &resultlen))) {
  		if (rv == YPERR_MAP) {
! 			if (yp_match(yp_domain, "services.byname", buf,
  					strlen(buf), &result, &resultlen))
! 			return(0);
  		} else
! 			return(0);
  	}
  		
  	/* getservent() expects lines terminated with \n -- make it happy */
! 	snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
! 
  	free(result);
! 	return(1);
  }
  
  static int
! _getservbyname_yp(line)
! 	char *line;
  {
! 	char *result;
! 	int resultlen;
! 	char buf[YPMAXRECORD + 2];
! 
! 	if(!yp_domain) {
! 		if(yp_get_default_domain(&yp_domain))
! 			return (0);
! 	}
  
! 	snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,
! 						___getservbyproto_yp);
  
! 	___getservbyname_yp = 0;
! 	___getservbyproto_yp = NULL;
  
! 	if (yp_match(yp_domain, "services.byname", buf, strlen(buf),
! 						&result, &resultlen)) {
! 		return(0);
! 	}
  		
! 	/* getservent() expects lines terminated with \n -- make it happy */
! 	snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
! 
! 	free(result);
! 	return(1);
  }
  
  static int
! _getservent_yp(line)
! 	char *line;
  {
! 	static char *key = NULL;
! 	static int keylen;
  	char *lastkey, *result;
  	int resultlen;
  	int rv;
  
! 	if(!yp_domain) {
! 		if(yp_get_default_domain(&yp_domain))
! 			return (0);
  	}
  
! 	if (!serv_stepping_yp) {
! 		if (key)
! 			free(key);
! 		if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,
  			     &result, &resultlen))) {
! 			serv_stepping_yp = 0;
! 			return(0);
! 		}
! 		serv_stepping_yp = 1;
  	} else {
! 		lastkey = key;
! 		rv = yp_next(yp_domain, "services.byname", key, keylen, &key,
! 			     &keylen, &result, &resultlen);
  		free(lastkey);
  		if (rv) {
! 			serv_stepping_yp = 0;
! 			return (0);
  		}
  	}
  
  	/* getservent() expects lines terminated with \n -- make it happy */
! 	snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
! 
  	free(result);
  
! 	return(1);
  }
  #endif
  
! void
! setservent(f)
! 	int f;
  {
! 	if (servf == NULL)
! 		servf = fopen(_PATH_SERVICES, "r" );
  	else
! 		rewind(servf);
! 	_serv_stayopen |= f;
  }
  
  void
! endservent()
  {
! 	if (servf) {
! 		fclose(servf);
! 		servf = NULL;
! 	}
! 	_serv_stayopen = 0;
  }
  
! struct servent *
! getservent()
  {
! 	char *p;
! 	char *cp, **q;
  
  #ifdef YP
! 	if (serv_stepping_yp && _getservent_yp(line)) {
! 		p = (char *)&line;
! 		goto unpack;
! 	}
! tryagain:
! #endif
! 	if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
! 		return (NULL);
! again:
! 	if ((p = fgets(line, BUFSIZ, servf)) == NULL)
! 		return (NULL);
! #ifdef YP
! 	if (*p == '+' && _yp_check(NULL)) {
! 		if (___getservbyname_yp != NULL) {
! 			if (!_getservbyname_yp(line))
! 				goto tryagain;
! 		} 
! 		else if (___getservbyport_yp != 0) {
! 			if (!_getservbyport_yp(line))
! 				goto tryagain;
! 		}
! 		else if (!_getservent_yp(line))
! 			goto tryagain;
! 	}
! unpack:
  #endif
! 	if (*p == '#')
! 		goto again;
! 	cp = strpbrk(p, "#\n");
! 	if (cp == NULL)
! 		goto again;
! 	*cp = '\0';
! 	serv.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';
! 	serv.s_port = htons((u_short)atoi(p));
! 	serv.s_proto = cp;
! 	q = serv.s_aliases = serv_aliases;
! 	cp = strpbrk(cp, " \t");
! 	if (cp != NULL)
! 		*cp++ = '\0';
! 	while (cp && *cp) {
! 		if (*cp == ' ' || *cp == '\t') {
! 			cp++;
! 			continue;
! 		}
! 		if (q < &serv_aliases[MAXALIASES - 1])
! 			*q++ = cp;
! 		cp = strpbrk(cp, " \t");
! 		if (cp != NULL)
! 			*cp++ = '\0';
! 	}
! 	*q = NULL;
! 	return (&serv);
  }
--- 604,950 ----
  	 * 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),
  						&result, &resultlen))) {
  		if (rv == YPERR_MAP) {
! 			if (yp_match(st->yp_domain, "services.byname", buf,
  					strlen(buf), &result, &resultlen))
! 			return(NS_NOTFOUND);
  		} else
! 			return(NS_NOTFOUND);
  	}
  		
  	/* getservent() expects lines terminated with \n -- make it happy */
! 	snprintf(st->line, BUFSIZ, "%.*s\n", resultlen, result);
  	free(result);
! 	
! 	if (_servent_unpack(&st->serv,st->serv_aliases,st->line,&q)!=_SERVENT_UNPACK_RETURN)
! 		return (NS_UNAVAIL);
! 
! 	*(struct servent **)retval=&st->serv;	
! 	return (NS_SUCCESS);
  }
  
  static int
! _nis_setservent(void *retval, void *mdata, va_list ap)
  {
! 	struct nis_state * st;
! 	int rv;
  
! 	rv=_get_compat_nis_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 		
! 	st->serv_stepping_yp=0;
! 	st->_notfound_block=0;
! 	return (NS_UNAVAIL);
! }
  
! static int
! _nis_endservent(void *retval, void *mdata, va_list ap)
! {
! 	struct nis_state * st;
! 	int rv;
  
! 	rv=_get_compat_nis_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
  		
! 	st->yp_domain=NULL;
! 	st->serv_stepping_yp=0;
! 	st->_notfound_block=0;
! 	return (NS_UNAVAIL);
  }
  
  static int
! _nis_getservent(void *retval, void *mdata, va_list ap)
  {
! 	struct nis_state * st;
! 	
! 	char *p,**q;
! 
  	char *lastkey, *result;
  	int resultlen;
  	int rv;
  
! 	rv=_get_compat_nis_state(&st,mdata);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 
! 	if (st->_notfound_block!=0)
! 		return (NS_NOTFOUND);
! 
! 	if(!st->yp_domain) {
! 		if(yp_get_default_domain(&st->yp_domain))
! 			return (NS_UNAVAIL);
  	}
  
! 	if (!st->serv_stepping_yp) {
! 		if (st->key)
! 			free(st->key);
! 		if ((rv = yp_first(st->yp_domain, "services.byname", &st->key, &st->keylen,
  			     &result, &resultlen))) {
! 			st->serv_stepping_yp = 0;
! 			return(NS_NOTFOUND);
! 		} else
! 			st->serv_stepping_yp = 1;
  	} else {
! 		lastkey = st->key;
! 		rv = yp_next(st->yp_domain, "services.byname", st->key, st->keylen, &st->key,
! 			     &st->keylen, &result, &resultlen);
  		free(lastkey);
  		if (rv) {
! 			st->serv_stepping_yp = 0;
! 			st->_notfound_block=1;
! 			return (NS_NOTFOUND);
  		}
  	}
  
  	/* getservent() expects lines terminated with \n -- make it happy */
! 	snprintf(st->line, BUFSIZ, "%.*s\n", resultlen, result);
  	free(result);
  
! 	p=st->line;
! 	if (_servent_unpack(&st->serv,st->serv_aliases,p,&q)!=_SERVENT_UNPACK_RETURN)
! 		return (NS_UNAVAIL);
! 
! 	*(struct servent **)retval=&st->serv;
! 	return(NS_SUCCESS);
  }
+ 
  #endif
+  
+ static void
+ compat_endstate(void * p)
+ {
+ 	struct compat_state * st;
+ 	if (p == NULL)
+ 		return;
  
! 	st=(struct compat_state *)p;
! 	if (st->files_st.servf!=NULL)
! 		fclose(st->files_st.servf);	
! #ifdef YP
! 	if (st->nis_st.key!=NULL)
! 		free(st->nis_st.key);
! #endif
! 	free(p);
! }
!  
! static int
! _compat_setservent(void *retval, void *mdata, va_list ap)
  {
! 	struct compat_state * st;
! 	int rv;
! 
! 	rv=compat_getstate(&st);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 	
! 	_files_setservent(retval,&st->current_condition,ap);
! #ifdef YP	
! 	_nis_setservent(retval,&st->current_condition,ap);
! 	st->current_condition=FILES_STATE;
! #endif
! 	return (NS_UNAVAIL);
! }
! 
! static	int
! _compat_endservent(void *retval, void *mdata, va_list ap)
! {
! 	struct compat_state * st;
! 	int rv;
! 
! 	rv=compat_getstate(&st);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 	
! 	_files_endservent(retval,&st->current_condition,ap);
! #ifdef YP
! 	_nis_endservent(retval,&st->current_condition,ap);
! 	st->current_condition=FILES_STATE;
! #endif
! 	return (NS_UNAVAIL);
! }
! 
! static int
!  _compat_getservent(void *retval, void *mdata, va_list ap)
! {
! 	struct compat_state * st;
! 	int rv;
! 
! 	int continue_flag=0;
! 
! 	rv=compat_getstate(&st);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 
! #ifdef YP
! 	do {
! 		switch (st->current_condition) {
! 			case FILES_STATE:
! 				rv=_files_getservent(retval,&st->current_condition,ap);
! 				if (st->current_condition==NIS_STATE)
! 					continue_flag=1;
! 				else
! 					return rv;
! 			break;
! 			
! 			case NIS_STATE:
! 				rv=_nis_getservent(retval,&st->current_condition,ap);
! 				if (rv!=NS_SUCCESS) {
! 					st->current_condition=FILES_STATE;
! 					continue_flag=1;
! 				} else 
! 					return NS_SUCCESS;
! 			break;
! 			
! 			default:
! 				/* NOT REACHED */
! 			break;
! 		}
! 	} while (continue_flag==1);
! #else
! 	return _files_getservent(retval,&st->current_condition,ap);
! #endif
! 
! 	/* NOT REACHED */
! 	return (NS_UNAVAIL);
! }
! 
! static int
! _compat_getservbyname(void *retval, void *mdata, va_list ap)
! {
! 	struct compat_state * st;
! 	int rv;
! 
! 	enum compat_condition current_condition;
! 
! 	rv=compat_getstate(&st);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
! 
!     	current_condition=FILES_STATE;
! 	rv=_files_getservbyname(retval,&current_condition,ap);
! 	
! 	return rv;
! }
! 
! static int
! _compat_getservbyport(void *retval, void *mdata, va_list ap)
! {
! 	struct compat_state * st;
! 	int rv;
! 
! 	enum compat_condition current_condition;
! 
! 	rv=compat_getstate(&st);
! 	if (rv != 0)
! 		return (NS_UNAVAIL);
!     
! 	current_condition=FILES_STATE;
! 	rv=_files_getservbyport(retval,&current_condition,ap);
! 	
! 	return rv;	
! }
! 
! struct servent *
! getservent(void)
! {
! 	struct servent * sv = 0;
! 	int rval;
! 	
! 	static const ns_dtab dtab[] = {
! 		{ NSSRC_FILES, _files_getservent, NULL },
! #ifdef YP		
! 		{ NSSRC_NIS, _nis_getservent, NULL },
! #endif
! 		{ NSSRC_COMPAT, _compat_getservent, NULL },
! 		{ NULL, NULL, NULL }
! 	};
! 		
! 	rval = _nsdispatch( (void *) &sv, dtab, NSDB_SERVICES, "getservent", defaultsrc, 0);
! 	
! 	if (rval != NS_SUCCESS)
! 		return NULL;
  	else
! 		return sv;
  }
  
  void
! setservent(int stayopen)
  {
!         static const ns_dtab dtab[] = {
!                 { NSSRC_FILES, _files_setservent, NULL },
! #ifdef YP                
!                 { NSSRC_NIS, _nis_setservent, NULL },
! #endif
!                 { NSSRC_COMPAT, _compat_setservent, NULL},
!                 { NULL, NULL, NULL }
!         };
! 		
!         (void)_nsdispatch(NULL, dtab, NSDB_SERVICES, "setservent", defaultsrc, 0);
  }
  
! void
! endservent(void)
  {
!         static const ns_dtab dtab[] = {
!                 { NSSRC_FILES, _files_endservent, NULL },
! #ifdef YP                
!                 { NSSRC_NIS, _nis_endservent, NULL },
! #endif
!                 { NSSRC_COMPAT, _compat_endservent, NULL},
!                 { NULL, NULL, NULL }
!         };
! 		
!         (void)_nsdispatch(NULL, dtab, NSDB_SERVICES, "endservent", defaultsrc, 0);
! }
  
+ struct servent *
+ getservbyname(const char * name, const char * proto)
+ {
+ 	struct servent * sv = 0;
+ 	int rval;
+ 	
+ 	static const ns_dtab dtab[] = {
+ 			{ NSSRC_FILES,_files_getservbyname,NULL },
  #ifdef YP
! 			{ NSSRC_NIS,_nis_getservbyname,NULL },
  #endif
! 			{ NSSRC_COMPAT, _compat_getservbyname, NULL },
! 			{ 0 }
! 	};
! 	
! 	rval = _nsdispatch( (void *) &sv, dtab, NSDB_SERVICES, "getservbyname", defaultsrc, name, proto);
! 	
! 	if (rval != NS_SUCCESS)
! 		return NULL;
! 	else
! 		return sv;
  }
+ 
+ struct servent *
+ getservbyport(int port, const char * proto)
+ {
+ 	struct servent * sv = 0;
+ 	int rval;
+ 	
+ 	static const ns_dtab dtab[] = {
+ 			{ NSSRC_FILES,_files_getservbyport,NULL },
+ #ifdef YP			
+ 			{ NSSRC_NIS, _nis_getservbyport,NULL },
+ #endif
+ 			{ NSSRC_COMPAT, _compat_getservbyport, NULL } ,
+ 			{ 0 }
+ 	};
+ 	
+ 	rval = _nsdispatch( (void *) &sv, dtab, NSDB_SERVICES, "getservbyport", defaultsrc, port, proto);
+ 	
+ 	if (rval != NS_SUCCESS)
+ 		return NULL;
+ 	else
+ 		return sv;
+ 	} 
*** ./initial/getservbyname.c	Wed Jul 14 18:06:32 2004
--- getservbyname.c	Wed Jul 14 18:05:10 2004
***************
*** 38,81 ****
  __FBSDID("$FreeBSD: src/lib/libc/net/getservbyname.c,v 1.4 2002/03/21 18:49:23 obrien Exp $");
  
  #include <netdb.h>
  #include <string.h>
  
- extern int _serv_stayopen;
- 
- struct servent *
- getservbyname(name, proto)
- 	const char *name, *proto;
- {
- 	struct servent *p;
- 	char **cp;
- 
- #ifdef YP
- 	extern char *___getservbyname_yp;
- 	extern char *___getservbyproto_yp;
- 
- 	___getservbyname_yp = (char *)name;
- 	___getservbyproto_yp = (char *)proto;
- #endif
- 
- 	setservent(_serv_stayopen);
- 	while ( (p = getservent()) ) {
- 		if (strcmp(name, p->s_name) == 0)
- 			goto gotname;
- 		for (cp = p->s_aliases; *cp; cp++)
- 			if (strcmp(name, *cp) == 0)
- 				goto gotname;
- 		continue;
- gotname:
- 		if (proto == 0 || strcmp(p->s_proto, proto) == 0)
- 			break;
- 	}
- 	if (!_serv_stayopen)
- 		endservent();
- 
- #ifdef YP
- 	___getservbyname_yp = NULL;
- 	___getservbyproto_yp = NULL;
- #endif
- 
- 	return (p);
- }
--- 38,42 ----
*** ./initial/getservbyport.c	Wed Jul 14 18:06:32 2004
--- getservbyport.c	Wed Jul 14 18:05:17 2004
***************
*** 38,76 ****
  __FBSDID("$FreeBSD: src/lib/libc/net/getservbyport.c,v 1.4 2002/03/21 18:49:23 obrien Exp $");
  
  #include <netdb.h>
  #include <string.h>
  
- extern int _serv_stayopen;
- 
- struct servent *
- getservbyport(port, proto)
- 	int port;
- 	const char *proto;
- {
- 	struct servent *p;
- 
- #ifdef YP
- 	extern int ___getservbyport_yp;
- 	extern char *___getservbyproto_yp;
- 
- 	___getservbyport_yp = port;
- 	___getservbyproto_yp = (char *)proto;
- #endif
- 
- 	setservent(_serv_stayopen);
- 	while ( (p = getservent()) ) {
- 		if (p->s_port != port)
- 			continue;
- 		if (proto == 0 || strcmp(p->s_proto, proto) == 0)
- 			break;
- 	}
- 	if (!_serv_stayopen)
- 		endservent();
- 
- #ifdef YP
- 	___getservbyport_yp = 0;
- 	___getservbyproto_yp = NULL;
- #endif
- 
- 	return (p);
- }
--- 38,42 ----

--=-NBIlVcBobXF4E8EHBWGR--



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