From owner-p4-projects@FreeBSD.ORG Tue Jul 5 08:30:37 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 30F7316A420; Tue, 5 Jul 2005 08:30:37 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CA00116A41C for ; Tue, 5 Jul 2005 08:30:36 +0000 (GMT) (envelope-from soc-bushman@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9CB1243D4C for ; Tue, 5 Jul 2005 08:30:36 +0000 (GMT) (envelope-from soc-bushman@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j658Uail061013 for ; Tue, 5 Jul 2005 08:30:36 GMT (envelope-from soc-bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j658UaMM061010 for perforce@freebsd.org; Tue, 5 Jul 2005 08:30:36 GMT (envelope-from soc-bushman@freebsd.org) Date: Tue, 5 Jul 2005 08:30:36 GMT Message-Id: <200507050830.j658UaMM061010@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-bushman@freebsd.org using -f From: soc-bushman To: Perforce Change Reviews Cc: Subject: PERFORCE change 79589 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jul 2005 08:30:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=79589 Change 79589 by soc-bushman@soc-bushman_stinger on 2005/07/05 08:30:06 services patch completed Affected files ... .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyname.c#4 edit .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyport.c#4 edit .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservent.c#6 edit .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/netdb_private.h#2 edit Differences ... ==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyname.c#4 (text+ko) ==== @@ -37,7 +37,7 @@ #include __FBSDID("$FreeBSD: src/lib/libc/net/getservbyname.c,v 1.7 2005/04/18 18:34:58 ume Exp $"); -#include +/*#include #include #include "netdb_private.h" @@ -87,3 +87,4 @@ return (NULL); return (&sd->serv); } +*/ ==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservbyport.c#4 (text+ko) ==== @@ -37,6 +37,7 @@ #include __FBSDID("$FreeBSD: src/lib/libc/net/getservbyport.c,v 1.7 2005/04/18 18:34:58 ume Exp $"); +/* #include #include #include "netdb_private.h" @@ -81,3 +82,4 @@ return (NULL); return (&sd->serv); } +*/ ==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservent.c#6 (text+ko) ==== @@ -37,9 +37,12 @@ #include __FBSDID("$FreeBSD: src/lib/libc/net/getservent.c,v 1.19 2005/04/28 15:32:55 ume Exp $"); +#include #include #include #include +#include +#include #include #include #include @@ -49,105 +52,113 @@ #include #include #endif +#include #include "namespace.h" #include "reentrant.h" #include "un-namespace.h" #include "netdb_private.h" - -/* nsswitch part - begin */ #include "libc_private.h" #include "nss_tls.h" -#include -#include -/* nsswitch part - end */ -/* nsswitch part - begin */ +enum constants +{ + SETSERVENT = 1, + ENDSERVENT = 2, + SERVENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */ + SERVENT_STORAGE_MAX = 1 << 20, /* 1 MByte */ +}; -// I guess, we'd better send this structure as the sequence of function arguments -/*static struct servent_data +struct servent_mdata { -// char *aliases[_MAXALIASES]; -// char line[_MAXLINELEN + 1]; - char **aliases; - size_t aliases_size; - - char * buffer; - size_t buffer_size; -};*/ + enum nss_lookup_type how; + int compat_mode; +}; static const ns_src defaultsrc[] = { { NSSRC_COMPAT, NS_SUCCESS }, { NULL, 0 } }; -static int servent_unpack(char *, struct servent *, char **, size_t); -static void servent_init(struct servent *); +static int servent_unpack(char *, struct servent *, char **, size_t, int *); +/* files backend declarations */ struct files_state { - FILE *fp; - int stayopen; + FILE *fp; + int stayopen; + + int compat_mode_active; }; -static void files_endstate(void *); +static void files_endstate(void *); NSS_TLS_HANDLING(files); -static int files_servent(void *, void *, va_list); -static int files_setservent(void *, void *, va_list); -static int files_endservent(void *, void *, va_list); -static void files_setent(int, struct files_state *); -static void files_endent(struct files_state *); +static int files_servent(void *, void *, va_list); +static int files_setservent(void *, void *, va_list); -#ifdef YP -static int nis_getservbyname_r(void *, void *, va_list); -static int nis_getservbyport_t(void *, void *, va_list); -static int nis_getservent_r(void *, void *, va_list); -static int nis_setservent(void *, void *, va_list); -static int nis_endservent(void *, void *, va_list); +/* nis backend declarations */ +static int nis_servent(void *, void *, va_list); +static int nis_setservent(void *, void *, va_list); struct nis_state { - /* this specification is not finished */ - int yp_stepping; -// char *yp_name; -// char *yp_proto; -// int yp_port; - char *yp_domain; - char *yp_key; - int yp_keylen; + int yp_stepping; + char yp_domain[MAXHOSTNAMELEN]; + char *yp_key; + int yp_keylen; }; -static void nis_endstate(void *); +static void nis_endstate(void *); NSS_TLS_HANDLING(nis); -#endif +static int nis_servent(void *, void *, va_list); +static int nis_setservent(void *, void *, va_list); + +/* compat backend declarations */ +static int compat_setservent(void *, void *, va_list); + +/* get** wrappers for get**_r functions declarations */ +struct servent_state { + struct servent serv; + char *buffer; + size_t bufsize; +}; +static void servent_endstate(void *); +NSS_TLS_HANDLING(servent); -struct compat_state -{ - FILE *fp; - int stayopen; -/* char *name; - enum _compat { - COMPAT_MODE_OFF = 0, - COMPAT_MODE_ALL, - COMPAT_MODE_NAME - } compat;*/ +struct key { + const char *proto; + union { + const char *name; + int port; + }; }; -//static void compat_endstate(void *); -//NSS_TLS_HANDLING(compat); - -/* nsswitch part - end */ +static int wrap_getservbyname_r(struct key key, struct servent *serv, char *buffer, + size_t bufsize, struct servent **res); +static int wrap_getservbyport_r(struct key key, struct servent *serv, char *buffer, + size_t bufsize, struct servent **res); +static int wrap_getservent_r(struct key key, struct servent *serv, char *buffer, + size_t bufsize, struct servent **res); +static struct servent *getserv(int (*fn)(struct key, struct servent *, char *, + size_t, struct servent **), struct key key); + + static int -servent_unpack(char *p, struct servent * serv, char ** aliases, size_t aliases_size) +servent_unpack(char *p, struct servent * serv, char ** aliases, size_t aliases_size, + int * errnop) { - char *cp, **q, *endp; - long l; + char *cp, **q, *endp; + long l; if (*p == '#') return -1; + + memset(serv, 0, sizeof(struct servent)); + cp = strpbrk(p, "#\n"); if (cp != NULL) *cp = '\0'; serv->s_name = p; + p = strpbrk(p, " \t"); if (p == NULL) return -1; @@ -157,12 +168,14 @@ cp = strpbrk(p, ",/"); if (cp == NULL) return -1; + *cp++ = '\0'; l = strtol(p, &endp, 10); if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX) return -1; serv->s_port = htons((in_port_t)l); serv->s_proto = cp; + q = serv->s_aliases = aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) @@ -172,38 +185,24 @@ cp++; continue; } - if (q < &aliases[_MAXALIASES - 1]) { + if (q < &aliases[aliases_size - 1]) { *q++ = cp; - *q++ = '\0'; // my hack - should work - but will left the buffer in mess after the ending 0 + } else { + *q = NULL; + *errnop = ERANGE; + return -1; } cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; } *q = NULL; - + return 0; } -static void -servent_init(struct servent * serv) -{ -} - -#define SERVENT_BUFFER_UNPACK(buffer, buffer_size, line, line_size, aliases) \ - aliases=(char **)(_ALIGN((char **)buffer)); \ - line=(char *)aliases+sizeof(char *)*_MAXALIASES; \ - if (line>buffer+buffer_size) \ - return (NS_UNAVAIL); \ - line_size=buffer+buffer_size-line; \ - if (line_size<_MAXLINELEN+1) \ - return (NS_TRYAGAIN); - /* TODO - must check the alignment here */ - -#define SERVENT_BUFFER_SIZE sizeof(char*)*_MAXALIASES+_ALIGNBYTES+_MAXLINELEN - -/* files backend implementation - begin */ -static void +/* files backend implementation */ +static void files_endstate(void *p) { FILE * f; @@ -218,260 +217,223 @@ free(p); } -//struct servent * serv, char * buffer, size_t buffer_size, int * errnop, struct files_state * st -static int -files_servent(void * retval, void *mdata, va_list ap) +/* + * compat structures. compat and files sources functionalities are almost equa, so + * they all are managed by files_servent function + */ +static int +files_servent(void *retval, void *mdata, va_list ap) { - struct files_state * st; - int rv; - int stayopen; + static const ns_src compat_src[] = { +#ifdef YP + { NSSRC_NIS, NS_SUCCESS }, +#endif + { NULL, 0 } + }; + ns_dtab compat_dtab[] = { +#ifdef YP + { NSSRC_NIS, nis_servent, (void *)((struct servent_mdata *)mdata)->how }, +#endif + { NULL, NULL, NULL } + }; - enum nss_lookup_type how; - char * name; - char * proto; - int port; - - struct servent * serv; - char * buffer; - size_t buffer_size; - int * errnop; - - char **aliases; - char * line; - size_t line_size; + struct files_state *st; + int rv; + int stayopen; - char *p; - char **cp;//, **q, *endp; -// long l; - - rv = files_getstate(&st); - if (rv != 0) - return (NS_UNAVAIL); + struct servent_mdata *serv_mdata; + char *name; + char *proto; + int port; - SERVENT_BUFFER_UNPACK(buffer, buffer_size,line,line_size,aliases) -/* aliases=_ALIGN((char **)buffer); - line=aliases+sizeof(char *)*_MAXALIASES; - if (line>=buffer+buffer_size) - return (NS_TRYAGAIN); - line_size=buffer+buffer_size-line; + struct servent *serv; + char *buffer; + size_t bufsize; + int *errnop; - if (line_size<_MAXLINELEN+1) - return (NS_TRYAGAIN);*/ - + char **aliases; + int aliases_size; + size_t linesize; + char *line; + char **cp; + name = NULL; proto = NULL; - how = (enum nss_lookup_type)mdata; - switch (how) - { - case nss_lt_name: - name = va_arg(ap, char *); - proto = va_arg(ap, char *); - stayopen=0; - break; - case nss_lt_id: - port = va_arg(ap, int); - proto = va_arg(ap, char *); - stayopen=0; - break; - case nss_lt_all: - stayopen=1; - break; - default: - return NS_NOTFOUND; + serv_mdata = (struct servent_mdata *)mdata; + switch (serv_mdata->how) { + case nss_lt_name: + name = va_arg(ap, char *); + proto = va_arg(ap, char *); + break; + case nss_lt_id: + port = va_arg(ap, int); + proto = va_arg(ap, char *); + break; + case nss_lt_all: + break; + default: + return NS_NOTFOUND; }; serv = va_arg(ap, struct servent *); buffer = va_arg(ap, char *); - buffer_size = va_arg(ap, size_t); + bufsize = va_arg(ap, size_t); errnop = va_arg(ap,int *); - if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) + *errnop = files_getstate(&st); + if (*errnop != 0) + return (NS_UNAVAIL); + + if (st->fp == NULL) + st->compat_mode_active = 0; + + if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) { + *errnop = errno; return (NS_UNAVAIL); + } - if (stayopen==1) - files_setent(1,st); + if (serv_mdata->how == nss_lt_all) + stayopen = 1; + else { + rewind(st->fp); + stayopen = st->stayopen; + } - rv=NS_NOTFOUND; - do { - memset(serv,0,sizeof(*serv)); - *aliases='\0'; + rv = NS_NOTFOUND; + do { + if (!st->compat_mode_active) { + if ((line = fgetln(st->fp, &linesize)) == NULL) { + *errnop = errno; + rv = NS_RETURN; + break; + } + + if (*line=='+') + st->compat_mode_active = 1; + else { + if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { + *errnop = ERANGE; + rv = NS_RETURN; + break; + } + aliases = (char **)_ALIGN(&buffer[linesize+1]); + aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *); + if (aliases_size < 1) { + *errnop = ERANGE; + rv = NS_RETURN; + break; + } - if ((p = fgets(line,line_size, st->fp)) == NULL) { - rv=(NS_RETURN); - break; + memcpy(buffer, line, linesize); + buffer[linesize] = '\0'; + } } + + if (st->compat_mode_active != 0) { + switch (serv_mdata->how) { + case nss_lt_name: + rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyname_r", + compat_src, name, proto, serv, buffer, bufsize, errnop); + break; + case nss_lt_id: + rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyport_r", + compat_src, port, proto, serv, buffer, bufsize, errnop); + break; + case nss_lt_all: + rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES, "getservent_r", + compat_src, serv, buffer, bufsize, errnop); + break; + } + + if ( ( !(rv & NS_TERMINATE) ) || (serv_mdata->how != nss_lt_all)) + st->compat_mode_active = 0; - if (servent_unpack(p,serv,aliases,_MAXALIASES) == -1) continue; -/* if (*p == '#') - continue; - cp = strpbrk(p, "#\n"); - if (cp != NULL) - *cp = '\0'; - serv->s_name = p; - p = strpbrk(p, " \t"); - if (p == NULL) - continue; - *p++ = '\0'; - while (*p == ' ' || *p == '\t') - p++; - cp = strpbrk(p, ",/"); - if (cp == NULL) - continue; - *cp++ = '\0'; - l = strtol(p, &endp, 10); - if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX) - continue; - serv->s_port = htons((in_port_t)l); - serv->s_proto = cp; - q = serv->s_aliases = aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; + } + + rv = servent_unpack(line, serv, aliases, aliases_size, errnop); + if (rv !=0 ) { + if (*errnop == 0) { + rv = NS_NOTFOUND; continue; } - if (q < &st->aliases[_MAXALIASES - 1]) { - *q++ = cp; - *q++ = '\0'; // my hack - should work - but will left the buffer in mess after the ending 0 + else { + rv = NS_RETURN; + break; } - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - } - *q = NULL; */ - - switch (how) - { - case nss_lt_name: - if (strcmp(name, serv->s_name) == 0) + } + + switch (serv_mdata->how) { + case nss_lt_name: + if (strcmp(name, serv->s_name) == 0) + goto gotname; + for (cp = serv->s_aliases; *cp; cp++) + if (strcmp(name, *cp) == 0) goto gotname; - for (cp = serv->s_aliases; *cp; cp++) - if (strcmp(name, *cp) == 0) - goto gotname; - + + continue; + gotname: + if (proto == 0 || strcmp(serv->s_proto, proto) == 0) + rv = NS_SUCCESS; + break; + case nss_lt_id: + if (port != serv->s_port) continue; - gotname: - if (proto == 0 || strcmp(serv->s_proto, proto) == 0) - rv=NS_SUCCESS; - break; - case nss_lt_id: - if (port != serv->s_port) - continue; - if (proto == 0 || strcmp(serv->s_proto, proto) == 0) - rv=NS_SUCCESS; - break; - case nss_lt_all: - rv = (NS_SUCCESS); - break; - }; + if (proto == 0 || strcmp(serv->s_proto, proto) == 0) + rv = NS_SUCCESS; + break; + case nss_lt_all: + rv = NS_SUCCESS; + break; + } } while (!(rv & NS_TERMINATE)); - if (stayopen==1) - files_endent(st); - - if (rv==NS_SUCCESS) + if (!stayopen && st->fp!=NULL) { + fclose(st->fp); + st->fp = NULL; + } + + if ((rv ==NS_SUCCESS) && (retval != NULL)) *(struct servent **)retval=serv; - return rv; + return (rv); } -static void files_setent(int f, struct files_state * st) +static int +files_setservent(void *retval, void *mdata, va_list ap) { -/* struct files_state * st; - int rv; - - rv = files_getstate(&st); - if (rv != 0) - return (NS_UNAVAIL); - */ - if (st->fp == NULL) - st->fp = fopen(_PATH_SERVICES, "r"); - else - rewind(st->fp); - st->stayopen |= f; - - //return (NS_SUCCESS); -} + struct files_state *st; + int rv; + int f; -static void files_endent(struct files_state * st) -{ -/* struct files_state *st; - int rv; - - rv = files_getstate(&st); - if (rv != 0) - return (NS_UNAVAIL); - */ - st->stayopen = 0; -// return (NS_SUCCESS); -} - -/*static int -files_getservent_r(void * retval, void * mdata, va_list ap) -{ - struct files_state * st; - struct servent * serv; - char * buffer; - size_t buffer_size; - int * errnop; - int rv; - rv = files_getstate(&st); if (rv != 0) return (NS_UNAVAIL); - serv = va_arg(ap, struct servent *); - buffer = va_arg(ap, char *); - buffer_size = va_arg(ap, size_t); - errnop = va_arg(ap,int *); - - rv=files_servent(se,buffer,buffer_size,errnop); - if (rv==NS_SUCCESS) - *(struct servent **)retval=se; - - return rv; -} */ - - -static int -files_setservent(void * retval, void * mdata, va_list ap) -{ - struct files_state *st; - int rv; - int f; - - f=va_arg(ap,int); - - rv = files_getstate(&st); - if (rv != 0) - return (NS_UNAVAIL); + switch ((enum constants)mdata) { + case SETSERVENT: + f = va_arg(ap,int); + if (st->fp == NULL) + st->fp = fopen(_PATH_SERVICES, "r"); + else + rewind(st->fp); + st->stayopen |= f; + break; + case ENDSERVENT: + st->stayopen = 0; + break; + default: + break; + }; + st->compat_mode_active = 0; - files_setent(f,st); - return (NS_SUCCESS); + return (NS_UNAVAIL); } -static int -files_endservent(void * retval, void * mdata, va_list ap) -{ - struct files_state *st; - int rv; - - rv = files_getstate(&st); - if (rv != 0) - return (NS_UNAVAIL); - - files_endent(st); - return (NS_SUCCESS); -} - -/* files backend implementation - end */ - -/* nis backend implementation - begin */ +/* nis backend implementation */ +#ifdef YP static void nis_endstate(void *p) { @@ -482,331 +444,249 @@ free(p); } -static int -nis_getservbyname_r(void * result, void * mdata, va_list ap) +static int +nis_servent(void *retval, void *mdata, va_list ap) { - struct nis_state * ns; - int rv; + char *resultbuf, *lastkey; + int resultbuflen; + char buf[YPMAXRECORD + 2]; + + struct nis_state *st; + int rv; - struct servent * serv; - char **aliases; - char * line; - size_t line_size; + enum nss_lookup_type how; + char *name; + char *proto; + int port; - char * name; - char * proto; - char * buffer; - size_t bufsize; - int * errnop; + struct servent *serv; + char *buffer; + size_t bufsize; + int *errnop; - char *resultbuf; - int resultbuflen; - char buf[YPMAXRECORD + 2]; + char **aliases; + int aliases_size; - rv = nis_getstate(&ns); - if (rv != 0) - return (NS_UNAVAIL); + name = NULL; + proto = NULL; + how = (enum nss_lookup_type)mdata; + switch (how) { + case nss_lt_name: + name = va_arg(ap, char *); + proto = va_arg(ap, char *); + break; + case nss_lt_id: + port = va_arg(ap, int); + proto = va_arg(ap, char *); + break; + case nss_lt_all: + break; + default: + return NS_NOTFOUND; + }; - name = va_arg(ap, char *); - proto = va_arg(ap, char *); serv = va_arg(ap, struct servent *); - buffer = va_arg(ap, char *); + buffer = va_arg(ap, char *); bufsize = va_arg(ap, size_t); errnop = va_arg(ap, int *); - SERVENT_BUFFER_UNPACK(buffer,bufsize,line,line_size,aliases) + *errnop = nis_getstate(&st); + if (*errnop != 0) + return (NS_UNAVAIL); - /* TODO: do we need this ? */ -/* if (bufsize < _MAXLINELEN+1) - return (NS_TRYAGAIN);*/ - - if(!ns->yp_domain) { - if(yp_get_default_domain(&ns->yp_domain)) + if (st->yp_domain[0] == '\0') { + if (getdomainname(st->yp_domain, sizeof st->yp_domain)) { + *errnop=errno; return (NS_UNAVAIL); + } } - //snprintf(buf, sizeof(buf), "%s/%s", ns->yp_name, ns->yp_proto); - snprintf(buf, sizeof(buf), "%s/%s", name, proto); + do { + switch (how) + { + case nss_lt_name: + snprintf(buf, sizeof(buf), "%s/%s", name, proto); + if (yp_match(st->yp_domain, "services.byname", buf, strlen(buf), + &resultbuf, &resultbuflen)) { + rv = NS_NOTFOUND; + goto fin; + } + break; + case nss_lt_id: + snprintf(buf, sizeof(buf), "%d/%s", ntohs(port), proto); + + /* + * We have to be a little flexible here. Ideally you're supposed + * to have both a services.byname and a services.byport map, but + * some systems have only services.byname. FreeBSD cheats a little + * 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), + &resultbuf, &resultbuflen))) { + if (rv == YPERR_MAP) { + if (yp_match(st->yp_domain, "services.byname", buf,strlen(buf), &resultbuf, &resultbuflen)) { + rv = NS_NOTFOUND; + goto fin; + } + } else { + rv = NS_NOTFOUND; + goto fin; + } + } + + break; + case nss_lt_all: + if (!st->yp_stepping) { + free(st->yp_key); + rv = yp_first(st->yp_domain, "services.byname", &st->yp_key, + &st->yp_keylen, &resultbuf, &resultbuflen); + if (rv) { + st->yp_stepping = 0; + rv = NS_NOTFOUND; + goto fin; + } + st->yp_stepping = 1; + } else { + lastkey = st->yp_key; + rv = yp_next(st->yp_domain, "services.byname", st->yp_key, + st->yp_keylen, &st->yp_key, &st->yp_keylen, &resultbuf, + &resultbuflen); + free(lastkey); + if (rv) { + st->yp_stepping = 0; + rv = NS_NOTFOUND; + goto fin; + } + } + break; + }; -// ns->yp_name = 0; -// ns->yp_proto = NULL; - - if (yp_match(ns->yp_domain, "services.byname", buf, strlen(buf), - &resultbuf, &resultbuflen)) { - return (NS_NOTFOUND); - } + /* we need a room for additional \n symbol */ + if (bufsize <= resultbuflen +1 + _ALIGNBYTES + sizeof(char *)) { + *errnop = ERANGE; + rv = NS_RETURN; + break; + } - /* getservent() expects lines terminated with \n -- make it happy */ - //snprintf(sed->line, sizeof sed->line, "%.*s\n", resultbuflen, resultbuf); - snprintf(buffer, bufsize, "%.*s\n", resultbuflen, resultbuf); - rv = (servent_unpack(buffer,serv,aliases,_MAXALIASES)==-1) ? (NS_NOTFOUND) : (NS_SUCCESS); - - free(resultbuf); - return rv; -} - -static int -nis_getservbyport_t(void * result, void * mdata, va_list ap) -{ - struct nis_state * ns; - - struct servent * serv; - char ** aliases; - char * line; - size_t line_size; - - int port; - char * proto; - char * buffer; - size_t bufsize; - int * errnop; - - char *resultbuf; - int resultbuflen; - char buf[YPMAXRECORD + 2]; - int rv; - - rv = nis_getstate(&ns); - if (rv != 0) - return (NS_UNAVAIL); - - port = va_arg(ap, int); - proto = va_arg(ap, char *); - serv = va_arg(ap, struct servent *); - buffer = va_arg(ap, char *); - bufsize = va_arg(ap, size_t); - errnop = va_arg(ap, int *); - - SERVENT_BUFFER_UNPACK(buffer,bufsize,line,line_size,aliases); - - /* TODO - do we need this? */ -// if (bufsize<_MAXLINELEN+1) -// return (NS_TRYAGAIN); - -// snprintf(buf, sizeof(buf), "%d/%s", ntohs(sed->yp_port), -// sed->yp_proto); - snprintf(buf, sizeof(buf), "%d/%s", ntohs(port), - proto); - -// sed->yp_port = 0; -// sed->yp_proto = NULL; - - if (!ns->yp_domain) { - if (yp_get_default_domain(&ns->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 - * some systems have only services.byname. FreeBSD cheats a little - * 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(ns->yp_domain, "services.byport", buf, strlen(buf), - &resultbuf, &resultbuflen))) { - if (rv == YPERR_MAP) { - if (yp_match(ns->yp_domain, "services.byname", buf, - strlen(buf), &resultbuf, &resultbuflen)) - return(NS_NOTFOUND); - } else - return(NS_NOTFOUND); - } + aliases=(char **)_ALIGN(&buffer[resultbuflen+2]); + aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *); + if (aliases_size < 1) { + *errnop = ERANGE; + rv = NS_RETURN; + break; + } + + /* servent_unpack expects lines terminated with \n -- make it happy */ + memcpy(buffer, resultbuf, resultbuflen); + buffer[resultbuflen] = '\n'; + buffer[resultbuflen+1] = '\0'; - snprintf(buffer, bufsize, "%.*s\n", resultbuflen, resultbuf); - rv = (servent_unpack(buffer,serv,aliases,_MAXALIASES)==-1) ? (NS_NOTFOUND) : (NS_SUCCESS); + if (servent_unpack(buffer, serv, aliases, aliases_size, errnop) != 0) { + if (*errnop == 0) + rv = NS_NOTFOUND; + else + rv = NS_RETURN; + } >>> TRUNCATED FOR MAIL (1000 lines) <<<