summaryrefslogtreecommitdiffstats
path: root/libc/inet
diff options
context:
space:
mode:
author"Steven J. Hill" <sjhill@realitydiluted.com>2005-08-18 23:43:52 +0000
committer"Steven J. Hill" <sjhill@realitydiluted.com>2005-08-18 23:43:52 +0000
commit1e4616de20f7ba07cf490499b4291d8e6c3cc054 (patch)
tree5b20affa5e3ddf8d81667e53395cf2a6aaf6316c /libc/inet
parent1a8265e2cf9482397a03011318419c5c724cac6a (diff)
downloaduClibc-alpine-1e4616de20f7ba07cf490499b4291d8e6c3cc054.tar.bz2
uClibc-alpine-1e4616de20f7ba07cf490499b4291d8e6c3cc054.tar.xz
Sync with trunk.
Diffstat (limited to 'libc/inet')
-rw-r--r--libc/inet/rpc/clnt_generic.c29
-rw-r--r--libc/inet/rpc/getrpcent.c191
-rw-r--r--libc/inet/rpc/rcmd.c25
3 files changed, 169 insertions, 76 deletions
diff --git a/libc/inet/rpc/clnt_generic.c b/libc/inet/rpc/clnt_generic.c
index 349c0f62d..c8fe545c3 100644
--- a/libc/inet/rpc/clnt_generic.c
+++ b/libc/inet/rpc/clnt_generic.c
@@ -53,7 +53,9 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
struct hostent hostbuf, *h;
size_t hstbuflen;
char *hsttmpbuf;
- struct protoent *p;
+ struct protoent protobuf, *p;
+ size_t prtbuflen;
+ char *prttmpbuf;
struct sockaddr_in sin;
struct sockaddr_un sun;
int sock;
@@ -113,14 +115,23 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
memset (sin.sin_zero, 0, sizeof (sin.sin_zero));
memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length);
-#warning getprotobyname is not reentrant... Add getprotobyname_r
- p = getprotobyname(proto);
- if (p == NULL) {
- struct rpc_createerr *ce = &get_rpc_createerr ();
- ce->cf_stat = RPC_UNKNOWNPROTO;
- ce->cf_error.re_errno = EPFNOSUPPORT;
- return NULL;
- }
+ prtbuflen = 1024;
+ prttmpbuf = alloca (prtbuflen);
+ while (getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p) != 0
+ || p == NULL)
+ if (errno != ERANGE)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_UNKNOWNPROTO;
+ ce->cf_error.re_errno = EPFNOSUPPORT;
+ return NULL;
+ }
+ else
+ {
+ /* Enlarge the buffer. */
+ prtbuflen *= 2;
+ prttmpbuf = alloca (prtbuflen);
+ }
sock = RPC_ANYSOCK;
switch (p->p_proto)
diff --git a/libc/inet/rpc/getrpcent.c b/libc/inet/rpc/getrpcent.c
index e290449c0..b796d856d 100644
--- a/libc/inet/rpc/getrpcent.c
+++ b/libc/inet/rpc/getrpcent.c
@@ -42,6 +42,7 @@
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
+#include <errno.h>
/*
* Internet version.
@@ -58,46 +59,37 @@ static struct rpcdata {
char *domain;
} *rpcdata;
-static struct rpcent *interpret(const char *val, int len);
-
static char RPCDB[] = "/etc/rpc";
static struct rpcdata *_rpcdata(void)
{
register struct rpcdata *d = rpcdata;
- if (d == 0) {
+ if (d == NULL) {
d = (struct rpcdata *) calloc(1, sizeof(struct rpcdata));
rpcdata = d;
}
- return (d);
+ return d;
}
-struct rpcent *getrpcbynumber(number)
-register int number;
+struct rpcent *getrpcbynumber(register int number)
{
register struct rpcdata *d = _rpcdata();
- register struct rpcent *p;
+ register struct rpcent *rpc;
- if (d == 0)
- return (0);
+ if (d == NULL)
+ return NULL;
setrpcent(0);
- while ((p = getrpcent())) {
- if (p->r_number == number)
+ while ((rpc = getrpcent())) {
+ if (rpc->r_number == number)
break;
}
endrpcent();
- return (p);
+ return rpc;
}
-struct rpcent *
-#ifdef __linux__
-getrpcbyname(const char *name)
-#else
-getrpcbyname(name)
-char *name;
-#endif
+struct rpcent *getrpcbyname(const char *name)
{
struct rpcent *rpc;
char **rp;
@@ -105,25 +97,21 @@ char *name;
setrpcent(0);
while ((rpc = getrpcent())) {
if (strcmp(rpc->r_name, name) == 0)
- return (rpc);
+ return rpc;
for (rp = rpc->r_aliases; *rp != NULL; rp++) {
if (strcmp(*rp, name) == 0)
- return (rpc);
+ return rpc;
}
}
endrpcent();
- return (NULL);
+ return NULL;
}
-#ifdef __linux__
-void
-#endif
-setrpcent(f)
-int f;
+void setrpcent(int f)
{
register struct rpcdata *d = _rpcdata();
- if (d == 0)
+ if (d == NULL)
return;
if (d->rpcf == NULL)
d->rpcf = fopen(RPCDB, "r");
@@ -135,36 +123,42 @@ int f;
d->stayopen |= f;
}
-#ifdef __linux__
-void
-#endif
-endrpcent()
+void endrpcent()
{
register struct rpcdata *d = _rpcdata();
- if (d == 0)
+ if (d == NULL)
return;
- if (d->current && !d->stayopen) {
+ if (d->stayopen)
+ return;
+ if (d->current) {
free(d->current);
d->current = NULL;
}
- if (d->rpcf && !d->stayopen) {
+ if (d->rpcf) {
fclose(d->rpcf);
d->rpcf = NULL;
}
}
+static struct rpcent *interpret(struct rpcdata *);
+
+static struct rpcent *__get_next_rpcent(struct rpcdata *d)
+{
+ if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
+ return NULL;
+ return interpret(d);
+}
+
struct rpcent *getrpcent()
{
register struct rpcdata *d = _rpcdata();
- if (d == 0)
- return (NULL);
+ if (d == NULL)
+ return NULL;
if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
- return (NULL);
- if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
- return (NULL);
- return interpret(d->line, strlen(d->line));
+ return NULL;
+ return __get_next_rpcent(d);
}
#ifdef __linux__
@@ -184,37 +178,33 @@ static char *firstwhite(char *s)
}
#endif
-static struct rpcent *interpret(const char *val, int len)
+static struct rpcent *interpret(register struct rpcdata *d)
{
- register struct rpcdata *d = _rpcdata();
char *p;
register char *cp, **q;
- if (d == 0)
- return NULL;
- strncpy(d->line, val, len);
p = d->line;
- d->line[len] = '\n';
+ d->line[strlen(p)-1] = '\n';
if (*p == '#')
- return (getrpcent());
+ return __get_next_rpcent(d);
cp = index(p, '#');
if (cp == NULL) {
cp = index(p, '\n');
if (cp == NULL)
- return (getrpcent());
+ return __get_next_rpcent(d);
}
*cp = '\0';
#ifdef __linux__
if ((cp = firstwhite(p)))
*cp++ = 0;
else
- return (getrpcent());
+ return __get_next_rpcent(d);
#else
cp = index(p, ' ');
if (cp == NULL) {
cp = index(p, '\t');
if (cp == NULL)
- return (getrpcent());
+ return __get_next_rpcent(d);
}
*cp++ = '\0';
#endif
@@ -259,5 +249,102 @@ static struct rpcent *interpret(const char *val, int len)
#endif
}
*q = NULL;
- return (&d->rpc);
+ return &d->rpc;
+}
+
+#if defined(__UCLIBC_HAS_REENTRANT_RPC__)
+
+#if defined(__UCLIBC_HAS_THREADS__)
+# include <pthread.h>
+static pthread_mutex_t rpcdata_lock = PTHREAD_MUTEX_INITIALIZER;
+# define LOCK __pthread_mutex_lock(&rpcdata_lock)
+# define UNLOCK __pthread_mutex_unlock(&rpcdata_lock);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+static int __copy_rpcent(struct rpcent *r, struct rpcent *result_buf, char *buffer,
+ size_t buflen, struct rpcent **result)
+{
+ size_t i, s;
+
+ *result = NULL;
+
+ if (!r)
+ return ENOENT;
+
+ /* copy the struct from the shared mem */
+ memset(result_buf, 0x00, sizeof(*result_buf));
+ memset(buffer, 0x00, buflen);
+
+ result_buf->r_number = r->r_number;
+
+ /* copy the aliases ... need to not only copy the alias strings,
+ * but the array of pointers to the alias strings */
+ i = 0;
+ while (r->r_aliases[i++]) ;
+
+ s = i-- * sizeof(char*);
+ if (buflen < s)
+ goto err_out;
+ result_buf->r_aliases = (char**)buffer;
+ buffer += s;
+ buflen -= s;
+
+ while (i-- > 0) {
+ s = strlen(r->r_aliases[i]) + 1;
+ if (buflen < s)
+ goto err_out;
+ result_buf->r_aliases[i] = buffer;
+ buffer += s;
+ buflen -= s;
+ memcpy(result_buf->r_aliases[i], r->r_aliases[i], s);
+ }
+
+ /* copy the name */
+ i = strlen(r->r_name);
+ if (buflen <= i)
+ goto err_out;
+ result_buf->r_name = buffer;
+ memcpy(result_buf->r_name, r->r_name, i);
+
+ /* that was a hoot eh ? */
+ *result = result_buf;
+
+ return 0;
+err_out:
+ return ERANGE;
+}
+
+int getrpcbynumber_r(int number, struct rpcent *result_buf, char *buffer,
+ size_t buflen, struct rpcent **result)
+{
+ int ret;
+ LOCK;
+ ret = __copy_rpcent(getrpcbynumber(number), result_buf, buffer, buflen, result);
+ UNLOCK;
+ return ret;
+}
+
+int getrpcbyname_r(const char *name, struct rpcent *result_buf, char *buffer,
+ size_t buflen, struct rpcent **result)
+{
+ int ret;
+ LOCK;
+ ret = __copy_rpcent(getrpcbyname(name), result_buf, buffer, buflen, result);
+ UNLOCK;
+ return ret;
+}
+
+int getrpcent_r(struct rpcent *result_buf, char *buffer,
+ size_t buflen, struct rpcent **result)
+{
+ int ret;
+ LOCK;
+ ret = __copy_rpcent(getrpcent(), result_buf, buffer, buflen, result);
+ UNLOCK;
+ return ret;
}
+
+#endif /* __UCLIBC_HAS_REENTRANT_RPC__ */
diff --git a/libc/inet/rpc/rcmd.c b/libc/inet/rpc/rcmd.c
index cf839f4c6..af0e2e17a 100644
--- a/libc/inet/rpc/rcmd.c
+++ b/libc/inet/rpc/rcmd.c
@@ -57,11 +57,6 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94";
#include <netinet/in.h>
#include <arpa/inet.h>
-#ifdef __UCLIBC_HAS_THREADS__
-#undef __UCLIBC_HAS_THREADS__
-#warning FIXME I am not reentrant yet...
-#endif
-
/* some forward declarations */
static int __ivaliduser2(FILE *hostf, u_int32_t raddr,
@@ -76,13 +71,13 @@ int rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
const char *locuser, *remuser, *cmd;
int *fd2p;
{
-#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
int herr;
- struct hostent hostbuf;
+ struct hostent hostbuf;
size_t hstbuflen;
char *tmphstbuf;
#endif
- struct hostent *hp;
+ struct hostent *hp;
struct sockaddr_in sin, from;
struct pollfd pfd[2];
int32_t oldmask;
@@ -92,7 +87,7 @@ int rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
pid = getpid();
-#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
hstbuflen = 1024;
#ifdef __ARCH_HAS_MMU__
tmphstbuf = alloca (hstbuflen);
@@ -299,14 +294,14 @@ int ruserok(rhost, superuser, ruser, luser)
struct hostent *hp;
u_int32_t addr;
char **ap;
-#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
size_t buflen;
char *buffer;
int herr;
struct hostent hostbuf;
#endif
-#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
buflen = 1024;
#ifdef __ARCH_HAS_MMU__
buffer = alloca (buflen);
@@ -432,7 +427,7 @@ iruserok2 (raddr, superuser, ruser, luser, rhost)
size_t dirlen;
uid_t uid;
-#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
struct passwd pwdbuf;
#ifdef __ARCH_HAS_MMU__
@@ -515,7 +510,7 @@ __icheckhost (u_int32_t raddr, char *lhost, const char *rhost)
int negate=1; /* Multiply return with this to get -1 instead of 1 */
char **pp;
-#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
int save_errno;
size_t buflen;
char *buffer;
@@ -545,7 +540,7 @@ __icheckhost (u_int32_t raddr, char *lhost, const char *rhost)
return negate * (! (raddr ^ laddr));
/* Better be a hostname. */
-#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_REENTRANT_RPC__
buflen = 1024;
buffer = malloc(buflen);
save_errno = errno;
@@ -559,7 +554,7 @@ __icheckhost (u_int32_t raddr, char *lhost, const char *rhost)
__set_errno (save_errno);
#else
hp = gethostbyname(lhost);
-#endif /* __UCLIBC_HAS_THREADS__ */
+#endif /* __UCLIBC_HAS_REENTRANT_RPC__ */
if (hp == NULL)
return 0;