From owner-cvs-src@FreeBSD.ORG Mon Aug 23 07:54:00 2004 Return-Path: Delivered-To: cvs-src@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A4BB616A4CE; Mon, 23 Aug 2004 07:54:00 +0000 (GMT) Received: from asterix.rsu.ru (mail.at.rsu.ru [195.208.245.250]) by mx1.FreeBSD.org (Postfix) with ESMTP id CF53E43D1D; Mon, 23 Aug 2004 07:53:58 +0000 (GMT) (envelope-from bushman@rsu.ru) Received: from [195.208.252.82] (stinger.cc.rsu.ru [195.208.252.82]) by asterix.rsu.ru (8.13.1/8.13.1) with ESMTP id i7N7rfak029032; Mon, 23 Aug 2004 11:53:42 +0400 (MSD) (envelope-from bushman@rsu.ru) From: Michael Bushkov To: DougB@DougBarton.net Content-Type: multipart/mixed; boundary="=-3nsEfv7dxSW/zpQIyhAD" Organization: Rostov State University Message-Id: <1093247765.10372.7.camel@localhost> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.6 Date: Mon, 23 Aug 2004 11:56:06 +0400 X-Spam-Status: No, hits=-104.8 required=5.0 tests=AWL,BAYES_00, USER_IN_WHITELIST autolearn=ham version=2.64 X-Spam-Checker-Version: SpamAssassin 2.64 (2004-01-11) on asterix.rsu.ru cc: cvs-src@freebsd.org cc: src-committers@freebsd.org cc: cvs-all@freebsd.org Subject: getserv* functions and lookupd X-BeenThere: cvs-src@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: bushman@rsu.ru List-Id: CVS commit messages for the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Aug 2004 07:54:00 -0000 --=-3nsEfv7dxSW/zpQIyhAD Content-Type: text/plain Content-Transfer-Encoding: 7bit > Finally, the solution that has most often been discussed for improving > the performance of getservbyname() and friends is a Berkeley db > implementation similar to the way login.conf is done now. I'm not sure > a > lookup daemon is justified, and I'd like to see some discussion about > this topic too. > > Thanks, > > Doug > Hello! I think the best way to solve the problems with getserv* functions is to implement them via nsdispatch. It gives us an ability to plug in any appropriate functionality later. I've attached the patch to libc, which does it. It implements nis, files and compat sources. Any other source can be plugged dynamically as nsswitch module. I'll release next lookupd version, which supports getserv* functions in the next 5-6 days. It solves a lot of problems, i think, because of caching. Thanks, Michael --=-3nsEfv7dxSW/zpQIyhAD 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 __FBSDID("$FreeBSD: src/lib/libc/net/getservent.c,v 1.12 2003/02/27 13:40:00 nectar Exp $"); + #include "namespace.h" #include #include #include #include #include *************** *** 46,91 **** #include #ifdef YP #include #include #include - 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 #ifdef YP #include #include #include #endif + #include + #include + #include + #include #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, stayopen); } ! 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); ! } + 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 #include - 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 #include - 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 ---- --=-3nsEfv7dxSW/zpQIyhAD--