summaryrefslogtreecommitdiffstats
path: root/freebsd/lib/libc/rpc/getrpcent.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/lib/libc/rpc/getrpcent.c')
-rw-r--r--freebsd/lib/libc/rpc/getrpcent.c1048
1 files changed, 1048 insertions, 0 deletions
diff --git a/freebsd/lib/libc/rpc/getrpcent.c b/freebsd/lib/libc/rpc/getrpcent.c
new file mode 100644
index 00000000..b4d51e0d
--- /dev/null
+++ b/freebsd/lib/libc/rpc/getrpcent.c
@@ -0,0 +1,1048 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+#include <rtems/bsd/sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <assert.h>
+#include <errno.h>
+#include <nsswitch.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+#include <unistd.h>
+#include "namespace.h"
+#include "reentrant.h"
+#include "un-namespace.h"
+#include "libc_private.h"
+#include "nss_tls.h"
+#ifdef NS_CACHING
+#include "nscache.h"
+#endif
+
+#define RPCDB "/etc/rpc"
+
+/* nsswitch declarations */
+enum constants
+{
+ SETRPCENT = 1,
+ ENDRPCENT = 2,
+ RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */
+ RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */
+};
+
+static const ns_src defaultsrc[] = {
+ { NSSRC_FILES, NS_SUCCESS },
+#ifdef YP
+ { NSSRC_NIS, NS_SUCCESS },
+#endif
+ { NULL, 0 }
+};
+
+/* files backend declarations */
+struct files_state {
+ FILE *fp;
+ int stayopen;
+};
+
+static int files_rpcent(void *, void *, va_list);
+static int files_setrpcent(void *, void *, va_list);
+
+static void files_endstate(void *);
+NSS_TLS_HANDLING(files);
+
+/* nis backend declarations */
+#ifdef YP
+struct nis_state {
+ char domain[MAXHOSTNAMELEN];
+ char *current;
+ int currentlen;
+ int stepping;
+ int no_name_map;
+};
+
+static int nis_rpcent(void *, void *, va_list);
+static int nis_setrpcent(void *, void *, va_list);
+
+static void nis_endstate(void *);
+NSS_TLS_HANDLING(nis);
+#endif
+
+/* get** wrappers for get**_r functions declarations */
+struct rpcent_state {
+ struct rpcent rpc;
+ char *buffer;
+ size_t bufsize;
+};
+static void rpcent_endstate(void *);
+NSS_TLS_HANDLING(rpcent);
+
+union key {
+ const char *name;
+ int number;
+};
+
+static int wrap_getrpcbyname_r(union key, struct rpcent *, char *,
+ size_t, struct rpcent **);
+static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *,
+ size_t, struct rpcent **);
+static int wrap_getrpcent_r(union key, struct rpcent *, char *,
+ size_t, struct rpcent **);
+static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *,
+ size_t, struct rpcent **), union key);
+
+#ifdef NS_CACHING
+static int rpc_id_func(char *, size_t *, va_list, void *);
+static int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
+static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
+#endif
+
+static int
+rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
+ size_t aliases_size, int *errnop)
+{
+ char *cp, **q;
+
+ assert(p != NULL);
+
+ if (*p == '#')
+ return (-1);
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ return (-1);
+ *cp = '\0';
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ return (-1);
+ *cp++ = '\0';
+ /* THIS STUFF IS INTERNET SPECIFIC */
+ rpc->r_name = p;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ rpc->r_number = atoi(cp);
+ q = rpc->r_aliases = r_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &(r_aliases[aliases_size - 1]))
+ *q++ = cp;
+ else {
+ *errnop = ERANGE;
+ return -1;
+ }
+
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return 0;
+}
+
+/* files backend implementation */
+static void
+files_endstate(void *p)
+{
+ FILE * f;
+
+ if (p == NULL)
+ return;
+
+ f = ((struct files_state *)p)->fp;
+ if (f != NULL)
+ fclose(f);
+
+ free(p);
+}
+
+static int
+files_rpcent(void *retval, void *mdata, va_list ap)
+{
+ char *name;
+ int number;
+ struct rpcent *rpc;
+ char *buffer;
+ size_t bufsize;
+ int *errnop;
+
+ char *line;
+ size_t linesize;
+ char **aliases;
+ int aliases_size;
+ char **rp;
+
+ struct files_state *st;
+ int rv;
+ int stayopen;
+ enum nss_lookup_type how;
+
+ how = (enum nss_lookup_type)mdata;
+ switch (how)
+ {
+ case nss_lt_name:
+ name = va_arg(ap, char *);
+ break;
+ case nss_lt_id:
+ number = va_arg(ap, int);
+ break;
+ case nss_lt_all:
+ break;
+ default:
+ return (NS_NOTFOUND);
+ }
+
+ rpc = va_arg(ap, struct rpcent *);
+ buffer = va_arg(ap, char *);
+ bufsize = va_arg(ap, size_t);
+ errnop = va_arg(ap, int *);
+
+ *errnop = files_getstate(&st);
+ if (*errnop != 0)
+ return (NS_UNAVAIL);
+
+ if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
+ *errnop = errno;
+ return (NS_UNAVAIL);
+ }
+
+ if (how == nss_lt_all)
+ stayopen = 1;
+ else {
+ rewind(st->fp);
+ stayopen = st->stayopen;
+ }
+
+ do {
+ if ((line = fgetln(st->fp, &linesize)) == NULL) {
+ *errnop = errno;
+ rv = NS_RETURN;
+ break;
+ }
+
+ 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;
+ }
+
+ memcpy(buffer, line, linesize);
+ buffer[linesize] = '\0';
+
+ rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
+ if (rv != 0) {
+ if (*errnop == 0) {
+ rv = NS_NOTFOUND;
+ continue;
+ }
+ else {
+ rv = NS_RETURN;
+ break;
+ }
+ }
+
+ switch (how)
+ {
+ case nss_lt_name:
+ if (strcmp(rpc->r_name, name) == 0)
+ goto done;
+ for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+ if (strcmp(*rp, name) == 0)
+ goto done;
+ }
+ rv = NS_NOTFOUND;
+ continue;
+done:
+ rv = NS_SUCCESS;
+ break;
+ case nss_lt_id:
+ rv = (rpc->r_number == number) ? NS_SUCCESS :
+ NS_NOTFOUND;
+ break;
+ case nss_lt_all:
+ rv = NS_SUCCESS;
+ break;
+ }
+
+ } while (!(rv & NS_TERMINATE));
+
+ if (!stayopen && st->fp!=NULL) {
+ fclose(st->fp);
+ st->fp = NULL;
+ }
+
+ if ((rv == NS_SUCCESS) && (retval != NULL))
+ *((struct rpcent **)retval) = rpc;
+
+ return (rv);
+}
+
+static int
+files_setrpcent(void *retval, void *mdata, va_list ap)
+{
+ struct files_state *st;
+ int rv;
+ int f;
+
+ rv = files_getstate(&st);
+ if (rv != 0)
+ return (NS_UNAVAIL);
+
+ switch ((enum constants)mdata)
+ {
+ case SETRPCENT:
+ f = va_arg(ap,int);
+ if (st->fp == NULL)
+ st->fp = fopen(RPCDB, "r");
+ else
+ rewind(st->fp);
+ st->stayopen |= f;
+ break;
+ case ENDRPCENT:
+ if (st->fp != NULL) {
+ fclose(st->fp);
+ st->fp = NULL;
+ }
+ st->stayopen = 0;
+ break;
+ default:
+ break;
+ }
+
+ return (NS_UNAVAIL);
+}
+
+/* nis backend implementation */
+#ifdef YP
+static void
+nis_endstate(void *p)
+{
+ if (p == NULL)
+ return;
+
+ free(((struct nis_state *)p)->current);
+ free(p);
+}
+
+static int
+nis_rpcent(void *retval, void *mdata, va_list ap)
+{
+ char *name;
+ int number;
+ struct rpcent *rpc;
+ char *buffer;
+ size_t bufsize;
+ int *errnop;
+
+ char **rp;
+ char **aliases;
+ int aliases_size;
+
+ char *lastkey;
+ char *resultbuf;
+ int resultbuflen;
+ char buf[YPMAXRECORD + 2];
+
+ struct nis_state *st;
+ int rv;
+ enum nss_lookup_type how;
+ int no_name_active;
+
+ how = (enum nss_lookup_type)mdata;
+ switch (how)
+ {
+ case nss_lt_name:
+ name = va_arg(ap, char *);
+ break;
+ case nss_lt_id:
+ number = va_arg(ap, int);
+ break;
+ case nss_lt_all:
+ break;
+ default:
+ return (NS_NOTFOUND);
+ }
+
+ rpc = va_arg(ap, struct rpcent *);
+ buffer = va_arg(ap, char *);
+ bufsize = va_arg(ap, size_t);
+ errnop = va_arg(ap, int *);
+
+ *errnop = nis_getstate(&st);
+ if (*errnop != 0)
+ return (NS_UNAVAIL);
+
+ if (st->domain[0] == '\0') {
+ if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
+ *errnop = errno;
+ return (NS_UNAVAIL);
+ }
+ }
+
+ no_name_active = 0;
+ do {
+ switch (how)
+ {
+ case nss_lt_name:
+ if (!st->no_name_map)
+ {
+ snprintf(buf, sizeof buf, "%s", name);
+ rv = yp_match(st->domain, "rpc.byname", buf,
+ strlen(buf), &resultbuf, &resultbuflen);
+
+ switch (rv) {
+ case 0:
+ break;
+ case YPERR_MAP:
+ st->stepping = 0;
+ no_name_active = 1;
+ how = nss_lt_all;
+
+ rv = NS_NOTFOUND;
+ continue;
+ default:
+ rv = NS_NOTFOUND;
+ goto fin;
+ }
+ } else {
+ st->stepping = 0;
+ no_name_active = 1;
+ how = nss_lt_all;
+
+ rv = NS_NOTFOUND;
+ continue;
+ }
+ break;
+ case nss_lt_id:
+ snprintf(buf, sizeof buf, "%d", number);
+ if (yp_match(st->domain, "rpc.bynumber", buf,
+ strlen(buf), &resultbuf, &resultbuflen)) {
+ rv = NS_NOTFOUND;
+ goto fin;
+ }
+ break;
+ case nss_lt_all:
+ if (!st->stepping) {
+ rv = yp_first(st->domain, "rpc.bynumber",
+ &st->current,
+ &st->currentlen, &resultbuf,
+ &resultbuflen);
+ if (rv) {
+ rv = NS_NOTFOUND;
+ goto fin;
+ }
+ st->stepping = 1;
+ } else {
+ lastkey = st->current;
+ rv = yp_next(st->domain, "rpc.bynumber",
+ st->current,
+ st->currentlen, &st->current,
+ &st->currentlen,
+ &resultbuf, &resultbuflen);
+ free(lastkey);
+ if (rv) {
+ st->stepping = 0;
+ rv = NS_NOTFOUND;
+ goto fin;
+ }
+ }
+ break;
+ }
+
+ /* we need a room for additional \n symbol */
+ if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
+ sizeof(char *)) {
+ *errnop = ERANGE;
+ rv = NS_RETURN;
+ break;
+ }
+
+ aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
+ aliases_size = (buffer + bufsize - (char *)aliases) /
+ sizeof(char *);
+ if (aliases_size < 1) {
+ *errnop = ERANGE;
+ rv = NS_RETURN;
+ break;
+ }
+
+ /*
+ * rpcent_unpack expects lines terminated with \n -- make it happy
+ */
+ memcpy(buffer, resultbuf, resultbuflen);
+ buffer[resultbuflen] = '\n';
+ buffer[resultbuflen+1] = '\0';
+ free(resultbuf);
+
+ if (rpcent_unpack(buffer, rpc, aliases, aliases_size,
+ errnop) != 0) {
+ if (*errnop == 0)
+ rv = NS_NOTFOUND;
+ else
+ rv = NS_RETURN;
+ } else {
+ if ((how == nss_lt_all) && (no_name_active != 0)) {
+ if (strcmp(rpc->r_name, name) == 0)
+ goto done;
+ for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+ if (strcmp(*rp, name) == 0)
+ goto done;
+ }
+ rv = NS_NOTFOUND;
+ continue;
+done:
+ rv = NS_SUCCESS;
+ } else
+ rv = NS_SUCCESS;
+ }
+
+ } while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
+
+fin:
+ if ((rv == NS_SUCCESS) && (retval != NULL))
+ *((struct rpcent **)retval) = rpc;
+
+ return (rv);
+}
+
+static int
+nis_setrpcent(void *retval, void *mdata, va_list ap)
+{
+ struct nis_state *st;
+ int rv;
+
+ rv = nis_getstate(&st);
+ if (rv != 0)
+ return (NS_UNAVAIL);
+
+ switch ((enum constants)mdata)
+ {
+ case SETRPCENT:
+ case ENDRPCENT:
+ free(st->current);
+ st->current = NULL;
+ st->stepping = 0;
+ break;
+ default:
+ break;
+ }
+
+ return (NS_UNAVAIL);
+}
+#endif
+
+#ifdef NS_CACHING
+static int
+rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
+{
+ char *name;
+ int rpc;
+
+ size_t desired_size, size;
+ enum nss_lookup_type lookup_type;
+ int res = NS_UNAVAIL;
+
+ lookup_type = (enum nss_lookup_type)cache_mdata;
+ switch (lookup_type) {
+ case nss_lt_name:
+ name = va_arg(ap, char *);
+
+ size = strlen(name);
+ desired_size = sizeof(enum nss_lookup_type) + size + 1;
+ if (desired_size > *buffer_size) {
+ res = NS_RETURN;
+ goto fin;
+ }
+
+ memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
+ memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
+
+ res = NS_SUCCESS;
+ break;
+ case nss_lt_id:
+ rpc = va_arg(ap, int);
+
+ desired_size = sizeof(enum nss_lookup_type) + sizeof(int);
+ if (desired_size > *buffer_size) {
+ res = NS_RETURN;
+ goto fin;
+ }
+
+ memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
+ memcpy(buffer + sizeof(enum nss_lookup_type), &rpc,
+ sizeof(int));
+
+ res = NS_SUCCESS;
+ break;
+ default:
+ /* should be unreachable */
+ return (NS_UNAVAIL);
+ }
+
+fin:
+ *buffer_size = desired_size;
+ return (res);
+}
+
+static int
+rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
+ void *cache_mdata)
+{
+ char *name;
+ int num;
+ struct rpcent *rpc;
+ char *orig_buf;
+ size_t orig_buf_size;
+
+ struct rpcent new_rpc;
+ size_t desired_size, size, aliases_size;
+ char *p;
+ char **alias;
+
+ switch ((enum nss_lookup_type)cache_mdata) {
+ case nss_lt_name:
+ name = va_arg(ap, char *);
+ break;
+ case nss_lt_id:
+ num = va_arg(ap, int);
+ break;
+ case nss_lt_all:
+ break;
+ default:
+ /* should be unreachable */
+ return (NS_UNAVAIL);
+ }
+
+ rpc = va_arg(ap, struct rpcent *);
+ orig_buf = va_arg(ap, char *);
+ orig_buf_size = va_arg(ap, size_t);
+
+ desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *);
+ if (rpc->r_name != NULL)
+ desired_size += strlen(rpc->r_name) + 1;
+
+ if (rpc->r_aliases != NULL) {
+ aliases_size = 0;
+ for (alias = rpc->r_aliases; *alias; ++alias) {
+ desired_size += strlen(*alias) + 1;
+ ++aliases_size;
+ }
+
+ desired_size += _ALIGNBYTES + (aliases_size + 1) *
+ sizeof(char *);
+ }
+
+ if (*buffer_size < desired_size) {
+ /* this assignment is here for future use */
+ *buffer_size = desired_size;
+ return (NS_RETURN);
+ }
+
+ new_rpc = *rpc;
+
+ *buffer_size = desired_size;
+ memset(buffer, 0, desired_size);
+ p = buffer + sizeof(struct rpcent) + sizeof(char *);
+ memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *));
+ p = (char *)_ALIGN(p);
+
+ if (new_rpc.r_name != NULL) {
+ size = strlen(new_rpc.r_name);
+ memcpy(p, new_rpc.r_name, size);
+ new_rpc.r_name = p;
+ p += size + 1;
+ }
+
+ if (new_rpc.r_aliases != NULL) {
+ p = (char *)_ALIGN(p);
+ memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size);
+ new_rpc.r_aliases = (char **)p;
+ p += sizeof(char *) * (aliases_size + 1);
+
+ for (alias = new_rpc.r_aliases; *alias; ++alias) {
+ size = strlen(*alias);
+ memcpy(p, *alias, size);
+ *alias = p;
+ p += size + 1;
+ }
+ }
+
+ memcpy(buffer, &new_rpc, sizeof(struct rpcent));
+ return (NS_SUCCESS);
+}
+
+static int
+rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
+ void *cache_mdata)
+{
+ char *name;
+ int num;
+ struct rpcent *rpc;
+ char *orig_buf;
+ size_t orig_buf_size;
+ int *ret_errno;
+
+ char *p;
+ char **alias;
+
+ switch ((enum nss_lookup_type)cache_mdata) {
+ case nss_lt_name:
+ name = va_arg(ap, char *);
+ break;
+ case nss_lt_id:
+ num = va_arg(ap, int);
+ break;
+ case nss_lt_all:
+ break;
+ default:
+ /* should be unreachable */
+ return (NS_UNAVAIL);
+ }
+
+ rpc = va_arg(ap, struct rpcent *);
+ orig_buf = va_arg(ap, char *);
+ orig_buf_size = va_arg(ap, size_t);
+ ret_errno = va_arg(ap, int *);
+
+ if (orig_buf_size <
+ buffer_size - sizeof(struct rpcent) - sizeof(char *)) {
+ *ret_errno = ERANGE;
+ return (NS_RETURN);
+ }
+
+ memcpy(rpc, buffer, sizeof(struct rpcent));
+ memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *));
+
+ orig_buf = (char *)_ALIGN(orig_buf);
+ memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) +
+ _ALIGN(p) - (size_t)p,
+ buffer_size - sizeof(struct rpcent) - sizeof(char *) -
+ _ALIGN(p) + (size_t)p);
+ p = (char *)_ALIGN(p);
+
+ NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *);
+ if (rpc->r_aliases != NULL) {
+ NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **);
+
+ for (alias = rpc->r_aliases ; *alias; ++alias)
+ NS_APPLY_OFFSET(*alias, orig_buf, p, char *);
+ }
+
+ if (retval != NULL)
+ *((struct rpcent **)retval) = rpc;
+
+ return (NS_SUCCESS);
+}
+
+NSS_MP_CACHE_HANDLING(rpc);
+#endif /* NS_CACHING */
+
+
+/* get**_r functions implementation */
+static int
+getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer,
+ size_t bufsize, struct rpcent **result)
+{
+#ifdef NS_CACHING
+ static const nss_cache_info cache_info =
+ NS_COMMON_CACHE_INFO_INITIALIZER(
+ rpc, (void *)nss_lt_name,
+ rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
+#endif
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
+#ifdef YP
+ { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
+#endif
+#ifdef NS_CACHING
+ NS_CACHE_CB(&cache_info)
+#endif
+ { NULL, NULL, NULL }
+ };
+ int rv, ret_errno;
+
+ ret_errno = 0;
+ *result = NULL;
+ rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc,
+ name, rpc, buffer, bufsize, &ret_errno);
+
+ if (rv == NS_SUCCESS)
+ return (0);
+ else
+ return (ret_errno);
+}
+
+static int
+getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer,
+ size_t bufsize, struct rpcent **result)
+{
+#ifdef NS_CACHING
+ static const nss_cache_info cache_info =
+ NS_COMMON_CACHE_INFO_INITIALIZER(
+ rpc, (void *)nss_lt_id,
+ rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
+#endif
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
+#ifdef YP
+ { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
+#endif
+#ifdef NS_CACHING
+ NS_CACHE_CB(&cache_info)
+#endif
+ { NULL, NULL, NULL }
+ };
+ int rv, ret_errno;
+
+ ret_errno = 0;
+ *result = NULL;
+ rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc,
+ number, rpc, buffer, bufsize, &ret_errno);
+
+ if (rv == NS_SUCCESS)
+ return (0);
+ else
+ return (ret_errno);
+}
+
+static int
+getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
+ struct rpcent **result)
+{
+#ifdef NS_CACHING
+ static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
+ rpc, (void *)nss_lt_all,
+ rpc_marshal_func, rpc_unmarshal_func);
+#endif
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
+#ifdef YP
+ { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
+#endif
+#ifdef NS_CACHING
+ NS_CACHE_CB(&cache_info)
+#endif
+ { NULL, NULL, NULL }
+ };
+ int rv, ret_errno;
+
+ ret_errno = 0;
+ *result = NULL;
+ rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc,
+ rpc, buffer, bufsize, &ret_errno);
+
+ if (rv == NS_SUCCESS)
+ return (0);
+ else
+ return (ret_errno);
+}
+
+/* get** wrappers for get**_r functions implementation */
+static void
+rpcent_endstate(void *p)
+{
+ if (p == NULL)
+ return;
+
+ free(((struct rpcent_state *)p)->buffer);
+ free(p);
+}
+
+static int
+wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer,
+ size_t bufsize, struct rpcent **res)
+{
+ return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res));
+}
+
+static int
+wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer,
+ size_t bufsize, struct rpcent **res)
+{
+ return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
+}
+
+static int
+wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer,
+ size_t bufsize, struct rpcent **res)
+{
+ return (getrpcent_r(rpc, buffer, bufsize, res));
+}
+
+static struct rpcent *
+getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **),
+ union key key)
+{
+ int rv;
+ struct rpcent *res;
+ struct rpcent_state * st;
+
+ rv=rpcent_getstate(&st);
+ if (rv != 0) {
+ errno = rv;
+ return NULL;
+ }
+
+ if (st->buffer == NULL) {
+ st->buffer = malloc(RPCENT_STORAGE_INITIAL);
+ if (st->buffer == NULL)
+ return (NULL);
+ st->bufsize = RPCENT_STORAGE_INITIAL;
+ }
+ do {
+ rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res);
+ if (res == NULL && rv == ERANGE) {
+ free(st->buffer);
+ if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) {
+ st->buffer = NULL;
+ errno = ERANGE;
+ return (NULL);
+ }
+ st->bufsize <<= 1;
+ st->buffer = malloc(st->bufsize);
+ if (st->buffer == NULL)
+ return (NULL);
+ }
+ } while (res == NULL && rv == ERANGE);
+ if (rv != 0)
+ errno = rv;
+
+ return (res);
+}
+
+struct rpcent *
+getrpcbyname(char *name)
+{
+ union key key;
+
+ key.name = name;
+
+ return (getrpc(wrap_getrpcbyname_r, key));
+}
+
+struct rpcent *
+getrpcbynumber(int number)
+{
+ union key key;
+
+ key.number = number;
+
+ return (getrpc(wrap_getrpcbynumber_r, key));
+}
+
+struct rpcent *
+getrpcent()
+{
+ union key key;
+
+ key.number = 0; /* not used */
+
+ return (getrpc(wrap_getrpcent_r, key));
+}
+
+void
+setrpcent(int stayopen)
+{
+#ifdef NS_CACHING
+ static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
+ rpc, (void *)nss_lt_all,
+ NULL, NULL);
+#endif
+
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
+#ifdef YP
+ { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
+#endif
+#ifdef NS_CACHING
+ NS_CACHE_CB(&cache_info)
+#endif
+ { NULL, NULL, NULL }
+ };
+
+ (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc,
+ stayopen);
+}
+
+void
+endrpcent()
+{
+#ifdef NS_CACHING
+ static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
+ rpc, (void *)nss_lt_all,
+ NULL, NULL);
+#endif
+
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
+#ifdef YP
+ { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
+#endif
+#ifdef NS_CACHING
+ NS_CACHE_CB(&cache_info)
+#endif
+ { NULL, NULL, NULL }
+ };
+
+ (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc);
+}