From owner-freebsd-hackers@FreeBSD.ORG Tue Oct 26 10:14:48 2004 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F071E16A4CE; Tue, 26 Oct 2004 10:14:47 +0000 (GMT) Received: from asterix.rsu.ru (relay.r61.net [195.208.245.250]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1F6B343D41; Tue, 26 Oct 2004 10:14:46 +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 i9QAEb56015953; Tue, 26 Oct 2004 14:14:37 +0400 (MSD) (envelope-from bushman@rsu.ru) From: Michael Bushkov To: hackers@freebsd.org Content-Type: multipart/mixed; boundary="=-NBIlVcBobXF4E8EHBWGR" Organization: Rostov State University Message-Id: <1098785868.61417.39.camel@localhost> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.6 Date: Tue, 26 Oct 2004 14:17:49 +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: "Jacques A. Vidrine" cc: "Christian S.J. Peron" Subject: nsdispatch services patch + lookupd X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: bushman@rsu.ru List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Oct 2004 10:14:48 -0000 --=-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 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 __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 ---- --=-NBIlVcBobXF4E8EHBWGR--