From owner-freebsd-bugs@FreeBSD.ORG Tue Jul 27 07:40:37 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2358A16A4CE for ; Tue, 27 Jul 2004 07:40:37 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id EAFDE43D3F for ; Tue, 27 Jul 2004 07:40:36 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i6R7eahI007605 for ; Tue, 27 Jul 2004 07:40:36 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i6R7eagC007604; Tue, 27 Jul 2004 07:40:36 GMT (envelope-from gnats) Resent-Date: Tue, 27 Jul 2004 07:40:36 GMT Resent-Message-Id: <200407270740.i6R7eagC007604@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Michael Bushkov Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E389516A4CE for ; Tue, 27 Jul 2004 07:33:45 +0000 (GMT) Received: from stinger.cc.rsu.ru (stinger.cc.rsu.ru [195.208.252.82]) by mx1.FreeBSD.org (Postfix) with ESMTP id CF8E643D31 for ; Tue, 27 Jul 2004 07:33:42 +0000 (GMT) (envelope-from bushman@stinger.cc.rsu.ru) Received: from stinger.cc.rsu.ru (localhost [127.0.0.1]) by stinger.cc.rsu.ru (8.12.11/8.12.10) with ESMTP id i6R7YcTD073549 for ; Tue, 27 Jul 2004 11:34:38 +0400 (MSD) (envelope-from bushman@stinger.cc.rsu.ru) Received: (from bushman@localhost) by stinger.cc.rsu.ru (8.12.11/8.12.10/Submit) id i6R7YbTn073548; Tue, 27 Jul 2004 11:34:37 +0400 (MSD) (envelope-from bushman) Message-Id: <200407270734.i6R7YbTn073548@stinger.cc.rsu.ru> Date: Tue, 27 Jul 2004 11:34:37 +0400 (MSD) From: Michael Bushkov To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: misc/69650: make getserv* functions work with nsdispatch X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Michael Bushkov List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jul 2004 07:40:37 -0000 >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@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 __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, 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 #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 ---- --- getserv.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted: