summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/getservent.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/net/getservent.c')
-rw-r--r--lib/libc/net/getservent.c1373
1 files changed, 0 insertions, 1373 deletions
diff --git a/lib/libc/net/getservent.c b/lib/libc/net/getservent.c
deleted file mode 100644
index 3228bdc..0000000
--- a/lib/libc/net/getservent.c
+++ /dev/null
@@ -1,1373 +0,0 @@
-/*
- * Copyright (c) 1983, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <db.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <netdb.h>
-#include <nsswitch.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#ifdef YP
-#include <rpc/rpc.h>
-#include <rpcsvc/yp_prot.h>
-#include <rpcsvc/ypclnt.h>
-#endif
-#include "namespace.h"
-#include "reentrant.h"
-#include "un-namespace.h"
-#include "netdb_private.h"
-#ifdef NS_CACHING
-#include "nscache.h"
-#endif
-#include "nss_tls.h"
-
-enum constants
-{
- SETSERVENT = 1,
- ENDSERVENT = 2,
- SERVENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */
- SERVENT_STORAGE_MAX = 1 << 20, /* 1 MByte */
-};
-
-struct servent_mdata
-{
- 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, int *);
-
-/* files backend declarations */
-struct files_state
-{
- FILE *fp;
- int stayopen;
-
- int compat_mode_active;
-};
-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);
-
-/* db backend declarations */
-struct db_state
-{
- DB *db;
- int stayopen;
- int keynum;
-};
-static void db_endstate(void *);
-NSS_TLS_HANDLING(db);
-
-static int db_servent(void *, void *, va_list);
-static int db_setservent(void *, void *, va_list);
-
-#ifdef YP
-/* nis backend declarations */
-static int nis_servent(void *, void *, va_list);
-static int nis_setservent(void *, void *, va_list);
-
-struct nis_state
-{
- int yp_stepping;
- char yp_domain[MAXHOSTNAMELEN];
- char *yp_key;
- int yp_keylen;
-};
-static void nis_endstate(void *);
-NSS_TLS_HANDLING(nis);
-
-static int nis_servent(void *, void *, va_list);
-static int nis_setservent(void *, void *, va_list);
-#endif
-
-/* 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 key {
- const char *proto;
- union {
- const char *name;
- int port;
- };
-};
-
-static int wrap_getservbyname_r(struct key, struct servent *, char *, size_t,
- struct servent **);
-static int wrap_getservbyport_r(struct key, struct servent *, char *, size_t,
- struct servent **);
-static int wrap_getservent_r(struct key, struct servent *, char *, size_t,
- struct servent **);
-static struct servent *getserv(int (*fn)(struct key, struct servent *, char *,
- size_t, struct servent **), struct key);
-
-#ifdef NS_CACHING
-static int serv_id_func(char *, size_t *, va_list, void *);
-static int serv_marshal_func(char *, size_t *, void *, va_list, void *);
-static int serv_unmarshal_func(char *, size_t, void *, va_list, void *);
-#endif
-
-static int
-servent_unpack(char *p, struct servent *serv, char **aliases,
- size_t aliases_size, int *errnop)
-{
- 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;
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- 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)
- *cp++ = '\0';
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (q < &aliases[aliases_size - 1]) {
- *q++ = cp;
- } else {
- *q = NULL;
- *errnop = ERANGE;
- return -1;
- }
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
- }
- *q = NULL;
-
- return 0;
-}
-
-static int
-parse_result(struct servent *serv, char *buffer, size_t bufsize,
- char *resultbuf, size_t resultbuflen, int *errnop)
-{
- char **aliases;
- int aliases_size;
-
- if (bufsize <= resultbuflen + _ALIGNBYTES + sizeof(char *)) {
- *errnop = ERANGE;
- return (NS_RETURN);
- }
- aliases = (char **)_ALIGN(&buffer[resultbuflen + 1]);
- aliases_size = (buffer + bufsize - (char *)aliases) / sizeof(char *);
- if (aliases_size < 1) {
- *errnop = ERANGE;
- return (NS_RETURN);
- }
-
- memcpy(buffer, resultbuf, resultbuflen);
- buffer[resultbuflen] = '\0';
-
- if (servent_unpack(buffer, serv, aliases, aliases_size, errnop) != 0)
- return ((*errnop == 0) ? NS_NOTFOUND : NS_RETURN);
- return (NS_SUCCESS);
-}
-
-/* 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);
-}
-
-/*
- * compat structures. compat and files sources functionalities are almost
- * equal, so they all are managed by files_servent function
- */
-static int
-files_servent(void *retval, void *mdata, va_list ap)
-{
- static const ns_src compat_src[] = {
-#ifdef YP
- { NSSRC_NIS, NS_SUCCESS },
-#endif
- { NULL, 0 }
- };
- ns_dtab compat_dtab[] = {
- { NSSRC_DB, db_servent,
- (void *)((struct servent_mdata *)mdata)->how },
-#ifdef YP
- { NSSRC_NIS, nis_servent,
- (void *)((struct servent_mdata *)mdata)->how },
-#endif
- { NULL, NULL, NULL }
- };
-
- struct files_state *st;
- int rv;
- int stayopen;
-
- struct servent_mdata *serv_mdata;
- char *name;
- char *proto;
- int port;
-
- struct servent *serv;
- char *buffer;
- size_t bufsize;
- int *errnop;
-
- size_t linesize;
- char *line;
- char **cp;
-
- name = NULL;
- proto = NULL;
- 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 *);
- 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->compat_mode_active = 0;
-
- if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) {
- *errnop = errno;
- return (NS_UNAVAIL);
- }
-
- if (serv_mdata->how == nss_lt_all)
- stayopen = 1;
- else {
- rewind(st->fp);
- stayopen = st->stayopen;
- }
-
- rv = NS_NOTFOUND;
- do {
- if (!st->compat_mode_active) {
- if ((line = fgetln(st->fp, &linesize)) == NULL) {
- *errnop = errno;
- rv = NS_RETURN;
- break;
- }
-
- if (*line=='+' && serv_mdata->compat_mode != 0)
- st->compat_mode_active = 1;
- }
-
- 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_COMPAT, "getservent_r",
- compat_src, serv, buffer, bufsize, errnop);
- break;
- }
-
- if (!(rv & NS_TERMINATE) ||
- serv_mdata->how != nss_lt_all)
- st->compat_mode_active = 0;
-
- continue;
- }
-
- rv = parse_result(serv, buffer, bufsize, line, linesize,
- errnop);
- if (rv == NS_NOTFOUND)
- continue;
- if (rv == NS_RETURN)
- break;
-
- rv = NS_NOTFOUND;
- 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;
-
- 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;
- }
-
- } while (!(rv & NS_TERMINATE));
-
- if (!stayopen && st->fp != NULL) {
- fclose(st->fp);
- st->fp = NULL;
- }
-
- if ((rv == NS_SUCCESS) && (retval != NULL))
- *(struct servent **)retval=serv;
-
- return (rv);
-}
-
-static int
-files_setservent(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 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:
- if (st->fp != NULL) {
- fclose(st->fp);
- st->fp = NULL;
- }
- st->stayopen = 0;
- break;
- default:
- break;
- };
-
- st->compat_mode_active = 0;
- return (NS_UNAVAIL);
-}
-
-/* db backend implementation */
-static void
-db_endstate(void *p)
-{
- DB *db;
-
- if (p == NULL)
- return;
-
- db = ((struct db_state *)p)->db;
- if (db != NULL)
- db->close(db);
-
- free(p);
-}
-
-static int
-db_servent(void *retval, void *mdata, va_list ap)
-{
- char buf[BUFSIZ];
- DBT key, data, *result;
- DB *db;
-
- struct db_state *st;
- int rv;
- int stayopen;
-
- enum nss_lookup_type how;
- char *name;
- char *proto;
- int port;
-
- struct servent *serv;
- char *buffer;
- size_t bufsize;
- int *errnop;
-
- 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;
- };
-
- serv = va_arg(ap, struct servent *);
- buffer = va_arg(ap, char *);
- bufsize = va_arg(ap, size_t);
- errnop = va_arg(ap,int *);
-
- *errnop = db_getstate(&st);
- if (*errnop != 0)
- return (NS_UNAVAIL);
-
- if (how == nss_lt_all && st->keynum < 0)
- return (NS_NOTFOUND);
-
- if (st->db == NULL) {
- st->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, DB_HASH, NULL);
- if (st->db == NULL) {
- *errnop = errno;
- return (NS_UNAVAIL);
- }
- }
-
- stayopen = (how == nss_lt_all) ? 1 : st->stayopen;
- db = st->db;
-
- do {
- switch (how) {
- case nss_lt_name:
- key.data = buf;
- if (proto == NULL)
- key.size = snprintf(buf, sizeof(buf),
- "\376%s", name);
- else
- key.size = snprintf(buf, sizeof(buf),
- "\376%s/%s", name, proto);
- key.size++;
- if (db->get(db, &key, &data, 0) != 0 ||
- db->get(db, &data, &key, 0) != 0) {
- rv = NS_NOTFOUND;
- goto db_fin;
- }
- result = &key;
- break;
- case nss_lt_id:
- key.data = buf;
- port = htons(port);
- if (proto == NULL)
- key.size = snprintf(buf, sizeof(buf),
- "\377%d", port);
- else
- key.size = snprintf(buf, sizeof(buf),
- "\377%d/%s", port, proto);
- key.size++;
- if (db->get(db, &key, &data, 0) != 0 ||
- db->get(db, &data, &key, 0) != 0) {
- rv = NS_NOTFOUND;
- goto db_fin;
- }
- result = &key;
- break;
- case nss_lt_all:
- key.data = buf;
- key.size = snprintf(buf, sizeof(buf), "%d",
- st->keynum++);
- key.size++;
- if (db->get(db, &key, &data, 0) != 0) {
- st->keynum = -1;
- rv = NS_NOTFOUND;
- goto db_fin;
- }
- result = &data;
- break;
- }
-
- rv = parse_result(serv, buffer, bufsize, result->data,
- result->size - 1, errnop);
-
- } while (!(rv & NS_TERMINATE) && how == nss_lt_all);
-
-db_fin:
- if (!stayopen && st->db != NULL) {
- db->close(db);
- st->db = NULL;
- }
-
- if (rv == NS_SUCCESS && retval != NULL)
- *(struct servent **)retval = serv;
-
- return (rv);
-}
-
-static int
-db_setservent(void *retval, void *mdata, va_list ap)
-{
- DB *db;
- struct db_state *st;
- int rv;
- int f;
-
- rv = db_getstate(&st);
- if (rv != 0)
- return (NS_UNAVAIL);
-
- switch ((enum constants)mdata) {
- case SETSERVENT:
- f = va_arg(ap, int);
- st->stayopen |= f;
- st->keynum = 0;
- break;
- case ENDSERVENT:
- db = st->db;
- if (db != NULL) {
- db->close(db);
- st->db = 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)->yp_key);
- free(p);
-}
-
-static int
-nis_servent(void *retval, void *mdata, va_list ap)
-{
- char *resultbuf, *lastkey;
- int resultbuflen;
- char buf[YPMAXRECORD + 2];
-
- struct nis_state *st;
- int rv;
-
- enum nss_lookup_type how;
- char *name;
- char *proto;
- int port;
-
- struct servent *serv;
- char *buffer;
- size_t bufsize;
- int *errnop;
-
- 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;
- };
-
- serv = va_arg(ap, struct servent *);
- 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->yp_domain[0] == '\0') {
- if (getdomainname(st->yp_domain, sizeof st->yp_domain)) {
- *errnop = errno;
- return (NS_UNAVAIL);
- }
- }
-
- 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.
- */
- rv = yp_match(st->yp_domain, "services.byport", buf,
- strlen(buf), &resultbuf, &resultbuflen);
- if (rv) {
- 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) {
- 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;
- };
-
- rv = parse_result(serv, buffer, bufsize, resultbuf,
- resultbuflen, errnop);
- free(resultbuf);
-
- } while (!(rv & NS_TERMINATE) && how == nss_lt_all);
-
-fin:
- if (rv == NS_SUCCESS && retval != NULL)
- *(struct servent **)retval = serv;
-
- return (rv);
-}
-
-static int
-nis_setservent(void *result, 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 SETSERVENT:
- case ENDSERVENT:
- free(st->yp_key);
- st->yp_key = NULL;
- st->yp_stepping = 0;
- break;
- default:
- break;
- };
-
- return (NS_UNAVAIL);
-}
-#endif
-
-/* compat backend implementation */
-static int
-compat_setservent(void *retval, void *mdata, va_list ap)
-{
- static const ns_src compat_src[] = {
-#ifdef YP
- { NSSRC_NIS, NS_SUCCESS },
-#endif
- { NULL, 0 }
- };
- ns_dtab compat_dtab[] = {
- { NSSRC_DB, db_setservent, mdata },
-#ifdef YP
- { NSSRC_NIS, nis_setservent, mdata },
-#endif
- { NULL, NULL, NULL }
- };
- int f;
-
- (void)files_setservent(retval, mdata, ap);
-
- switch ((enum constants)mdata) {
- case SETSERVENT:
- f = va_arg(ap,int);
- (void)nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT,
- "setservent", compat_src, f);
- break;
- case ENDSERVENT:
- (void)nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT,
- "endservent", compat_src);
- break;
- default:
- break;
- }
-
- return (NS_UNAVAIL);
-}
-
-#ifdef NS_CACHING
-static int
-serv_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
-{
- char *name;
- char *proto;
- int port;
-
- size_t desired_size, size, size2;
- 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 *);
- proto = va_arg(ap, char *);
-
- size = strlen(name);
- desired_size = sizeof(enum nss_lookup_type) + size + 1;
- if (proto != NULL) {
- size2 = strlen(proto);
- desired_size += size2 + 1;
- } else
- size2 = 0;
-
- 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);
-
- if (proto != NULL)
- memcpy(buffer + sizeof(enum nss_lookup_type) + size + 1,
- proto, size2 + 1);
-
- res = NS_SUCCESS;
- break;
- case nss_lt_id:
- port = va_arg(ap, int);
- proto = va_arg(ap, char *);
-
- desired_size = sizeof(enum nss_lookup_type) + sizeof(int);
- if (proto != NULL) {
- size = strlen(proto);
- desired_size += size + 1;
- } else
- size = 0;
-
- 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), &port,
- sizeof(int));
-
- if (proto != NULL)
- memcpy(buffer + sizeof(enum nss_lookup_type) +
- sizeof(int), proto, size + 1);
-
- res = NS_SUCCESS;
- break;
- default:
- /* should be unreachable */
- return (NS_UNAVAIL);
- }
-
-fin:
- *buffer_size = desired_size;
- return (res);
-}
-
-int
-serv_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
- void *cache_mdata)
-{
- char *name;
- char *proto;
- int port;
- struct servent *serv;
- char *orig_buf;
- size_t orig_buf_size;
-
- struct servent new_serv;
- size_t desired_size;
- char **alias;
- char *p;
- size_t size;
- size_t aliases_size;
-
- switch ((enum nss_lookup_type)cache_mdata) {
- 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:
- /* should be unreachable */
- return (NS_UNAVAIL);
- }
-
- serv = va_arg(ap, struct servent *);
- orig_buf = va_arg(ap, char *);
- orig_buf_size = va_arg(ap, size_t);
-
- desired_size = _ALIGNBYTES + sizeof(struct servent) + sizeof(char *);
- if (serv->s_name != NULL)
- desired_size += strlen(serv->s_name) + 1;
- if (serv->s_proto != NULL)
- desired_size += strlen(serv->s_proto) + 1;
-
- aliases_size = 0;
- if (serv->s_aliases != NULL) {
- for (alias = serv->s_aliases; *alias; ++alias) {
- desired_size += strlen(*alias) + 1;
- ++aliases_size;
- }
-
- desired_size += _ALIGNBYTES +
- sizeof(char *) * (aliases_size + 1);
- }
-
- if (*buffer_size < desired_size) {
- /* this assignment is here for future use */
- *buffer_size = desired_size;
- return (NS_RETURN);
- }
-
- memcpy(&new_serv, serv, sizeof(struct servent));
- memset(buffer, 0, desired_size);
-
- *buffer_size = desired_size;
- p = buffer + sizeof(struct servent) + sizeof(char *);
- memcpy(buffer + sizeof(struct servent), &p, sizeof(char *));
- p = (char *)_ALIGN(p);
-
- if (new_serv.s_name != NULL) {
- size = strlen(new_serv.s_name);
- memcpy(p, new_serv.s_name, size);
- new_serv.s_name = p;
- p += size + 1;
- }
-
- if (new_serv.s_proto != NULL) {
- size = strlen(new_serv.s_proto);
- memcpy(p, new_serv.s_proto, size);
- new_serv.s_proto = p;
- p += size + 1;
- }
-
- if (new_serv.s_aliases != NULL) {
- p = (char *)_ALIGN(p);
- memcpy(p, new_serv.s_aliases, sizeof(char *) * aliases_size);
- new_serv.s_aliases = (char **)p;
- p += sizeof(char *) * (aliases_size + 1);
-
- for (alias = new_serv.s_aliases; *alias; ++alias) {
- size = strlen(*alias);
- memcpy(p, *alias, size);
- *alias = p;
- p += size + 1;
- }
- }
-
- memcpy(buffer, &new_serv, sizeof(struct servent));
- return (NS_SUCCESS);
-}
-
-int
-serv_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
- void *cache_mdata)
-{
- char *name;
- char *proto;
- int port;
- struct servent *serv;
- char *orig_buf;
- char *p;
- char **alias;
- size_t orig_buf_size;
- int *ret_errno;
-
- switch ((enum nss_lookup_type)cache_mdata) {
- 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:
- /* should be unreachable */
- return (NS_UNAVAIL);
- }
-
- serv = va_arg(ap, struct servent *);
- 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 servent) - sizeof(char *)) {
- *ret_errno = ERANGE;
- return (NS_RETURN);
- }
-
- memcpy(serv, buffer, sizeof(struct servent));
- memcpy(&p, buffer + sizeof(struct servent), sizeof(char *));
-
- orig_buf = (char *)_ALIGN(orig_buf);
- memcpy(orig_buf, buffer + sizeof(struct servent) + sizeof(char *) +
- (_ALIGN(p) - (size_t)p),
- buffer_size - sizeof(struct servent) - sizeof(char *) -
- (_ALIGN(p) - (size_t)p));
- p = (char *)_ALIGN(p);
-
- NS_APPLY_OFFSET(serv->s_name, orig_buf, p, char *);
- NS_APPLY_OFFSET(serv->s_proto, orig_buf, p, char *);
- if (serv->s_aliases != NULL) {
- NS_APPLY_OFFSET(serv->s_aliases, orig_buf, p, char **);
-
- for (alias = serv->s_aliases; *alias; ++alias)
- NS_APPLY_OFFSET(*alias, orig_buf, p, char *);
- }
-
- if (retval != NULL)
- *((struct servent **)retval) = serv;
- return (NS_SUCCESS);
-}
-
-NSS_MP_CACHE_HANDLING(services);
-#endif /* NS_CACHING */
-
-/* get**_r functions implementation */
-int
-getservbyname_r(const char *name, const char *proto, struct servent *serv,
- char *buffer, size_t bufsize, struct servent **result)
-{
- static const struct servent_mdata mdata = { nss_lt_name, 0 };
- static const struct servent_mdata compat_mdata = { nss_lt_name, 1 };
-#ifdef NS_CACHING
- static const nss_cache_info cache_info =
- NS_COMMON_CACHE_INFO_INITIALIZER(
- services, (void *)nss_lt_name,
- serv_id_func, serv_marshal_func, serv_unmarshal_func);
-#endif /* NS_CACHING */
- static const ns_dtab dtab[] = {
- { NSSRC_FILES, files_servent, (void *)&mdata },
- { NSSRC_DB, db_servent, (void *)nss_lt_name },
-#ifdef YP
- { NSSRC_NIS, nis_servent, (void *)nss_lt_name },
-#endif
- { NSSRC_COMPAT, files_servent, (void *)&compat_mdata },
-#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_SERVICES, "getservbyname_r",
- defaultsrc, name, proto, serv, buffer, bufsize, &ret_errno);
-
- if (rv == NS_SUCCESS)
- return (0);
- else
- return (ret_errno);
-}
-
-int
-getservbyport_r(int port, const char *proto, struct servent *serv,
- char *buffer, size_t bufsize, struct servent **result)
-{
- static const struct servent_mdata mdata = { nss_lt_id, 0 };
- static const struct servent_mdata compat_mdata = { nss_lt_id, 1 };
-#ifdef NS_CACHING
- static const nss_cache_info cache_info =
- NS_COMMON_CACHE_INFO_INITIALIZER(
- services, (void *)nss_lt_id,
- serv_id_func, serv_marshal_func, serv_unmarshal_func);
-#endif
- static const ns_dtab dtab[] = {
- { NSSRC_FILES, files_servent, (void *)&mdata },
- { NSSRC_DB, db_servent, (void *)nss_lt_id },
-#ifdef YP
- { NSSRC_NIS, nis_servent, (void *)nss_lt_id },
-#endif
- { NSSRC_COMPAT, files_servent, (void *)&compat_mdata },
-#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_SERVICES, "getservbyport_r",
- defaultsrc, port, proto, serv, buffer, bufsize, &ret_errno);
-
- if (rv == NS_SUCCESS)
- return (0);
- else
- return (ret_errno);
-}
-
-int
-getservent_r(struct servent *serv, char *buffer, size_t bufsize,
- struct servent **result)
-{
- static const struct servent_mdata mdata = { nss_lt_all, 0 };
- static const struct servent_mdata compat_mdata = { nss_lt_all, 1 };
-#ifdef NS_CACHING
- static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
- services, (void *)nss_lt_all,
- serv_marshal_func, serv_unmarshal_func);
-#endif
- static const ns_dtab dtab[] = {
- { NSSRC_FILES, files_servent, (void *)&mdata },
- { NSSRC_DB, db_servent, (void *)nss_lt_all },
-#ifdef YP
- { NSSRC_NIS, nis_servent, (void *)nss_lt_all },
-#endif
- { NSSRC_COMPAT, files_servent, (void *)&compat_mdata },
-#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_SERVICES, "getservent_r",
- defaultsrc, serv, buffer, bufsize, &ret_errno);
-
- if (rv == NS_SUCCESS)
- return (0);
- else
- return (ret_errno);
-}
-
-void
-setservent(int stayopen)
-{
-#ifdef NS_CACHING
- static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
- services, (void *)nss_lt_all,
- NULL, NULL);
-#endif
- static const ns_dtab dtab[] = {
- { NSSRC_FILES, files_setservent, (void *)SETSERVENT },
- { NSSRC_DB, db_setservent, (void *)SETSERVENT },
-#ifdef YP
- { NSSRC_NIS, nis_setservent, (void *)SETSERVENT },
-#endif
- { NSSRC_COMPAT, compat_setservent, (void *)SETSERVENT },
-#ifdef NS_CACHING
- NS_CACHE_CB(&cache_info)
-#endif
- { NULL, NULL, NULL }
- };
-
- (void)nsdispatch(NULL, dtab, NSDB_SERVICES, "setservent", defaultsrc,
- stayopen);
-}
-
-void
-endservent()
-{
-#ifdef NS_CACHING
- static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
- services, (void *)nss_lt_all,
- NULL, NULL);
-#endif
- static const ns_dtab dtab[] = {
- { NSSRC_FILES, files_setservent, (void *)ENDSERVENT },
- { NSSRC_DB, db_setservent, (void *)ENDSERVENT },
-#ifdef YP
- { NSSRC_NIS, nis_setservent, (void *)ENDSERVENT },
-#endif
- { NSSRC_COMPAT, compat_setservent, (void *)ENDSERVENT },
-#ifdef NS_CACHING
- NS_CACHE_CB(&cache_info)
-#endif
- { NULL, NULL, NULL }
- };
-
- (void)nsdispatch(NULL, dtab, NSDB_SERVICES, "endservent", defaultsrc);
-}
-
-/* get** wrappers for get**_r functions implementation */
-static void
-servent_endstate(void *p)
-{
- if (p == NULL)
- return;
-
- free(((struct servent_state *)p)->buffer);
- free(p);
-}
-
-static int
-wrap_getservbyname_r(struct key key, struct servent *serv, char *buffer,
- size_t bufsize, struct servent **res)
-{
- return (getservbyname_r(key.name, key.proto, serv, buffer, bufsize,
- res));
-}
-
-static int
-wrap_getservbyport_r(struct key key, struct servent *serv, char *buffer,
- size_t bufsize, struct servent **res)
-{
- return (getservbyport_r(key.port, key.proto, serv, buffer, bufsize,
- res));
-}
-
-static int
-wrap_getservent_r(struct key key, struct servent *serv, char *buffer,
- size_t bufsize, struct servent **res)
-{
- return (getservent_r(serv, buffer, bufsize, res));
-}
-
-static struct servent *
-getserv(int (*fn)(struct key, struct servent *, char *, size_t,
- struct servent **), struct key key)
-{
- int rv;
- struct servent *res;
- struct servent_state * st;
-
- rv = servent_getstate(&st);
- if (rv != 0) {
- errno = rv;
- return NULL;
- }
-
- if (st->buffer == NULL) {
- st->buffer = malloc(SERVENT_STORAGE_INITIAL);
- if (st->buffer == NULL)
- return (NULL);
- st->bufsize = SERVENT_STORAGE_INITIAL;
- }
- do {
- rv = fn(key, &st->serv, st->buffer, st->bufsize, &res);
- if (res == NULL && rv == ERANGE) {
- free(st->buffer);
- if ((st->bufsize << 1) > SERVENT_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 servent *
-getservbyname(const char *name, const char *proto)
-{
- struct key key;
-
- key.name = name;
- key.proto = proto;
-
- return (getserv(wrap_getservbyname_r, key));
-}
-
-struct servent *
-getservbyport(int port, const char *proto)
-{
- struct key key;
-
- key.port = port;
- key.proto = proto;
-
- return (getserv(wrap_getservbyport_r, key));
-}
-
-struct servent *
-getservent()
-{
- struct key key;
-
- key.proto = NULL;
- key.port = 0;
-
- return (getserv(wrap_getservent_r, key));
-}
OpenPOWER on IntegriCloud