misc/69650: make getserv* functions work with nsdispatch
Michael Bushkov
bushman at stinger.cc.rsu.ru
Tue Jul 27 00:40:37 PDT 2004
>Number: 69650
>Category: misc
>Synopsis: make getserv* functions work with nsdispatch
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: update
>Submitter-Id: current-users
>Arrival-Date: Tue Jul 27 07:40:36 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Michael Bushkov
>Release: FreeBSD 5.2-CURRENT i386
>Organization:
Rostov State Universiry
>Environment:
System: FreeBSD stinger.cc.rsu.ru 5.2-CURRENT FreeBSD 5.2-CURRENT #1: Fri Jun 25 12:56:22 MSD 2004 bushman at stinger.cc.rsu.ru:/usr/obj/usr/src/sys/STINGER i386
>Description:
Patch adds nsdispatch functionality to getserv* functions.
It implements nis, files and compat sources.
It shold be applied to files in src/lib/libc/net/
>How-To-Repeat:
>Fix:
--- getserv.patch begins here ---
*** ./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,¤t_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,¤t_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 ----
--- getserv.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list