Update from Eric Norum <eric@cls.usask.ca>.

This commit is contained in:
Joel Sherrill
2000-05-03 14:12:51 +00:00
parent 45e4cc77c6
commit 9fb78b8039
20 changed files with 692 additions and 78 deletions

View File

@@ -1,14 +1,46 @@
# USING RPC/XDR ON RTEMS
# $Id$ ======================
# 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 Most of the FreeBSD rpc library ports to RTEMS with little
or no modification, but some of the library has not made it into or no modification beyond that required to provide for operation
the RTEMS implementation. FreeBSD source files which have been in a multitasking environment. Multitasking operation was
left out include: 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: - Files which provide RPC to the AF_UNIX address family:
clnt_unix.c clnt_unix.c
svc_unix.c svc_unix.c
An `ifndef __rtems__' was added to clnt_generic.c because clnt_unix.c
was omitted.
- Files which need NIS: - Files which need NIS:
auth_time.c auth_time.c
- Files which provide DES authentication: - Files which provide DES authentication:
@@ -23,3 +55,10 @@ left out include:
svc_auth_des.c svc_auth_des.c
The FreeBSD xdr source compiles and runs on RTEMS without modification. 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

View File

@@ -91,4 +91,47 @@ extern int bindresvport_sa __P((int, struct sockaddr *));
extern int get_myaddress __P((struct sockaddr_in *)); extern int get_myaddress __P((struct sockaddr_in *));
__END_DECLS __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 */ #endif /* !_RPC_RPC_H */

View File

@@ -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_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 \ 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 \ 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 \ 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 \ 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 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 += # 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) $(LIB): $(OBJS)
$(make-library) $(make-library)

View File

@@ -59,9 +59,10 @@ clnt_create(hostname, prog, vers, proto)
struct sockaddr_in sin; struct sockaddr_in sin;
struct sockaddr_un sun; struct sockaddr_un sun;
int sock; int sock;
static struct timeval tv; struct timeval tv;
CLIENT *client; CLIENT *client;
#ifndef __rtems__
if (!strcmp(proto, "unix")) { if (!strcmp(proto, "unix")) {
bzero((char *)&sun, sizeof(sun)); bzero((char *)&sun, sizeof(sun));
sun.sun_family = AF_UNIX; sun.sun_family = AF_UNIX;
@@ -77,6 +78,7 @@ clnt_create(hostname, prog, vers, proto)
clnt_control(client, CLSET_TIMEOUT, &tv); clnt_control(client, CLSET_TIMEOUT, &tv);
return(client); return(client);
} }
#endif
h = gethostbyname(hostname); h = gethostbyname(hostname);
if (h == NULL) { if (h == NULL) {

View File

@@ -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(); static char *auth_errmsg();
#define CLNT_PERROR_BUFLEN 256 #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 * static char *
_buf() _buf()

View File

@@ -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. * This is the "network" we will be moving stuff over.
*/ */
static struct clntraw_private { struct clnt_raw_private {
CLIENT client_object; CLIENT client_object;
XDR xdr_stream; XDR xdr_stream;
char _raw_buf[UDPMSGSIZE]; char _raw_buf[UDPMSGSIZE];
char mashl_callmsg[MCALL_MSG_SIZE]; char mashl_callmsg[MCALL_MSG_SIZE];
u_int mcnt; 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 enum clnt_stat clntraw_call();
static void clntraw_abort(); static void clntraw_abort();
@@ -87,13 +88,13 @@ clntraw_create(prog, vers)
u_long prog; u_long prog;
u_long vers; u_long vers;
{ {
register struct clntraw_private *clp = clntraw_private; register struct clnt_raw_private *clp = clntraw_private;
struct rpc_msg call_msg; struct rpc_msg call_msg;
XDR *xdrs = &clp->xdr_stream; XDR *xdrs = &clp->xdr_stream;
CLIENT *client = &clp->client_object; CLIENT *client = &clp->client_object;
if (clp == 0) { if (clp == 0) {
clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); clp = (struct clnt_raw_private *)calloc(1, sizeof (*clp));
if (clp == 0) if (clp == 0)
return (0); return (0);
clntraw_private = clp; clntraw_private = clp;
@@ -135,7 +136,7 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
caddr_t resultsp; caddr_t resultsp;
struct timeval timeout; struct timeval timeout;
{ {
register struct clntraw_private *clp = clntraw_private; register struct clnt_raw_private *clp = clntraw_private;
register XDR *xdrs = &clp->xdr_stream; register XDR *xdrs = &clp->xdr_stream;
struct rpc_msg msg; struct rpc_msg msg;
enum clnt_stat status; enum clnt_stat status;
@@ -212,7 +213,7 @@ clntraw_freeres(cl, xdr_res, res_ptr)
xdrproc_t xdr_res; xdrproc_t xdr_res;
caddr_t res_ptr; 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; register XDR *xdrs = &clp->xdr_stream;
bool_t rval; bool_t rval;

View File

@@ -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 <sys/socket.h>
#include <netdb.h> #include <netdb.h>
static struct callrpc_private { struct call_rpc_private {
CLIENT *client; CLIENT *client;
int socket; int socket;
int oldprognum, oldversnum, valid; int oldprognum, oldversnum, valid;
char *oldhost; char *oldhost;
} *callrpc_private; };
#define callrpc_private ((struct call_rpc_private *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->call_rpc_private)
int int
callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) 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; xdrproc_t inproc, outproc;
char *in, *out; char *in, *out;
{ {
register struct callrpc_private *crp = callrpc_private; register struct call_rpc_private *crp = callrpc_private;
struct sockaddr_in server_addr; struct sockaddr_in server_addr;
enum clnt_stat clnt_stat; enum clnt_stat clnt_stat;
struct hostent *hp; struct hostent *hp;
struct timeval timeout, tottimeout; struct timeval timeout, tottimeout;
if (crp == 0) { if (crp == 0) {
crp = (struct callrpc_private *)calloc(1, sizeof (*crp)); crp = (struct call_rpc_private *)calloc(1, sizeof (*crp));
if (crp == 0) if (crp == 0)
return (0); return (0);
callrpc_private = crp; callrpc_private = crp;

View File

@@ -38,6 +38,4 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_commondata.c,v 1.7 1999/08/
* by public interfaces * by public interfaces
*/ */
struct opaque_auth _null_auth; struct opaque_auth _null_auth;
fd_set svc_fdset;
int svc_maxfd = -1;
struct rpc_createerr rpc_createerr; struct rpc_createerr rpc_createerr;

View File

@@ -39,8 +39,9 @@ static char sccsid[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro";
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.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 * static char *
get_default_domain() get_default_domain()

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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/rpc.h>
#include <rpc/pmap_clnt.h> #include <rpc/pmap_clnt.h>
static SVCXPRT **xports; #define xports ((SVCXPRT **)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xports)
static int xportssize; #define xportssize (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xportssize)
#define NULL_SVC ((struct svc_callout *)0) #define NULL_SVC ((struct svc_callout *)0)
#define RQCRED_SIZE 400 /* this size is excessive */ #define RQCRED_SIZE 400 /* this size is excessive */
@@ -63,18 +63,16 @@ static int xportssize;
* The dispatch routine takes request structs and runs the * The dispatch routine takes request structs and runs the
* apropriate procedure. * apropriate procedure.
*/ */
static struct svc_callout { struct svc_callout {
struct svc_callout *sc_next; struct svc_callout *sc_next;
u_long sc_prog; u_long sc_prog;
u_long sc_vers; u_long sc_vers;
void (*sc_dispatch)(); 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(); static struct svc_callout *svc_find();
int __svc_fdsetsize = 0;
fd_set *__svc_fdset = NULL;
/* *************** SVCXPRT related stuff **************** */ /* *************** SVCXPRT related stuff **************** */
/* /*
@@ -87,18 +85,17 @@ xprt_register(xprt)
register int sock = xprt->xp_sock; register int sock = xprt->xp_sock;
if (sock + 1 > __svc_fdsetsize) { if (sock + 1 > __svc_fdsetsize) {
int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); int bytes = sizeof (fd_set);
fd_set *fds; fd_set *fds;
fds = (fd_set *)malloc(bytes); fds = (fd_set *)malloc(bytes);
memset(fds, 0, bytes); memset(fds, 0, bytes);
if (__svc_fdset) { if (__svc_fdset) {
memcpy(fds, __svc_fdset, howmany(__svc_fdsetsize, memcpy(fds, __svc_fdset, bytes);
NFDBITS) * sizeof(fd_mask));
free(__svc_fdset); free(__svc_fdset);
} }
__svc_fdset = fds; __svc_fdset = fds;
__svc_fdsetsize = howmany(sock+1, NFDBITS) * NFDBITS; __svc_fdsetsize = bytes * NBBY;
} }
if (sock < FD_SETSIZE) if (sock < FD_SETSIZE)

View File

@@ -87,7 +87,7 @@ struct authsvc {
enum auth_stat (*handler)(); enum auth_stat (*handler)();
struct authsvc *next; 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 * The call rpc message, msg has been obtained from the wire. The msg contains

View File

@@ -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 * This is the "network" that we will be moving data over
*/ */
static struct svcraw_private { struct svc_raw_private {
char _raw_buf[UDPMSGSIZE]; char _raw_buf[UDPMSGSIZE];
SVCXPRT server; SVCXPRT server;
XDR xdr_stream; XDR xdr_stream;
char verf_body[MAX_AUTH_BYTES]; 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 bool_t svcraw_recv();
static enum xprt_stat svcraw_stat(); static enum xprt_stat svcraw_stat();
@@ -74,10 +75,10 @@ static struct xp_ops server_ops = {
SVCXPRT * SVCXPRT *
svcraw_create() svcraw_create()
{ {
register struct svcraw_private *srp = svcraw_private; register struct svc_raw_private *srp = svcraw_private;
if (srp == 0) { if (srp == 0) {
srp = (struct svcraw_private *)calloc(1, sizeof (*srp)); srp = (struct svc_raw_private *)calloc(1, sizeof (*srp));
if (srp == 0) if (srp == 0)
return (0); return (0);
} }
@@ -101,7 +102,7 @@ svcraw_recv(xprt, msg)
SVCXPRT *xprt; SVCXPRT *xprt;
struct rpc_msg *msg; struct rpc_msg *msg;
{ {
register struct svcraw_private *srp = svcraw_private; register struct svc_raw_private *srp = svcraw_private;
register XDR *xdrs; register XDR *xdrs;
if (srp == 0) if (srp == 0)
@@ -119,7 +120,7 @@ svcraw_reply(xprt, msg)
SVCXPRT *xprt; SVCXPRT *xprt;
struct rpc_msg *msg; struct rpc_msg *msg;
{ {
register struct svcraw_private *srp = svcraw_private; register struct svc_raw_private *srp = svcraw_private;
register XDR *xdrs; register XDR *xdrs;
if (srp == 0) if (srp == 0)
@@ -139,7 +140,7 @@ svcraw_getargs(xprt, xdr_args, args_ptr)
xdrproc_t xdr_args; xdrproc_t xdr_args;
caddr_t args_ptr; caddr_t args_ptr;
{ {
register struct svcraw_private *srp = svcraw_private; register struct svc_raw_private *srp = svcraw_private;
if (srp == 0) if (srp == 0)
return (FALSE); return (FALSE);
@@ -152,7 +153,7 @@ svcraw_freeargs(xprt, xdr_args, args_ptr)
xdrproc_t xdr_args; xdrproc_t xdr_args;
caddr_t args_ptr; caddr_t args_ptr;
{ {
register struct svcraw_private *srp = svcraw_private; register struct svc_raw_private *srp = svcraw_private;
register XDR *xdrs; register XDR *xdrs;
if (srp == 0) if (srp == 0)

View File

@@ -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 <stdlib.h>
#include <string.h> #include <string.h>
extern int __svc_fdsetsize;
extern fd_set *__svc_fdset;
void void
svc_run() svc_run()
{ {
@@ -56,8 +53,7 @@ svc_run()
for (;;) { for (;;) {
if (__svc_fdset) { if (__svc_fdset) {
int bytes = howmany(__svc_fdsetsize, NFDBITS) * int bytes = sizeof (fd_set);
sizeof(fd_mask);
fds = (fd_set *)malloc(bytes); fds = (fd_set *)malloc(bytes);
memcpy(fds, __svc_fdset, bytes); memcpy(fds, __svc_fdset, bytes);
} else } else

View File

@@ -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 <sys/socket.h>
#include <netdb.h> #include <netdb.h>
static struct proglst { struct prog_lst {
char *(*p_progname)(); char *(*p_progname)();
int p_prognum; int p_prognum;
int p_procnum; int p_procnum;
xdrproc_t p_inproc, p_outproc; xdrproc_t p_inproc, p_outproc;
struct proglst *p_nxt; struct prog_lst *p_nxt;
} *proglst; };
static void universal(); static void universal();
static SVCXPRT *transp; #define proglst ((struct prog_lst *)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_simple_proglst)
struct proglst *pl; #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 int
registerrpc(prognum, versnum, procnum, progname, inproc, outproc) registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
@@ -85,7 +86,7 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
prognum, versnum); prognum, versnum);
return (-1); return (-1);
} }
pl = (struct proglst *)malloc(sizeof(struct proglst)); pl = (struct prog_lst *)malloc(sizeof(struct prog_lst));
if (pl == NULL) { if (pl == NULL) {
(void) fprintf(stderr, "registerrpc: out of memory\n"); (void) fprintf(stderr, "registerrpc: out of memory\n");
return (-1); return (-1);
@@ -101,20 +102,20 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
} }
static void static void
universal(rqstp, transp) universal(rqstp, atransp)
struct svc_req *rqstp; struct svc_req *rqstp;
SVCXPRT *transp; SVCXPRT *atransp;
{ {
int prog, proc; int prog, proc;
char *outdata; char *outdata;
char xdrbuf[UDPMSGSIZE]; char xdrbuf[UDPMSGSIZE];
struct proglst *pl; struct prog_lst *lpl;
/* /*
* enforce "procnum 0 is echo" convention * enforce "procnum 0 is echo" convention
*/ */
if (rqstp->rq_proc == NULLPROC) { 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"); (void) fprintf(stderr, "xxx\n");
exit(1); exit(1);
} }
@@ -122,26 +123,26 @@ universal(rqstp, transp)
} }
prog = rqstp->rq_prog; prog = rqstp->rq_prog;
proc = rqstp->rq_proc; proc = rqstp->rq_proc;
for (pl = proglst; pl != NULL; pl = pl->p_nxt) for (lpl = proglst; lpl != NULL; lpl = lpl->p_nxt)
if (pl->p_prognum == prog && pl->p_procnum == proc) { if (lpl->p_prognum == prog && lpl->p_procnum == proc) {
/* decode arguments into a CLEAN buffer */ /* decode arguments into a CLEAN buffer */
memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */ memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */
if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { if (!svc_getargs(atransp, lpl->p_inproc, xdrbuf)) {
svcerr_decode(transp); svcerr_decode(atransp);
return; return;
} }
outdata = (*(pl->p_progname))(xdrbuf); outdata = (*(lpl->p_progname))(xdrbuf);
if (outdata == NULL && pl->p_outproc != xdr_void) if (outdata == NULL && lpl->p_outproc != xdr_void)
/* there was an error */ /* there was an error */
return; return;
if (!svc_sendreply(transp, pl->p_outproc, outdata)) { if (!svc_sendrelply(atransp, lpl->p_outproc, outdata)) {
(void) fprintf(stderr, (void) fprintf(stderr,
"trouble replying to prog %d\n", "trouble replying to prog %d\n",
pl->p_prognum); lpl->p_prognum);
exit(1); exit(1);
} }
/* free the decoded arguments */ /* free the decoded arguments */
(void)svc_freeargs(transp, pl->p_inproc, xdrbuf); (void)svc_freeargs(atransp, lpl->p_inproc, xdrbuf);
return; return;
} }
(void) fprintf(stderr, "never registered prog %d\n", prog); (void) fprintf(stderr, "never registered prog %d\n", prog);

View File

@@ -331,15 +331,12 @@ readtcp(xprt, buf, len)
struct timeval start, delta, tv; struct timeval start, delta, tv;
struct timeval tmp1, tmp2; struct timeval tmp1, tmp2;
fd_set *fds; fd_set *fds;
extern fd_set *__svc_fdset;
extern int __svc_fdsetsize;
delta = wait_per_try; delta = wait_per_try;
fds = NULL; fds = NULL;
gettimeofday(&start, NULL); gettimeofday(&start, NULL);
do { do {
int bytes = howmany(__svc_fdsetsize, NFDBITS) * int bytes = sizeof (fd_set);
sizeof(fd_mask);
if (fds != NULL) if (fds != NULL)
free(fds); free(fds);
fds = (fd_set *)malloc(bytes); fds = (fd_set *)malloc(bytes);

View File

@@ -373,15 +373,12 @@ readunix(xprt, buf, len)
struct timeval start, delta, tv; struct timeval start, delta, tv;
struct timeval tmp1, tmp2; struct timeval tmp1, tmp2;
fd_set *fds; fd_set *fds;
extern fd_set *__svc_fdset;
extern int __svc_fdsetsize;
delta = wait_per_try; delta = wait_per_try;
fds = NULL; fds = NULL;
gettimeofday(&start, NULL); gettimeofday(&start, NULL);
do { do {
int bytes = howmany(__svc_fdsetsize, NFDBITS) * int bytes = sizeof (fd_set);
sizeof(fd_mask);
if (fds != NULL) if (fds != NULL)
free(fds); free(fds);
fds = (fd_set *)malloc(bytes); fds = (fd_set *)malloc(bytes);

View File

@@ -24,7 +24,7 @@ TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a
# Add local stuff here using += # Add local stuff here using +=
# #
AM_CPPFLAGS += -DIEEEFP '-D__P(x)=x' AM_CPPFLAGS += '-D__P(x)=x'
$(LIB): $(OBJS) $(LIB): $(OBJS)
$(make-library) $(make-library)

View File

@@ -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__) || \ #if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
defined(__arm32__) || defined(__ppc__) defined(__arm32__) || defined(__ppc__) || defined(__m68000__)
/* #include <FLEEB> */
#include <machine/endian.h> #include <machine/endian.h>
#if !defined(IEEEFP) #if !defined(IEEEFP)
#define IEEEFP #define IEEEFP