summaryrefslogtreecommitdiffstats
path: root/c/src/librpc
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-05-03 14:12:51 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-05-03 14:12:51 +0000
commit9fb78b8039b23d3ec609ae1a73650200fb928623 (patch)
treefe3f8ad0132ed1dc13d21c66816a527e7771b8b8 /c/src/librpc
parentThis commit was manufactured by cvs2svn to create branch 'rtems-4-5-branch'. (diff)
downloadrtems-9fb78b8039b23d3ec609ae1a73650200fb928623.tar.bz2
Update from Eric Norum <eric@cls.usask.ca>.
Diffstat (limited to 'c/src/librpc')
-rw-r--r--c/src/librpc/README_RTEMS51
-rw-r--r--c/src/librpc/include/rpc/rpc.h43
-rw-r--r--c/src/librpc/src/rpc/Makefile.am4
-rw-r--r--c/src/librpc/src/rpc/clnt_generic.c4
-rw-r--r--c/src/librpc/src/rpc/clnt_perror.c2
-rw-r--r--c/src/librpc/src/rpc/clnt_raw.c13
-rw-r--r--c/src/librpc/src/rpc/clnt_simple.c9
-rw-r--r--c/src/librpc/src/rpc/rpc_commondata.c2
-rw-r--r--c/src/librpc/src/rpc/rpcdname.c3
-rw-r--r--c/src/librpc/src/rpc/rtems_portmapper.c485
-rw-r--r--c/src/librpc/src/rpc/rtems_rpc.c56
-rw-r--r--c/src/librpc/src/rpc/svc.c19
-rw-r--r--c/src/librpc/src/rpc/svc_auth.c2
-rw-r--r--c/src/librpc/src/rpc/svc_raw.c17
-rw-r--r--c/src/librpc/src/rpc/svc_run.c6
-rw-r--r--c/src/librpc/src/rpc/svc_simple.c39
-rw-r--r--c/src/librpc/src/rpc/svc_tcp.c5
-rw-r--r--c/src/librpc/src/rpc/svc_unix.c5
-rw-r--r--c/src/librpc/src/xdr/Makefile.am2
-rw-r--r--c/src/librpc/src/xdr/xdr_float.c3
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, &reg))
+ 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, &reg))
+ 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, &reg))
+ 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