diff options
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 |
commit | 1e4616de20f7ba07cf490499b4291d8e6c3cc054 (patch) | |
tree | 5b20affa5e3ddf8d81667e53395cf2a6aaf6316c /libc/inet | |
parent | 1a8265e2cf9482397a03011318419c5c724cac6a (diff) | |
download | uClibc-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.c | 29 | ||||
-rw-r--r-- | libc/inet/rpc/getrpcent.c | 191 | ||||
-rw-r--r-- | libc/inet/rpc/rcmd.c | 25 |
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; |