diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2000-05-03 14:12:51 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2000-05-03 14:12:51 +0000 |
commit | 9fb78b8039b23d3ec609ae1a73650200fb928623 (patch) | |
tree | fe3f8ad0132ed1dc13d21c66816a527e7771b8b8 /c/src/librpc | |
parent | This commit was manufactured by cvs2svn to create branch 'rtems-4-5-branch'. (diff) | |
download | rtems-9fb78b8039b23d3ec609ae1a73650200fb928623.tar.bz2 |
Update from Eric Norum <eric@cls.usask.ca>.
Diffstat (limited to 'c/src/librpc')
-rw-r--r-- | c/src/librpc/README_RTEMS | 51 | ||||
-rw-r--r-- | c/src/librpc/include/rpc/rpc.h | 43 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/Makefile.am | 4 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/clnt_generic.c | 4 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/clnt_perror.c | 2 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/clnt_raw.c | 13 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/clnt_simple.c | 9 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/rpc_commondata.c | 2 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/rpcdname.c | 3 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/rtems_portmapper.c | 485 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/rtems_rpc.c | 56 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/svc.c | 19 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/svc_auth.c | 2 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/svc_raw.c | 17 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/svc_run.c | 6 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/svc_simple.c | 39 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/svc_tcp.c | 5 | ||||
-rw-r--r-- | c/src/librpc/src/rpc/svc_unix.c | 5 | ||||
-rw-r--r-- | c/src/librpc/src/xdr/Makefile.am | 2 | ||||
-rw-r--r-- | c/src/librpc/src/xdr/xdr_float.c | 3 |
20 files changed, 692 insertions, 78 deletions
diff --git a/c/src/librpc/README_RTEMS b/c/src/librpc/README_RTEMS index 2d9e224e47..e60f8799aa 100644 --- a/c/src/librpc/README_RTEMS +++ b/c/src/librpc/README_RTEMS @@ -1,14 +1,46 @@ -# -# $Id$ -# +USING RPC/XDR ON RTEMS +====================== +For the most part, programmers using RPC/XDR routines on RTEMS +can proceed as if they were to be using a POSIX/UNIX system. +The only significant changes are those to start the portmapper +and to allow use of RPC/XDR by multiple threads. +Starting the portmapper +======================= +The SUN portmapper program has been modified to run as an RTEMS +task. Applications which need the portmapper can start this +task by calling: + int rtems_rpc_start_portmapper (int priority); +The return value is an RTEMS status code. + +Multi-threaded operation +======================== +The RPC/XDR package has been modified to allow for multiple RTEMS +tasks to use RPC/XDR routines. If more than one task is to call +an RPC/XDR routine, the additional tasks must call: + int rtems_rpc_task_init(void); +before calling any RPC/XDR routines. For example, the portmapper +calls this routine since the portmapper uses RPC/XDR routines in +a separate thread. +The return value is an RTEMS status code. + + +Porting Notes +============= Most of the FreeBSD rpc library ports to RTEMS with little -or no modification, but some of the library has not made it into -the RTEMS implementation. FreeBSD source files which have been -left out include: +or no modification beyond that required to provide for operation +in a multitasking environment. Multitasking operation was +provided by moving all `static persistence' variables into +a single structure and using an RTEMS task variable to point +to that structure. + +Some of the library, however, has not made it into the RTEMS +implementation. FreeBSD source files which have been left out include: - Files which provide RPC to the AF_UNIX address family: clnt_unix.c svc_unix.c + An `ifndef __rtems__' was added to clnt_generic.c because clnt_unix.c + was omitted. - Files which need NIS: auth_time.c - Files which provide DES authentication: @@ -23,3 +55,10 @@ left out include: svc_auth_des.c The FreeBSD xdr source compiles and runs on RTEMS without modification. + +The original source was obtained from: + ftp://ftp.FreeBSD.org/pub/FreeBSD/ + branches/4.0-stable/src/lib/libc/rpc + branches/4.0-stable/src/lib/libc/xdr + branches/4.0-stable/src/include/rpc + branches/4.0-stable/src/include/rpcsvc diff --git a/c/src/librpc/include/rpc/rpc.h b/c/src/librpc/include/rpc/rpc.h index 512a349ebf..f68dc1be89 100644 --- a/c/src/librpc/include/rpc/rpc.h +++ b/c/src/librpc/include/rpc/rpc.h @@ -91,4 +91,47 @@ extern int bindresvport_sa __P((int, struct sockaddr *)); extern int get_myaddress __P((struct sockaddr_in *)); __END_DECLS +int rtems_rpc_task_init (void); +int rtems_rpc_start_portmapper (int priority); + +#ifdef _RTEMS_RPC_INTERNAL_ +/* + * Multi-threaded support + * Group all global and static variables into a single spot. + * This area will be allocated on a per-task basis + */ +struct rtems_rpc_task_variables { + int svc_svc_maxfd; + fd_set svc_svc_fdset; + void *svc_xports; + int svc_xportssize; + int svc__svc_fdsetsize; + void *svc__svc_fdset; + void *svc_svc_head; + + void *clnt_perror_buf; + + void *clnt_raw_private; + + void *call_rpc_private; + + void *svc_raw_private; + + void *svc_simple_proglst; + void *svc_simple_pl; + void *svc_simple_transp; + + void *rpcdname_default_domain; + + void *svc_auths_Auths; +}; +extern void *rtems_rpc_task_variables; + +#define svc_maxfd (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_svc_maxfd) +#define svc_fdset (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_svc_fdset) +#define __svc_fdsetsize (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc__svc_fdsetsize) +#define __svc_fdset (fd_set *)(((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc__svc_fdset) + +#endif /* _RTEMS_RPC_INTERNAL_ */ + #endif /* !_RPC_RPC_H */ diff --git a/c/src/librpc/src/rpc/Makefile.am b/c/src/librpc/src/rpc/Makefile.am index 21ea585c87..1c7542fb1b 100644 --- a/c/src/librpc/src/rpc/Makefile.am +++ b/c/src/librpc/src/rpc/Makefile.am @@ -15,7 +15,7 @@ C_FILES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_prot2.c \ pmap_rmt.c rpc_callmsg.c rpc_commondata.c rpc_dtablesize.c rpc_prot.c \ rpcdname.c rtime.c svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_run.c \ - svc_simple.c svc_tcp.c svc_udp.c + svc_simple.c svc_tcp.c svc_udp.c rtems_portmapper.c rtems_rpc.c UNUSED_C_FILES = auth_des.c auth_time.c authdes_prot.c clnt_unix.c \ crypt_client.c des_crypt.c des_soft.c getpublickey.c key_call.c \ key_prot_xdr.c svc_auth_des.c svc_unix.c @@ -33,7 +33,7 @@ TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a # Add local stuff here using += # -AM_CPPFLAGS += '-D__P(x)=x' -D_read=read -D_write=write -D_close=close +AM_CPPFLAGS += '-D__P(x)=x' -D_read=read -D_write=write -D_close=close -D_RTEMS_RPC_INTERNAL_ $(LIB): $(OBJS) $(make-library) diff --git a/c/src/librpc/src/rpc/clnt_generic.c b/c/src/librpc/src/rpc/clnt_generic.c index 1a3b1c3639..b5c2c80579 100644 --- a/c/src/librpc/src/rpc/clnt_generic.c +++ b/c/src/librpc/src/rpc/clnt_generic.c @@ -59,9 +59,10 @@ clnt_create(hostname, prog, vers, proto) struct sockaddr_in sin; struct sockaddr_un sun; int sock; - static struct timeval tv; + struct timeval tv; CLIENT *client; +#ifndef __rtems__ if (!strcmp(proto, "unix")) { bzero((char *)&sun, sizeof(sun)); sun.sun_family = AF_UNIX; @@ -77,6 +78,7 @@ clnt_create(hostname, prog, vers, proto) clnt_control(client, CLSET_TIMEOUT, &tv); return(client); } +#endif h = gethostbyname(hostname); if (h == NULL) { diff --git a/c/src/librpc/src/rpc/clnt_perror.c b/c/src/librpc/src/rpc/clnt_perror.c index 1c90c7ae00..720583ba54 100644 --- a/c/src/librpc/src/rpc/clnt_perror.c +++ b/c/src/librpc/src/rpc/clnt_perror.c @@ -50,7 +50,7 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_perror.c,v 1.11 1999/08/28 static char *auth_errmsg(); #define CLNT_PERROR_BUFLEN 256 -static char *buf; +#define buf ((char *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->clnt_perror_buf) static char * _buf() diff --git a/c/src/librpc/src/rpc/clnt_raw.c b/c/src/librpc/src/rpc/clnt_raw.c index ae935b117d..a343c49068 100644 --- a/c/src/librpc/src/rpc/clnt_raw.c +++ b/c/src/librpc/src/rpc/clnt_raw.c @@ -53,13 +53,14 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_raw.c,v 1.10 1999/08/28 00 /* * This is the "network" we will be moving stuff over. */ -static struct clntraw_private { +struct clnt_raw_private { CLIENT client_object; XDR xdr_stream; char _raw_buf[UDPMSGSIZE]; char mashl_callmsg[MCALL_MSG_SIZE]; u_int mcnt; -} *clntraw_private; +}; +#define clntraw_private ((struct clnt_raw_private *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->clnt_raw_private) static enum clnt_stat clntraw_call(); static void clntraw_abort(); @@ -87,13 +88,13 @@ clntraw_create(prog, vers) u_long prog; u_long vers; { - register struct clntraw_private *clp = clntraw_private; + register struct clnt_raw_private *clp = clntraw_private; struct rpc_msg call_msg; XDR *xdrs = &clp->xdr_stream; CLIENT *client = &clp->client_object; if (clp == 0) { - clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); + clp = (struct clnt_raw_private *)calloc(1, sizeof (*clp)); if (clp == 0) return (0); clntraw_private = clp; @@ -135,7 +136,7 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) caddr_t resultsp; struct timeval timeout; { - register struct clntraw_private *clp = clntraw_private; + register struct clnt_raw_private *clp = clntraw_private; register XDR *xdrs = &clp->xdr_stream; struct rpc_msg msg; enum clnt_stat status; @@ -212,7 +213,7 @@ clntraw_freeres(cl, xdr_res, res_ptr) xdrproc_t xdr_res; caddr_t res_ptr; { - register struct clntraw_private *clp = clntraw_private; + register struct clnt_raw_private *clp = clntraw_private; register XDR *xdrs = &clp->xdr_stream; bool_t rval; diff --git a/c/src/librpc/src/rpc/clnt_simple.c b/c/src/librpc/src/rpc/clnt_simple.c index d29cad5a1c..e8f92bc657 100644 --- a/c/src/librpc/src/rpc/clnt_simple.c +++ b/c/src/librpc/src/rpc/clnt_simple.c @@ -49,12 +49,13 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_simple.c,v 1.12 2000/01/27 #include <sys/socket.h> #include <netdb.h> -static struct callrpc_private { +struct call_rpc_private { CLIENT *client; int socket; int oldprognum, oldversnum, valid; char *oldhost; -} *callrpc_private; +}; +#define callrpc_private ((struct call_rpc_private *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->call_rpc_private) int callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) @@ -63,14 +64,14 @@ callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) xdrproc_t inproc, outproc; char *in, *out; { - register struct callrpc_private *crp = callrpc_private; + register struct call_rpc_private *crp = callrpc_private; struct sockaddr_in server_addr; enum clnt_stat clnt_stat; struct hostent *hp; struct timeval timeout, tottimeout; if (crp == 0) { - crp = (struct callrpc_private *)calloc(1, sizeof (*crp)); + crp = (struct call_rpc_private *)calloc(1, sizeof (*crp)); if (crp == 0) return (0); callrpc_private = crp; diff --git a/c/src/librpc/src/rpc/rpc_commondata.c b/c/src/librpc/src/rpc/rpc_commondata.c index 068a32837c..bbe6003337 100644 --- a/c/src/librpc/src/rpc/rpc_commondata.c +++ b/c/src/librpc/src/rpc/rpc_commondata.c @@ -38,6 +38,4 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_commondata.c,v 1.7 1999/08/ * by public interfaces */ struct opaque_auth _null_auth; -fd_set svc_fdset; -int svc_maxfd = -1; struct rpc_createerr rpc_createerr; diff --git a/c/src/librpc/src/rpc/rpcdname.c b/c/src/librpc/src/rpc/rpcdname.c index f28b4fda9b..39f7167bcd 100644 --- a/c/src/librpc/src/rpc/rpcdname.c +++ b/c/src/librpc/src/rpc/rpcdname.c @@ -39,8 +39,9 @@ static char sccsid[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro"; #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <rpc/rpc.h> -static char *default_domain = 0; +#define default_domain ((char *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->rpcdname_default_domain) static char * get_default_domain() diff --git a/c/src/librpc/src/rpc/rtems_portmapper.c b/c/src/librpc/src/rpc/rtems_portmapper.c index e69de29bb2..31fe8b7ff4 100644 --- a/c/src/librpc/src/rpc/rtems_portmapper.c +++ b/c/src/librpc/src/rpc/rtems_portmapper.c @@ -0,0 +1,485 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <stdio.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/wait.h> +#include <sys/signal.h> + +int reg_service(); +static struct pmaplist *pmaplist; +static int debugging = 0; + +#include <rtems.h> +#define fork() (-1) + + +static rtems_task rtems_portmapper (rtems_task_argument unused) +{ + SVCXPRT *xprt; + int sock, pid, t; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + register struct pmaplist *pml; + + rtems_rpc_task_init (); + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("portmap cannot create socket"); + rtems_task_delete (RTEMS_SELF); + } + + addr.sin_addr.s_addr = 0; + addr.sin_family = AF_INET; + addr.sin_port = htons(PMAPPORT); + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + perror("portmap cannot bind"); + close (sock); + rtems_task_delete (RTEMS_SELF); + } + + if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) { + fprintf(stderr, "couldn't do udp_create\n"); + close (sock); + rtems_task_delete (RTEMS_SELF); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_next = 0; + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_UDP; + pml->pml_map.pm_port = PMAPPORT; + pmaplist = pml; + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("portmap cannot create socket"); + close (sock); + rtems_task_delete (RTEMS_SELF); + } + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + perror("portmap cannot bind"); + close (sock); + rtems_task_delete (RTEMS_SELF); + } + if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE)) + == (SVCXPRT *)NULL) { + fprintf(stderr, "couldn't do tcp_create\n"); + close (sock); + rtems_task_delete (RTEMS_SELF); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_TCP; + pml->pml_map.pm_port = PMAPPORT; + pml->pml_next = pmaplist; + pmaplist = pml; + + (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); + + svc_run(); + fprintf(stderr, "run_svc returned unexpectedly\n"); + close (sock); + rtems_task_delete (RTEMS_SELF); +} + +static struct pmaplist * +find_service(prog, vers, prot) +u_long prog; +u_long vers; +{ +register struct pmaplist *hit = NULL; +register struct pmaplist *pml; + +for (pml = pmaplist; pml != NULL; pml = pml->pml_next) { + if ((pml->pml_map.pm_prog != prog) || + (pml->pml_map.pm_prot != prot)) + continue; + hit = pml; + if (pml->pml_map.pm_vers == vers) + break; +} + return (hit); +} + +/* + * 1 OK, 0 not + */ +static reg_service(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct pmap reg; + struct pmaplist *pml, *prevpml, *fnd; + int ans, port; + caddr_t t; + +#ifdef DEBUG + fprintf(stderr, "server: about do a switch\n"); +#endif + switch (rqstp->rq_proc) { + + case PMAPPROC_NULL: + /* + * Null proc call + */ + if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) { + abort(); + } + break; + + case PMAPPROC_SET: + /* + * Set a program,version to port mapping + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + /* + * check to see if already used + * find_service returns a hit even if + * the versions don't match, so check for it + */ + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) { + if (fnd->pml_map.pm_port == reg.pm_port) { + ans = 1; + goto done; + } + else { + ans = 0; + goto done; + } + } else { + /* + * add to END of list + */ + pml = (struct pmaplist *) + malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map = reg; + pml->pml_next = 0; + if (pmaplist == 0) { + pmaplist = pml; + } else { + for (fnd= pmaplist; fnd->pml_next != 0; + fnd = fnd->pml_next); + fnd->pml_next = pml; + } + ans = 1; + } + done: + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_UNSET: + /* + * Remove a program,version to port mapping. + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + ans = 0; + for (prevpml = NULL, pml = pmaplist; pml != NULL; ) { + if ((pml->pml_map.pm_prog != reg.pm_prog) || + (pml->pml_map.pm_vers != reg.pm_vers)) { + /* both pml & prevpml move forwards */ + prevpml = pml; + pml = pml->pml_next; + continue; + } + /* found it; pml moves forward, prevpml stays */ + ans = 1; + t = (caddr_t)pml; + pml = pml->pml_next; + if (prevpml == NULL) + pmaplist = pml; + else + prevpml->pml_next = pml; + free(t); + } + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_GETPORT: + /* + * Lookup the mapping for a program,version and return its port + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd) + port = fnd->pml_map.pm_port; + else + port = 0; + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_DUMP: + /* + * Return the current set of mapped program,version + */ + if (!svc_getargs(xprt, xdr_void, NULL)) + svcerr_decode(xprt); + else { + if ((!svc_sendreply(xprt, xdr_pmaplist, + (caddr_t)&pmaplist)) && debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_CALLIT: + /* + * Calls a procedure on the local machine. If the requested + * procedure is not registered this procedure does not return + * error information!! + * This procedure is only supported on rpc/udp and calls via + * rpc/udp. It passes null authentication parameters. + */ + callit(rqstp, xprt); + break; + + default: + svcerr_noproc(xprt); + break; + } +} + + +/* + * Stuff for the rmtcall service + */ +#define ARGSIZE 9000 + +typedef struct encap_parms { + u_long arglen; + char *args; +}; + +static bool_t +xdr_encap_parms(xdrs, epp) + XDR *xdrs; + struct encap_parms *epp; +{ + + return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE)); +} + +typedef struct rmtcallargs { + u_long rmt_prog; + u_long rmt_vers; + u_long rmt_port; + u_long rmt_proc; + struct encap_parms rmt_args; +}; + +static bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + + /* does not get a port number */ + if (xdr_u_long(xdrs, &(cap->rmt_prog)) && + xdr_u_long(xdrs, &(cap->rmt_vers)) && + xdr_u_long(xdrs, &(cap->rmt_proc))) { + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + } + return (FALSE); +} + +static bool_t +xdr_rmtcall_result(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + if (xdr_u_long(xdrs, &(cap->rmt_port))) + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + return (FALSE); +} + +/* + * only worries about the struct encap_parms part of struct rmtcallargs. + * The arglen must already be set!! + */ +static bool_t +xdr_opaque_parms(xdrs, cap) + XDR *xdrs; + struct rmtcallargs *cap; +{ + + return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen)); +} + +/* + * This routine finds and sets the length of incoming opaque paraters + * and then calls xdr_opaque_parms. + */ +static bool_t +xdr_len_opaque_parms(xdrs, cap) + register XDR *xdrs; + struct rmtcallargs *cap; +{ + register u_int beginpos, lowpos, highpos, currpos, pos; + + beginpos = lowpos = pos = xdr_getpos(xdrs); + highpos = lowpos + ARGSIZE; + while ((int)(highpos - lowpos) >= 0) { + currpos = (lowpos + highpos) / 2; + if (xdr_setpos(xdrs, currpos)) { + pos = currpos; + lowpos = currpos + 1; + } else { + highpos = currpos - 1; + } + } + xdr_setpos(xdrs, beginpos); + cap->rmt_args.arglen = pos - beginpos; + return (xdr_opaque_parms(xdrs, cap)); +} + +/* + * Call a remote procedure service + * This procedure is very quiet when things go wrong. + * The proc is written to support broadcast rpc. In the broadcast case, + * a machine should shut-up instead of complain, less the requestor be + * overrun with complaints at the expense of not hearing a valid reply ... + * + * This now forks so that the program & process that it calls can call + * back to the portmapper. + */ +static +callit(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct rmtcallargs a; + struct pmaplist *pml; + u_short port; + struct sockaddr_in me; + int pid, socket = -1; + CLIENT *client; + struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred; + struct timeval timeout; + char buf[ARGSIZE]; + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + a.rmt_args.args = buf; + if (!svc_getargs(xprt, xdr_rmtcall_args, &a)) + return; + if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL) + return; + /* + * fork a child to do the work. Parent immediately returns. + * Child exits upon completion. + */ + if ((pid = fork()) != 0) { + if (debugging && (pid < 0)) { + fprintf(stderr, "portmap CALLIT: cannot fork.\n"); + } + return; + } + port = pml->pml_map.pm_port; + get_myaddress(&me); + me.sin_port = htons(port); + client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket); + if (client != (CLIENT *)NULL) { + if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) { + client->cl_auth = authunix_create(au->aup_machname, + au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids); + } + a.rmt_port = (u_long)port; + if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a, + xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) { + svc_sendreply(xprt, xdr_rmtcall_result, &a); + } + AUTH_DESTROY(client->cl_auth); + clnt_destroy(client); + } + (void)close(socket); + exit(0); +} + +/* + * Start the RPC portmapper + */ +int rtems_rpc_start_portmapper (int priority) +{ + rtems_mode mode; + rtems_status_code sc; + rtems_id tid; + static int started; + + rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode); + if (started) { + rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); + return RTEMS_SUCCESSFUL; + } + sc = rtems_task_create (rtems_build_name('P', 'M', 'A', 'P'), + priority, + 8000, + RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), + RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, + &tid); + if (sc != RTEMS_SUCCESSFUL) { + rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); + return sc; + } + sc = rtems_task_start (tid, rtems_portmapper, 0); + if (sc != RTEMS_SUCCESSFUL) { + rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); + return sc; + } + started = 1; + rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode); + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/librpc/src/rpc/rtems_rpc.c b/c/src/librpc/src/rpc/rtems_rpc.c index e69de29bb2..d2666e2f91 100644 --- a/c/src/librpc/src/rpc/rtems_rpc.c +++ b/c/src/librpc/src/rpc/rtems_rpc.c @@ -0,0 +1,56 @@ +/* + * RTEMS multi-tasking support + */ + +#include <rpc/rpc.h> +#include <rtems.h> +#include <stdlib.h> + +/* + * RPC variables for single-thread + */ +static struct rtems_rpc_task_variables rpc_default = { + -1, /* svc_maxfd */ +}; + +/* + * RPC values for initializing a new per-task set of variables + */ +static const struct rtems_rpc_task_variables rpc_init = { + -1, /* svc_maxfd */ +}; + +/* + * Per-task pointer to RPC data + */ +void *rtems_rpc_task_variables = &rpc_default; + +/* + * Set up per-task RPC variables + */ +int rtems_rpc_task_init (void) +{ + rtems_status_code sc; + struct rtems_rpc_task_variables *tvp; + + if (rtems_rpc_task_variables == &rpc_default) { + tvp = malloc (sizeof *tvp); + if (tvp == NULL) + return RTEMS_NO_MEMORY; + /* + * FIXME: Should have destructor which cleans up + * all RPC stuff: + * - Close all files + * - Go through and free linked list elements + * - Free other allocated memory (e.g. clnt_perror_buf) + */ + sc = rtems_task_variable_add (RTEMS_SELF, &rtems_rpc_task_variables, NULL); + if (sc != RTEMS_SUCCESSFUL) { + free (tvp); + return sc; + } + *tvp = rpc_init; + rtems_rpc_task_variables = tvp; + } + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/librpc/src/rpc/svc.c b/c/src/librpc/src/rpc/svc.c index 5d7212f175..92832a589b 100644 --- a/c/src/librpc/src/rpc/svc.c +++ b/c/src/librpc/src/rpc/svc.c @@ -49,8 +49,8 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc.c,v 1.14 1999/08/28 00:00:4 #include <rpc/rpc.h> #include <rpc/pmap_clnt.h> -static SVCXPRT **xports; -static int xportssize; +#define xports ((SVCXPRT **)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xports) +#define xportssize (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xportssize) #define NULL_SVC ((struct svc_callout *)0) #define RQCRED_SIZE 400 /* this size is excessive */ @@ -63,18 +63,16 @@ static int xportssize; * The dispatch routine takes request structs and runs the * apropriate procedure. */ -static struct svc_callout { +struct svc_callout { struct svc_callout *sc_next; u_long sc_prog; u_long sc_vers; void (*sc_dispatch)(); -} *svc_head; +}; +#define svc_head (struct svc_callout *)(((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_svc_head) static struct svc_callout *svc_find(); -int __svc_fdsetsize = 0; -fd_set *__svc_fdset = NULL; - /* *************** SVCXPRT related stuff **************** */ /* @@ -87,18 +85,17 @@ xprt_register(xprt) register int sock = xprt->xp_sock; if (sock + 1 > __svc_fdsetsize) { - int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); + int bytes = sizeof (fd_set); fd_set *fds; fds = (fd_set *)malloc(bytes); memset(fds, 0, bytes); if (__svc_fdset) { - memcpy(fds, __svc_fdset, howmany(__svc_fdsetsize, - NFDBITS) * sizeof(fd_mask)); + memcpy(fds, __svc_fdset, bytes); free(__svc_fdset); } __svc_fdset = fds; - __svc_fdsetsize = howmany(sock+1, NFDBITS) * NFDBITS; + __svc_fdsetsize = bytes * NBBY; } if (sock < FD_SETSIZE) diff --git a/c/src/librpc/src/rpc/svc_auth.c b/c/src/librpc/src/rpc/svc_auth.c index 83e9b150d9..f95f101f33 100644 --- a/c/src/librpc/src/rpc/svc_auth.c +++ b/c/src/librpc/src/rpc/svc_auth.c @@ -87,7 +87,7 @@ struct authsvc { enum auth_stat (*handler)(); struct authsvc *next; }; -static struct authsvc *Auths = NULL; +#define Auths ((struct authsvc *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_auths_Auths) /* * The call rpc message, msg has been obtained from the wire. The msg contains diff --git a/c/src/librpc/src/rpc/svc_raw.c b/c/src/librpc/src/rpc/svc_raw.c index 91acb17d1b..686c61bdd4 100644 --- a/c/src/librpc/src/rpc/svc_raw.c +++ b/c/src/librpc/src/rpc/svc_raw.c @@ -48,12 +48,13 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_raw.c,v 1.7 1999/08/28 00:0 /* * This is the "network" that we will be moving data over */ -static struct svcraw_private { +struct svc_raw_private { char _raw_buf[UDPMSGSIZE]; SVCXPRT server; XDR xdr_stream; char verf_body[MAX_AUTH_BYTES]; -} *svcraw_private; +}; +#define svcraw_private ((struct svc_raw_private *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_raw_private) static bool_t svcraw_recv(); static enum xprt_stat svcraw_stat(); @@ -74,10 +75,10 @@ static struct xp_ops server_ops = { SVCXPRT * svcraw_create() { - register struct svcraw_private *srp = svcraw_private; + register struct svc_raw_private *srp = svcraw_private; if (srp == 0) { - srp = (struct svcraw_private *)calloc(1, sizeof (*srp)); + srp = (struct svc_raw_private *)calloc(1, sizeof (*srp)); if (srp == 0) return (0); } @@ -101,7 +102,7 @@ svcraw_recv(xprt, msg) SVCXPRT *xprt; struct rpc_msg *msg; { - register struct svcraw_private *srp = svcraw_private; + register struct svc_raw_private *srp = svcraw_private; register XDR *xdrs; if (srp == 0) @@ -119,7 +120,7 @@ svcraw_reply(xprt, msg) SVCXPRT *xprt; struct rpc_msg *msg; { - register struct svcraw_private *srp = svcraw_private; + register struct svc_raw_private *srp = svcraw_private; register XDR *xdrs; if (srp == 0) @@ -139,7 +140,7 @@ svcraw_getargs(xprt, xdr_args, args_ptr) xdrproc_t xdr_args; caddr_t args_ptr; { - register struct svcraw_private *srp = svcraw_private; + register struct svc_raw_private *srp = svcraw_private; if (srp == 0) return (FALSE); @@ -152,7 +153,7 @@ svcraw_freeargs(xprt, xdr_args, args_ptr) xdrproc_t xdr_args; caddr_t args_ptr; { - register struct svcraw_private *srp = svcraw_private; + register struct svc_raw_private *srp = svcraw_private; register XDR *xdrs; if (srp == 0) diff --git a/c/src/librpc/src/rpc/svc_run.c b/c/src/librpc/src/rpc/svc_run.c index 6b546974d4..5e8a9e683a 100644 --- a/c/src/librpc/src/rpc/svc_run.c +++ b/c/src/librpc/src/rpc/svc_run.c @@ -46,9 +46,6 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_run.c,v 1.10 1999/08/28 00: #include <stdlib.h> #include <string.h> -extern int __svc_fdsetsize; -extern fd_set *__svc_fdset; - void svc_run() { @@ -56,8 +53,7 @@ svc_run() for (;;) { if (__svc_fdset) { - int bytes = howmany(__svc_fdsetsize, NFDBITS) * - sizeof(fd_mask); + int bytes = sizeof (fd_set); fds = (fd_set *)malloc(bytes); memcpy(fds, __svc_fdset, bytes); } else diff --git a/c/src/librpc/src/rpc/svc_simple.c b/c/src/librpc/src/rpc/svc_simple.c index 5f2a1d1799..c97247fb79 100644 --- a/c/src/librpc/src/rpc/svc_simple.c +++ b/c/src/librpc/src/rpc/svc_simple.c @@ -48,16 +48,17 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_simple.c,v 1.9 1999/08/28 0 #include <sys/socket.h> #include <netdb.h> -static struct proglst { +struct prog_lst { char *(*p_progname)(); int p_prognum; int p_procnum; xdrproc_t p_inproc, p_outproc; - struct proglst *p_nxt; -} *proglst; + struct prog_lst *p_nxt; +}; static void universal(); -static SVCXPRT *transp; -struct proglst *pl; +#define proglst ((struct prog_lst *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_simple_proglst) +#define pl ((struct prog_lst *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_simple_pl) +#define transp ((SVCXPRT *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_simple_transp) int registerrpc(prognum, versnum, procnum, progname, inproc, outproc) @@ -85,7 +86,7 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc) prognum, versnum); return (-1); } - pl = (struct proglst *)malloc(sizeof(struct proglst)); + pl = (struct prog_lst *)malloc(sizeof(struct prog_lst)); if (pl == NULL) { (void) fprintf(stderr, "registerrpc: out of memory\n"); return (-1); @@ -101,20 +102,20 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc) } static void -universal(rqstp, transp) +universal(rqstp, atransp) struct svc_req *rqstp; - SVCXPRT *transp; + SVCXPRT *atransp; { int prog, proc; char *outdata; char xdrbuf[UDPMSGSIZE]; - struct proglst *pl; + struct prog_lst *lpl; /* * enforce "procnum 0 is echo" convention */ if (rqstp->rq_proc == NULLPROC) { - if (svc_sendreply(transp, xdr_void, NULL) == FALSE) { + if (svc_sendreply(atransp, xdr_void, NULL) == FALSE) { (void) fprintf(stderr, "xxx\n"); exit(1); } @@ -122,26 +123,26 @@ universal(rqstp, transp) } prog = rqstp->rq_prog; proc = rqstp->rq_proc; - for (pl = proglst; pl != NULL; pl = pl->p_nxt) - if (pl->p_prognum == prog && pl->p_procnum == proc) { + for (lpl = proglst; lpl != NULL; lpl = lpl->p_nxt) + if (lpl->p_prognum == prog && lpl->p_procnum == proc) { /* decode arguments into a CLEAN buffer */ memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */ - if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { - svcerr_decode(transp); + if (!svc_getargs(atransp, lpl->p_inproc, xdrbuf)) { + svcerr_decode(atransp); return; } - outdata = (*(pl->p_progname))(xdrbuf); - if (outdata == NULL && pl->p_outproc != xdr_void) + outdata = (*(lpl->p_progname))(xdrbuf); + if (outdata == NULL && lpl->p_outproc != xdr_void) /* there was an error */ return; - if (!svc_sendreply(transp, pl->p_outproc, outdata)) { + if (!svc_sendrelply(atransp, lpl->p_outproc, outdata)) { (void) fprintf(stderr, "trouble replying to prog %d\n", - pl->p_prognum); + lpl->p_prognum); exit(1); } /* free the decoded arguments */ - (void)svc_freeargs(transp, pl->p_inproc, xdrbuf); + (void)svc_freeargs(atransp, lpl->p_inproc, xdrbuf); return; } (void) fprintf(stderr, "never registered prog %d\n", prog); diff --git a/c/src/librpc/src/rpc/svc_tcp.c b/c/src/librpc/src/rpc/svc_tcp.c index a2d07a9a7b..81ae27bead 100644 --- a/c/src/librpc/src/rpc/svc_tcp.c +++ b/c/src/librpc/src/rpc/svc_tcp.c @@ -331,15 +331,12 @@ readtcp(xprt, buf, len) struct timeval start, delta, tv; struct timeval tmp1, tmp2; fd_set *fds; - extern fd_set *__svc_fdset; - extern int __svc_fdsetsize; delta = wait_per_try; fds = NULL; gettimeofday(&start, NULL); do { - int bytes = howmany(__svc_fdsetsize, NFDBITS) * - sizeof(fd_mask); + int bytes = sizeof (fd_set); if (fds != NULL) free(fds); fds = (fd_set *)malloc(bytes); diff --git a/c/src/librpc/src/rpc/svc_unix.c b/c/src/librpc/src/rpc/svc_unix.c index 6e43fedfe9..b0f3175c0e 100644 --- a/c/src/librpc/src/rpc/svc_unix.c +++ b/c/src/librpc/src/rpc/svc_unix.c @@ -373,15 +373,12 @@ readunix(xprt, buf, len) struct timeval start, delta, tv; struct timeval tmp1, tmp2; fd_set *fds; - extern fd_set *__svc_fdset; - extern int __svc_fdsetsize; delta = wait_per_try; fds = NULL; gettimeofday(&start, NULL); do { - int bytes = howmany(__svc_fdsetsize, NFDBITS) * - sizeof(fd_mask); + int bytes = sizeof (fd_set); if (fds != NULL) free(fds); fds = (fd_set *)malloc(bytes); diff --git a/c/src/librpc/src/xdr/Makefile.am b/c/src/librpc/src/xdr/Makefile.am index 4ae8962027..222a4fe3f5 100644 --- a/c/src/librpc/src/xdr/Makefile.am +++ b/c/src/librpc/src/xdr/Makefile.am @@ -24,7 +24,7 @@ TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a # Add local stuff here using += # -AM_CPPFLAGS += -DIEEEFP '-D__P(x)=x' +AM_CPPFLAGS += '-D__P(x)=x' $(LIB): $(OBJS) $(make-library) diff --git a/c/src/librpc/src/xdr/xdr_float.c b/c/src/librpc/src/xdr/xdr_float.c index c46f549d96..b884f539c7 100644 --- a/c/src/librpc/src/xdr/xdr_float.c +++ b/c/src/librpc/src/xdr/xdr_float.c @@ -56,8 +56,7 @@ static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_float.c,v 1.7 1999/08/28 00 #if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ - defined(__arm32__) || defined(__ppc__) -/* #include <FLEEB> */ + defined(__arm32__) || defined(__ppc__) || defined(__m68000__) #include <machine/endian.h> #if !defined(IEEEFP) #define IEEEFP |