PERFORCE change 80260 for review
soc-bushman
soc-bushman at FreeBSD.org
Fri Jul 15 13:42:20 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80260
Change 80260 by soc-bushman at soc-bushman_stinger on 2005/07/15 13:42:14
rpc finished - patch and testing
Affected files ...
.. //depot/projects/soc2005/nsswitch_cached/src/include/rpc/rpcent.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/rpc/getrpcent.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/Makefile#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/getrpcent.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/getrpcent.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/getrpcent_test.c#2 edit
Differences ...
==== //depot/projects/soc2005/nsswitch_cached/src/include/rpc/rpcent.h#2 (text+ko) ====
@@ -53,12 +53,13 @@
};
__BEGIN_DECLS
-extern struct rpcent *getrpcbyname_r(const char *, struct rpcent *,
- char *, int);
-extern struct rpcent *getrpcbynumber_r(int, struct rpcent *, char *, int);
-extern struct rpcent *getrpcent_r(struct rpcent *, char *, int);
-
-/* Old interfaces that return a pointer to a static area; MT-unsafe */
+extern int getrpcbyname_r(const char *, struct rpcent *, char *, size_t,
+ struct rpcent **);
+extern int getrpcbynumber_r(int, struct rpcent *, char *, size_t,
+ struct rpcent **);
+extern int getrpcent_r(struct rpcent *, char *, size_t, struct rpcent **);
+
+/* These interfaces are currently implemented through nsswitch and MT-safe */
extern struct rpcent *getrpcbyname(char *);
extern struct rpcent *getrpcbynumber(int);
extern struct rpcent *getrpcent(void);
==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/rpc/getrpcent.c#2 (text+ko) ====
@@ -40,281 +40,740 @@
* Copyright (c) 1984 by Sun Microsystems, Inc.
*/
-#include "namespace.h"
+#include "getrpcent.h"
+
+#include <sys/param.h>
#include <sys/types.h>
-
-#include <netinet/in.h>
+#include <sys/socket.h>
#include <arpa/inet.h>
-
#include <assert.h>
-#include <netdb.h>
+#include <errno.h>
+#include <nsswitch.h>
+#include <netinet/in.h>
#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
#include <stdlib.h>
-#include <string.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"
+
+#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 }
+};
-/*
- * Internet version.
- */
-static struct rpcdata {
- FILE *rpcf;
+/* files backend declarations */
+struct files_state {
+ FILE *fp;
int stayopen;
-#define MAXALIASES 35
- char *rpc_aliases[MAXALIASES];
- struct rpcent rpc;
- char line[BUFSIZ+1];
-#ifdef YP
- char *domain;
+};
+
+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
-} *rpcdata;
-static struct rpcent *interpret(char *val, size_t len);
+/* 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);
-#ifdef YP
-static int __yp_nomap = 0;
-#endif /* YP */
+union key {
+ const char *name;
+ int number;
+};
-#define RPCDB "/etc/rpc"
+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);
-static struct rpcdata *_rpcdata(void);
+static int
+rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
+ size_t aliases_size, int *errnop)
+{
+ char *cp, **q;
-static struct rpcdata *
-_rpcdata()
-{
- struct rpcdata *d = rpcdata;
+ assert(p != NULL);
- if (d == 0) {
- d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
- rpcdata = d;
+ 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';
}
- return (d);
+ *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);
}
-struct rpcent *
-getrpcbynumber(number)
- int number;
+static int
+files_rpcent(void *retval, void *mdata, va_list ap)
{
-#ifdef YP
- int reason;
- char adrstr[16];
-#endif
- struct rpcent *p;
- struct rpcdata *d = _rpcdata();
+ 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;
+ }
- if (d == 0)
- return (0);
-#ifdef YP
- if (!__yp_nomap && _yp_check(&d->domain)) {
- sprintf(adrstr, "%d", number);
- reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
- &d->current, &d->currentlen);
- switch(reason) {
- case 0:
- break;
- case YPERR_MAP:
- __yp_nomap = 1;
- goto no_yp;
- break;
- default:
- return(0);
- break;
- }
- d->current[d->currentlen] = '\0';
- p = interpret(d->current, d->currentlen);
- (void) free(d->current);
- return p;
- }
-no_yp:
-#endif /* YP */
+ 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';
- setrpcent(0);
- while ((p = getrpcent()) != NULL) {
- if (p->r_number == number)
+ 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;
}
- endrpcent();
- return (p);
+
+ 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);
}
-struct rpcent *
-getrpcbyname(name)
- char *name;
+/* nis backend implementation */
+#ifdef YP
+static void
+nis_endstate(void *p)
{
- struct rpcent *rpc = NULL;
- char **rp;
+ if (p == NULL)
+ return;
- assert(name != NULL);
+ free(((struct nis_state *)p)->current);
+ free(p);
+}
- setrpcent(0);
- while ((rpc = getrpcent()) != NULL) {
- if (strcmp(rpc->r_name, name) == 0)
- goto done;
- for (rp = rpc->r_aliases; *rp != NULL; rp++) {
- if (strcmp(*rp, name) == 0)
- goto done;
+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:
- endrpcent();
- return (rpc);
+ 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
+
+/* get**_r functions implementation */
+int
+getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer,
+ size_t bufsize, struct rpcent **result)
+{
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
+#ifdef YP
+ { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
+#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);
+}
+
+int
+getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer,
+ size_t bufsize, struct rpcent **result)
+{
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
+#ifdef YP
+ { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
+#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);
}
-void
-setrpcent(f)
- int f;
+int
+getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
+ struct rpcent **result)
{
- struct rpcdata *d = _rpcdata();
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
+#ifdef YP
+ { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
+#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 (d == 0)
- return;
-#ifdef YP
- if (!__yp_nomap && _yp_check(NULL)) {
- if (d->current)
- free(d->current);
- d->current = NULL;
- d->currentlen = 0;
- return;
- }
- __yp_nomap = 0;
-#endif /* YP */
- if (d->rpcf == NULL)
- d->rpcf = fopen(RPCDB, "r");
+ if (rv == NS_SUCCESS)
+ return (0);
else
- rewind(d->rpcf);
- d->stayopen |= f;
+ return (ret_errno);
+}
+
+void
+setrpcent(int stayopen)
+{
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
+#ifdef YP
+ { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
+#endif
+ { NULL, NULL, NULL }
+ };
+
+ (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, stayopen);
}
-void
+void
endrpcent()
{
- struct rpcdata *d = _rpcdata();
+ static const ns_dtab dtab[] = {
+ { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
+#ifdef YP
+ { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
+#endif
+ { NULL, NULL, NULL }
+ };
+
+ (void)nsdispatch(NULL, dtab, NSDB_SERVICES, "endrpcent", defaultsrc);
+}
- if (d == 0)
+/* get** wrappers for get**_r functions implementation */
+static void
+rpcent_endstate(void *p)
+{
+ if (p == NULL)
return;
-#ifdef YP
- if (!__yp_nomap && _yp_check(NULL)) {
- if (d->current && !d->stayopen)
- free(d->current);
- d->current = NULL;
- d->currentlen = 0;
- return;
- }
- __yp_nomap = 0;
-#endif /* YP */
- if (d->rpcf && !d->stayopen) {
- fclose(d->rpcf);
- d->rpcf = NULL;
- }
+
+ 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));
}
-struct rpcent *
-getrpcent()
+static int
+wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer, size_t bufsize,
+ struct rpcent **res)
{
- struct rpcdata *d = _rpcdata();
-#ifdef YP
- struct rpcent *hp;
- int reason;
- char *val = NULL;
- int vallen;
-#endif
+ return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
+}
- if (d == 0)
- return(NULL);
-#ifdef YP
- if (!__yp_nomap && _yp_check(&d->domain)) {
- if (d->current == NULL && d->currentlen == 0) {
- reason = yp_first(d->domain, "rpc.bynumber",
- &d->current, &d->currentlen,
- &val, &vallen);
- } else {
- reason = yp_next(d->domain, "rpc.bynumber",
- d->current, d->currentlen,
- &d->current, &d->currentlen,
- &val, &vallen);
- }
- switch(reason) {
- case 0:
- break;
- case YPERR_MAP:
- __yp_nomap = 1;
- goto no_yp;
- break;
- default:
- return(0);
- break;
- }
- val[vallen] = '\0';
- hp = interpret(val, vallen);
- (void) free(val);
- return hp;
- }
-no_yp:
-#endif /* YP */
- if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
- return (NULL);
- /* -1 so there is room to append a \n below */
- if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
- return (NULL);
- return (interpret(d->line, strlen(d->line)));
+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 *
-interpret(val, len)
- char *val;
- size_t len;
+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)
{
- struct rpcdata *d = _rpcdata();
- char *p;
- char *cp, **q;
+ union key key;
- assert(val != NULL);
+ key.name = name;
+
+ return (getrpc(wrap_getrpcbyname_r, key));
+}
- if (d == 0)
- return (0);
- (void) strncpy(d->line, val, BUFSIZ);
- d->line[BUFSIZ] = '\0';
- p = d->line;
- p[len] = '\n';
- if (*p == '#')
- return (getrpcent());
- cp = strpbrk(p, "#\n");
- if (cp == NULL)
- return (getrpcent());
- *cp = '\0';
- cp = strpbrk(p, " \t");
- if (cp == NULL)
- return (getrpcent());
- *cp++ = '\0';
- /* THIS STUFF IS INTERNET SPECIFIC */
- d->rpc.r_name = d->line;
- while (*cp == ' ' || *cp == '\t')
- cp++;
- d->rpc.r_number = atoi(cp);
- q = d->rpc.r_aliases = d->rpc_aliases;
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (q < &(d->rpc_aliases[MAXALIASES - 1]))
- *q++ = cp;
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
- }
- *q = NULL;
- return (&d->rpc);
+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));
+}
==== //depot/projects/soc2005/nsswitch_cached/tests/getrpcent_test/Makefile#2 (text+ko) ====
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list