PERFORCE change 79589 for review
soc-bushman
soc-bushman at FreeBSD.org
Tue Jul 5 08:30:38 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=79589
Change 79589 by soc-bushman at 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 <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/net/getservbyname.c,v 1.7 2005/04/18 18:34:58 ume Exp $");
-#include <netdb.h>
+/*#include <netdb.h>
#include <string.h>
#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 <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/net/getservbyport.c,v 1.7 2005/04/18 18:34:58 ume Exp $");
+/*
#include <netdb.h>
#include <string.h>
#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 <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/net/getservent.c,v 1.19 2005/04/28 15:32:55 ume Exp $");
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
+#include <errno.h>
+#include <nsswitch.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
@@ -49,105 +52,113 @@
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#endif
+#include <unistd.h>
#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 <nsswitch.h>
-#include <errno.h>
-/* 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) <<<
More information about the p4-projects
mailing list