sources-request@mirror.UUCP (08/06/86)
Submitted by: cca!SUN.COM!marks (Mark Stein) Mod.sources: Volume 6, Issue 92 Archive-name: rpc2/Part04 [ All I did was verify that the shar files unpacked correctly. --r$ ] Sun RPC source (part 4 of 11). This software package contains code and documentation for Revision 3.0 of the Sun Remote Procedure Call library. In addition, a beta version of the XDR/RPC protocol compiler is included. Comments about this latest release may be mailed to sun!rpc or rpc@sun.com. 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. - - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - - #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # rpc/doc/rpc.prog.p2 # rpc/doc/xdr.spec.p2 # This archive created: Mon Jul 14 16:55:08 1986 export PATH; PATH=/bin:/usr/bin:$PATH for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test do if test ! -d $d then echo "shar: Making directory $d" mkdir $d chmod 755 $d fi done echo shar: "extracting 'rpc/doc/rpc.prog.p2'" '(33027 characters)' if test -f 'rpc/doc/rpc.prog.p2' then echo shar: "will not over-write existing file 'rpc/doc/rpc.prog.p2'" else sed 's/^X//' << \SHAR_EOF > 'rpc/doc/rpc.prog.p2' X.LP XIn order to do an RPC callback, Xyou need a program number to make the RPC call on. XSince this will be a dynamically generated program number, Xit should be in the transient range, 0x40000000 - 0x5fffffff. XThe routine X.LW gettransient() Xreturns a valid program number in the transient range, Xand registers it with the portmapper. XIt only talks to the portmapper running on the same machine as the X.LW gettransient() Xroutine itself. XThe call to X.LW pmap_set() Xis a test and set operation, Xin that it indivisibly tests whether a program number Xhas already been registered, Xand if it has not, then reserves it. XOn return, the X.LW sockp Xargument will contain a socket that can be used Xas the argument to an X.LW svcudp_create() Xor X.LW svctcp_create() Xcall. X.BS X.LS no X#include <stdio.h> X#include <rpc/rpc.h> X#include <sys/socket.h> X.sp.5 Xgettransient(proto, vers, sockp) X int proto, vers, *sockp; X{ X static int prognum = 0x40000000; X int s, len, socktype; X struct sockaddr_in addr; X.sp.5 X switch(proto) { X case IPPROTO_UDP: X socktype = SOCK_DGRAM; X break; X case IPPROTO_TCP: X socktype = SOCK_STREAM; X break; X default: X fprintf(stderr, "unknown protocol type\en"); X return 0; X } X if (*sockp == RPC_ANYSOCK) { X if ((s = socket(AF_INET, socktype, 0)) < 0) { X perror("socket"); X return (0); X } X *sockp = s; X } X else X s = *sockp; X addr.sin_addr.s_addr = 0; X addr.sin_family = AF_INET; X addr.sin_port = 0; X len = sizeof(addr); X /* X * may be already bound, so don't check for error X */ X bind(s, &addr, len); X if (getsockname(s, &addr, &len)< 0) { X perror("getsockname"); X return (0); X } X while (!pmap_set(prognum++, vers, proto, addr.sin_port)) X continue; X return (prognum-1); X} X.Lf X.BE XThe following pair of programs illustrate how to use the X.LW gettransient() Xroutine. XThe client makes an RPC call to the server, Xpassing it a transient program number. XThen the client waits around to receive a callback Xfrom the server at that program number. XThe server registers the program X.LW EXAMPLEPROG , Xso that it can receive the RPC call Xinforming it of the callback program number. XThen at some random time (on receiving an X.LW ALRM Xsignal in this example), it sends a callback RPC call, Xusing the program number it received earlier. X.BS X.LS no X/* X * client X */ X#include <stdio.h> X#include <rpc/rpc.h> X.sp.5 Xint callback(); Xchar hostname[256]; X.sp.5 Xmain(argc, argv) X char **argv; X{ X int x, ans, s; X SVCXPRT *xprt; X.sp.5 X gethostname(hostname, sizeof(hostname)); X s = RPC_ANYSOCK; X x = gettransient(IPPROTO_UDP, 1, &s); X fprintf(stderr, "client gets prognum %d\en", x); X if ((xprt = svcudp_create(s)) == NULL) { X fprintf(stderr, "rpc_server: svcudp_create\en"); X exit(1); X } X /* protocol is 0 - gettransient() does registering X */ X (void)svc_register(xprt, x, 1, callback, 0); X ans = callrpc(hostname, EXAMPLEPROG, EXAMPLEVERS, X EXAMPLEPROC_CALLBACK, xdr_int, &x, xdr_void, 0); X if (ans != RPC_SUCCESS) { X fprintf(stderr, "call: "); X clnt_perrno(ans); X fprintf(stderr, "\en"); X } X svc_run(); X fprintf(stderr, "Error: svc_run shouldn't return\en"); X} X.sp.5 Xcallback(rqstp, transp) X register struct svc_req *rqstp; X register SVCXPRT *transp; X{ X switch (rqstp->rq_proc) { X case 0: X if (!svc_sendreply(transp, xdr_void, 0)) { X fprintf(stderr, "err: rusersd\en"); X exit(1); X } X exit(0); X case 1: X if (!svc_getargs(transp, xdr_void, 0)) { X svcerr_decode(transp); X exit(1); X } X fprintf(stderr, "client got callback\en"); X if (!svc_sendreply(transp, xdr_void, 0)) { X fprintf(stderr, "err: rusersd"); X exit(1); X } X } X} X.sp.5 X/* X * server X */ X#include <stdio.h> X#include <rpc/rpc.h> X#include <sys/signal.h> X.sp.5 Xchar *getnewprog(); Xchar hostname[256]; Xint docallback(); Xint pnum; /* program number for callback routine */ X.sp.5 Xmain(argc, argv) X char **argv; X{ X gethostname(hostname, sizeof(hostname)); X registerrpc(EXAMPLEPROG, EXAMPLEVERS, X EXAMPLEPROC_CALLBACK, getnewprog, xdr_int, xdr_void); X fprintf(stderr, "server going into svc_run\en"); X signal(SIGALRM, docallback); X alarm(10); X svc_run(); X fprintf(stderr, "Error: svc_run shouldn't return\en"); X} X.sp.5 Xchar * Xgetnewprog(pnump) X char *pnump; X{ X pnum = *(int *)pnump; X return NULL; X} X.sp.5 Xdocallback() X{ X int ans; X.sp.5 X ans = callrpc(hostname, pnum, 1, 1, xdr_void, 0, X xdr_void, 0); X if (ans != 0) { X fprintf(stderr, "server: "); X clnt_perrno(ans); X fprintf(stderr, "\en"); X } X} X.Lf X.BE X.SH XAppendix A: Synopsis of RPC Routines X.SH Xauth_destroy() X.LP X.BS X.LS Xvoid Xauth_destroy(auth) X AUTH *auth; X.Lf X.BE XA macro that destroys the authentication information associated with X.LW auth . XDestruction usually involves deallocation Xof private data structures. The use of X.LW auth Xis undefined after calling X.LW auth_destroy() . X.SH Xauthnone_create() X.LP X.BS X.LS XAUTH * Xauthnone_create() X.Lf X.BE XCreates and returns an RPC authentication handle that passes no Xusable authentication information with each remote procedure call. X.SH Xauthunix_create() X.LP X.BS X.LS XAUTH * Xauthunix_create(host, uid, gid, len, aup_gids) X char *host; X int uid, gid, len, *aup_gids; X.Lf X.BE XCreates and returns an RPC authentication handle that contains X.UX Xauthentication information. XThe parameter X.LW host Xis the name of the machine on which the information was created; X.LW uid Xis the user's user ID; X.LW gid Xis the user's current group ID; X.LW len Xand X.LW aup_gids Xrefer to a counted array of groups to which the user belongs. XIt is easy to impersonate a user. X.SH Xauthunix_create\%_default() X.LP X.BS X.LS XAUTH * Xauthunix_create_default() X.Lf X.BE XCalls X.LW authunix_create() Xwith the appropriate parameters. X.SH Xcallrpc() X.LP X.BS X.LS Xcallrpc(host,prognum,versnum,procnum,inproc,in,outproc,out) X char *host; X u_long prognum, versnum, procnum; X char *in, *out; X xdrproc_t inproc, outproc; X.Lf X.BE XCalls the remote procedure associated with X.LW prognum , X.LW versnum , Xand X.LW procnum Xon the machine, X.LW host . XThe parameter X.LW in Xis the address of the procedure's argument(s), and X.LW out Xis the address of where to place the result(s); X.LW inproc Xis used to encode the procedure's parameters, and X.LW outproc Xis used to decode the procedure's results. XThis routine returns zero if it succeeds, or the value of X.LW "enum clnt_stat" Xcast to an integer if it fails. XThe routine X.LW clnt_perrno() Xis handy for translating failure statuses into messages. XWarning: calling remote procedures with this routine Xuses UDP/IP as a transport; see X.LW clntudp_create() Xfor restrictions. X.SH Xclnt_broadcast() X.LP X.BS X.LS Xenum clnt_stat Xclnt_broadcast(prognum, versnum, procnum, X inproc, in, outproc, out, eachresult) X u_long prognum, versnum, procnum; X char *in, *out; X xdrproc_t inproc, outproc; X resultproc_t eachresult; X.Lf X.BE XLike X.LW callrpc() , Xexcept the call message is broadcast to all locally connected broadcast nets. XEach time it receives a response, this routine calls X.LW eachresult() , Xwhose form is X.BS X.LS X eachresult(out, addr) X char *out; X struct sockaddr_in *addr; X.Lf X.BE Xwhere X.LW out Xis the same as X.LW out Xpassed to X.LW clnt_broadcast() , Xexcept that the remote procedure's output is decoded there; X.LW addr Xpoints to the address of the machine that sent the results. If X.LW eachresult() Xreturns zero, X.LW clnt_broadcast() Xwaits for more replies; Xotherwise it returns with appropriate status. X.SH Xclnt_call() X.LP X.BS X.LS Xenum clnt_stat Xclnt_call(clnt, procnum, inproc, in, outproc, out, tout) X CLIENT *clnt; long procnum; X xdrproc_t inproc, outproc; X char *in, *out; X struct timeval tout; X.Lf X.BE XA macro that calls the remote procedure X.LW procnum Xassociated with the client handle, X.LW clnt , Xwhich is obtained with an RPC client creation routine such as X.LW clntudp_create() . XThe parameter X.LW in Xis the address of the procedure's argument(s), and X.LW out Xis the address of where to place the result(s); X.LW inproc Xis used to encode the procedure's parameters, and X.LW outproc Xis used to decode the procedure's results; X.LW tout Xis the time allowed for results to come back. X.SH Xclnt_destroy() X.LP X.BS X.LS Xclnt_destroy(clnt) X CLIENT *clnt; X.Lf X.BE XA macro that destroys the client's RPC handle. XDestruction usually involves deallocation Xof private data structures, including X.LW clnt Xitself. Use of X.LW clnt Xis undefined after calling X.LW clnt_destroy() . XIt is the user's responsibility to close sockets associated with X.LW clnt . X.SH Xclnt_freeres() X.LP X.BS X.LS Xclnt_freeres(clnt, outproc, out) X CLIENT *clnt; X xdrproc_t outproc; X char *out; X.Lf X.BE XA macro that frees any data allocated by the RPC/XDR system Xwhen it decoded the results of an RPC call. XThe parameter X.LW out Xis the address of the results, and X.LW outproc Xis the XDR routine describing the results in simple primitives. XThis routine returns one if the results were successfully freed, Xand zero otherwise. X.SH Xclnt_geterr() X.LP X.BS X.LS Xvoid Xclnt_geterr(clnt, errp) X CLIENT *clnt; X struct rpc_err *errp; X.Lf X.BE XA macro that copies the error structure out of the client handle Xto the structure at address X.LW errp . X.SH Xclnt_pcreateerror() X.LP X.BS X.LS Xvoid Xclnt_pcreateerror(s) X char *s; X.Lf X.BE XPrints a message to standard error indicating Xwhy a client RPC handle could not be created. XThe message is prepended with string X.LW s Xand a colon. XUsed after a X.LW clntraw_create() , X.LW clnttcp_create() , Xor X.LW clntudp_create() Xcall. X.SH Xclnt_perrno() X.LP X.BS X.LS Xvoid Xclnt_perrno(stat) X enum clnt_stat stat; X.Lf X.BE XPrints a message to standard error corresponding Xto the condition indicated by X.LW stat . XUsed after X.LW callrpc() . X.SH Xclnt_perror() X.LP X.BS X.LS Xclnt_perror(clnt, s) X CLIENT *clnt; X char *s; X.Lf X.BE XPrints a message to standard error indicating why an RPC call failed; X.LW clnt Xis the handle used to do the call. XThe message is prepended with string X.LW s Xand a colon. XUsed after X.LW clnt_call() . X.SH Xclntraw_create() X.LP X.BS X.LS XCLIENT * Xclntraw_create(prognum, versnum) X u_long prognum, versnum; X.Lf X.BE XThis routine creates a toy RPC client for the remote program X.LW prognum , Xversion X.LW versnum . XThe transport used to pass messages to the service Xis actually a buffer within the process's address space, Xso the corresponding RPC server should live in the same address space; see X.LW svcraw_create() . XThis allows simulation of RPC and acquisition of RPC overheads, Xsuch as round trip times, without any kernel interference. XThis routine returns X.LW NULL Xif it fails. X.SH Xclnttcp_create() X.LP X.BS X.LS XCLIENT * Xclnttcp_create(addr,prognum,versnum,sockp,sendsz,recvsz) X struct sockaddr_in *addr; X u_long prognum, versnum; X int *sockp; X u_int sendsz, recvsz; X.Lf X.BE XThis routine creates an RPC client for the remote program X.LW prognum , Xversion X.LW versnum ; Xthe client uses TCP/IP as a transport. XThe remote program is located at Internet address X.LW *addr . XIf X.LW addr->sin_port Xis zero, then it is set to the actual port that the remote Xprogram is listening on (the remote X.I portmap Xservice is consulted for this information). XThe parameter X.LW *sockp Xis a socket; if it is X.LW RPC_ANYSOCK , Xthen this routine opens a new one and sets X.LW *sockp . XSince TCP-based RPC uses buffered I/O, the user may specify Xthe size of the send and receive buffers with the parameters X.LW sendsz Xand X.LW recvsz ; Xvalues of zero choose suitable defaults. XThis routine returns X.LW NULL Xif it fails. X.SH Xclntudp_create() X.LP X.BS X.LS XCLIENT * Xclntudp_create(addr, prognum, versnum, wait, sockp) X struct sockaddr_in *addr; X u_long prognum, versnum; X struct timeval wait; X int *sockp; X.Lf X.BE XThis routine creates an RPC client for the remote program X.LW prognum , Xversion X.LW versnum ; Xthe client uses use UDP/IP as a transport. XThe remote program is located at Internet address X.LW *addr . XIf X.LW addr->sin_port Xis zero, then it is set to actual port that the remote Xprogram is listening on (the remote X.I portmap Xservice is consulted for this information). XThe parameter X.LW *sockp Xis a socket; if it is X.LW RPC_ANYSOCK , Xthen this routine opens a new one and sets X.LW *sockp . XThe UDP transport resends the call message in intervals of X.LW wait Xtime until a response is received or until the call times out. XThe total time for the call to time out is specified by X.LW clnt_call() . XWarning: since UDP-based RPC messages can only hold up to 8 Kbytes Xof encoded data, this transport cannot be used for procedures Xthat take large arguments or return huge results. X.SH Xget_myaddress() X.LP X.BS X.LS Xvoid Xget_myaddress(addr) X struct sockaddr_in *addr; X.Lf X.BE XStuffs the machine's IP address into X.LW *addr , Xwithout consulting the library routines that deal with X.I /etc/hosts . XThe port number is always set to X.LW htons(PMAPPORT) . X.SH Xpmap_getmaps() X.LP X.BS X.LS Xstruct pmaplist * Xpmap_getmaps(addr) X struct sockaddr_in *addr; X.Lf X.BE XA user interface to the X.I portmap Xservice, which returns a list of the current RPC program-to-port mappings Xon the host located at IP address X.LW *addr . XThis routine can return X.LW NULL . XThe command X.LW "rpcinfo -p" Xuses this routine. X.SH Xpmap_getport() X.LP X.BS X.LS Xu_short Xpmap_getport(addr, prognum, versnum, protocol) X struct sockaddr_in *addr; X u_long prognum, versnum, protocol; X.Lf X.BE XA user interface to the X.I portmap Xservice, which returns the port number Xon which waits a service that supports program number X.LW prognum , Xversion X.LW versnum , Xand speaks the transport protocol associated with protocol. XA return value of zero means that the mapping does not exist or that Xthe RPC system failured to contact the remote X.I portmap Xservice. In the latter case, the global variable X.LW rpc_createerr Xcontains the RPC status. X.SH Xpmap_rmtcall() X.LP X.BS X.LS Xenum clnt_stat Xpmap_rmtcall(addr, prognum, versnum, procnum, X inproc, in, outproc, out, tout, portp) X struct sockaddr_in *addr; X u_long prognum, versnum, procnum; X char *in, *out; X xdrproc_t inproc, outproc; X struct timeval tout; X u_long *portp; X.Lf X.BE XA user interface to the X.I portmap Xservice, which instructs X.I portmap Xon the host at IP address X.LW *addr Xto make an RPC call on your behalf to a procedure on that host. XThe parameter X.LW *portp Xwill be modified to the program's port number if the procedure succeeds. XThe definitions of other parameters are discussed in X.LW callrpc() Xand X.LW clnt_call() . XThis procedure should be used for a ``ping'' and nothing else. XSee also X.LW clnt_broadcast() . X.SH Xpmap_set() X.LP X.BS X.LS Xpmap_set(prognum, versnum, protocol, port) X u_long prognum, versnum, protocol; X u_short port; X.Lf X.BE XA user interface to the X.I portmap Xservice, which establishes a mapping between the triple X.LW [prognum,versnum,protocol] Xand X.LW port Xon the machine's X.I portmap Xservice. The value of protocol is most likely X.LW IPPROTO_UDP Xor X.LW IPPROTO_TCP . XThis routine returns one if it succeeds, zero otherwise. XAutomatically done by X.LW svc_register() . X.SH Xpmap_unset() X.LP X.BS X.LS Xpmap_unset(prognum, versnum) X u_long prognum, versnum; X.Lf X.BE XA user interface to the X.I portmap Xservice, which destroys all mappings between the triple X.LW [prognum,versnum,*] Xand X.LW ports Xon the machine's X.I portmap Xservice. XThis routine returns one if it succeeds, zero otherwise. X.SH Xregisterrpc() X.LP X.BS X.LS Xregisterrpc(prognum,versnum,procnum,procname,inproc,outproc) X u_long prognum, versnum, procnum; X char *(*procname)(); X xdrproc_t inproc, outproc; X.Lf X.BE XRegisters procedure X.LW procname Xwith the RPC service package. If a request arrives for program X.LW prognum , Xversion X.LW versnum , Xand procedure X.LW procnum , X.LW procname Xis called with a pointer to its parameter(s); X.LW progname Xshould return a pointer to its static result(s); X.LW inproc Xis used to decode the parameters while X.LW outproc Xis used to encode the results. XThis routine returns zero if the registration succeeded, \-1 otherwise. XWarning: remote procedures registered in this form Xare accessed using the UDP/IP transport; see X.LW svcudp_create() Xfor restrictions. X.SH Xrpc_createerr X.LP X.BS X.LS Xstruct rpc_createerr rpc_createerr; X.Lf X.BE XA global variable whose value is set by any RPC client creation routine Xthat does not succeed. Use the routine X.LW clnt_pcreateerror() Xto print the reason why. X.SH Xsvc_destroy() X.LP X.BS X.LS Xsvc_destroy(xprt) X SVCXPRT *xprt; X.Lf X.BE XA macro that destroys the RPC service transport handle, X.LW xprt . XDestruction usually involves deallocation Xof private data structures, including X.LW xprt Xitself. Use of X.LW xprt Xis undefined after calling this routine. X.SH Xsvc_fds X.LP X.BS X.LS Xint svc_fds; X.Lf X.BE XA global variable reflecting the RPC service side's Xread file descriptor bit mask; it is suitable as a parameter to the X.LW select() Xsystem call. This is only of interest Xif a service implementor does not call X.LW svc_run() , Xbut rather does his own asynchronous event processing. XThis variable is read-only (do not pass its address to X.LW select() !), Xyet it may change after calls to X.LW svc_getreq() Xor any creation routines. X.SH Xsvc_freeargs() X.LP X.BS X.LS Xsvc_freeargs(xprt, inproc, in) X SVCXPRT *xprt; X xdrproc_t inproc; X char *in; X.Lf X.BE XA macro that frees any data allocated by the RPC/XDR system Xwhen it decoded the arguments to a service procedure using X.LW svc_getargs() . XThis routine returns one if the results were successfully freed, Xand zero otherwise. X.SH Xsvc_getargs() X.LP X.BS X.LS Xsvc_getargs(xprt, inproc, in) X SVCXPRT *xprt; X xdrproc_t inproc; X char *in; X.Lf X.BE XA macro that decodes the arguments of an RPC request Xassociated with the RPC service transport handle, X.LW xprt . XThe parameter X.LW in Xis the address where the arguments will be placed; X.LW inproc Xis the XDR routine used to decode the arguments. XThis routine returns one if decoding succeeds, and zero otherwise. X.SH Xsvc_getcaller() X.LP X.BS X.LS Xstruct sockaddr_in Xsvc_getcaller(xprt) X SVCXPRT *xprt; X.Lf X.BE XThe approved way of getting the network address of the caller Xof a procedure associated with the RPC service transport handle, X.LW xprt . X.SH Xsvc_getreq() X.LP X.BS X.LS Xsvc_getreq(rdfds) X int rdfds; X.Lf X.BE XThis routine is only of interest if a service implementor does not call X.LW svc_run() , Xbut instead implements custom asynchronous event processing. XIt is called when the X.LW select() Xsystem call has determined that an RPC request Xhas arrived on some RPC socket(s); X.LW rdfds Xis the resultant read file descriptor bit mask. XThe routine returns when all sockets associated with the value of X.LW rdfds Xhave been serviced. X.SH Xsvc_register() X.LP X.BS X.LS Xsvc_register(xprt, prognum, versnum, dispatch, protocol) X SVCXPRT *xprt; X u_long prognum, versnum; X void (*dispatch)(); X u_long protocol; X.Lf X.BE XAssociates X.LW prognum Xand X.LW versnum Xwith the service dispatch procedure, X.LW dispatch() . XIf X.LW protocol Xis zero, the service is not registered with the X.I portmap Xservice. If X.LW protocol Xis non-zero, then a mapping of the triple X.LW [prognum,versnum,protocol] Xto X.LW xprt->xp_port Xis established with the local X.I portmap Xservice (generally X.LW protocol Xis zero, X.LW IPPROTO_UDP Xor X.LW IPPROTO_TCP ). XThe procedure X.LW dispatch() Xhas the following form: X.BS X.LS X dispatch(request, xprt) X struct svc_req *request; X SVCXPRT *xprt; X.Lf X.BE XThe X.LW svc_register() Xroutine returns one if it succeeds, and zero otherwise. X.SH Xsvc_run() X.LP X.BS X.LS Xsvc_run() X.Lf X.BE XThis routine never returns. It waits for RPC requests to arrive, Xand calls the appropriate service procedure using X.LW svc_getreq() Xwhen one arrives. This procedure is usually waiting for a X.LW select() Xsystem call to return. X.SH Xsvc_sendreply() X.LP X.BS X.LS Xsvc_sendreply(xprt, outproc, out) X SVCXPRT *xprt; X xdrproc_t outproc; X char *out; X.Lf X.BE XCalled by an RPC service's dispatch routine Xto send the results of a remote procedure call. XThe parameter X.LW xprt Xis the caller's associated transport handle; X.LW outproc Xis the XDR routine which is used to encode the results; and X.LW out Xis the address of the results. XThis routine returns one if it succeeds, zero otherwise. X.SH Xsvc_unregister() X.LP X.BS X.LS Xvoid Xsvc_unregister(prognum, versnum) X u_long prognum, versnum; X.Lf X.BE XRemoves all mapping of the double X.LW [prognum,versnum] Xto dispatch routines, and of the triple X.LW [prognum,versnum,*] Xto port number. X.SH Xsvcerr_auth() X.LP X.BS X.LS Xvoid Xsvcerr_auth(xprt, why) X SVCXPRT *xprt; X enum auth_stat why; X.Lf X.BE XCalled by a service dispatch routine that refuses to perform Xa remote procedure call due to an authentication error. X.SH Xsvcerr_decode() X.LP X.BS X.LS Xvoid Xsvcerr_decode(xprt) X SVCXPRT *xprt; X.Lf X.BE XCalled by a service dispatch routine that can't successfully Xdecode its parameters. See also X.LW svc_getargs() . X.SH Xsvcerr_noproc() X.LP X.BS X.LS Xvoid Xsvcerr_noproc(xprt) X SVCXPRT *xprt; X.Lf X.BE XCalled by a service dispatch routine that doesn't implement Xthe desired procedure number the caller request. X.SH Xsvcerr_noprog() X.LP X.BS X.LS Xvoid Xsvcerr_noprog(xprt) X SVCXPRT *xprt; X.Lf X.BE XCalled when the desired program is not registered with the RPC package. XService implementors usually don't need this routine. X.SH Xsvcerr_progvers() X.LP X.BS X.LS Xvoid Xsvcerr_progvers(xprt) X SVCXPRT *xprt; X.Lf X.BE XCalled when the desired version of a program is not registered Xwith the RPC package. XService implementors usually don't need this routine. X.SH Xsvcerr_systemerr() X.LP X.BS X.LS Xvoid Xsvcerr_systemerr(xprt) X SVCXPRT *xprt; X.Lf X.BE XCalled by a service dispatch routine when it detects a system error Xnot covered by any particular protocol. XFor example, if a service can no longer allocate storage, Xit may call this routine. X.SH Xsvcerr_weakauth() X.LP X.BS X.LS Xvoid Xsvcerr_weakauth(xprt) X SVCXPRT *xprt; X.Lf X.BE XCalled by a service dispatch routine that refuses to perform Xa remote procedure call due to insufficient (but correct) Xauthentication parameters. The routine calls X.LW svcerr_auth(xprt,AUTH_TOOWEAK) . X.SH Xsvcraw_create() X.LP X.BS X.LS XSVCXPRT * Xsvcraw_create() X.Lf X.BE XThis routine creates a toy RPC service transport, Xto which it returns a pointer. The transport Xis really a buffer within the process's address space, Xso the corresponding RPC client should live in the same address space; see X.LW clntraw_create() . XThis routine allows simulation of RPC and acquisition of RPC overheads X(such as round trip times), without any kernel interference. XThis routine returns X.LW NULL Xif it fails. X.SH Xsvctcp_create() X.LP X.BS X.LS XSVCXPRT * Xsvctcp_create(sock, send_buf_size, recv_buf_size) X int sock; X u_int send_buf_size, recv_buf_size; X.Lf X.BE XThis routine creates a TCP/IP-based RPC service transport, Xto which it returns a pointer. XThe transport is associated with the socket X.LW sock , Xwhich may be X.LW RPC_ANYSOCK , Xin which case a new socket is created. XIf the socket is not bound to a local TCP port, then this routine Xbinds it to an arbitrary port. Upon completion, X.LW xprt->xp_sock Xis the transport's socket number, and X.LW xprt->xp_port Xis the transport's port number. XThis routine returns X.LW NULL Xif it fails. Since TCP-based RPC uses buffered I/O, Xusers may specify the size of the X.LW send Xand X.LW receive Xbuffers; values of zero choose suitable defaults. X.SH Xsvcudp_create() X.LP X.BS X.LS XSVCXPRT * Xsvcudp_create(sock) X int sock; X.Lf X.BE XThis routine creates a UDP/IP-based RPC service transport, Xto which it returns a pointer. XThe transport is associated with the socket X.LW sock , Xwhich may be X.LW RPC_ANYSOCK , Xin which case a new socket is created. XIf the socket is not bound to a local UDP port, then this routine Xbinds it to an arbitrary port. Upon completion, X.LW xprt->xp_sock Xis the transport's socket number, and X.LW xprt->xp_port Xis the transport's port number. XThis routine returns X.LW NULL Xif it fails. XWarning: since UDP-based RPC messages can only hold up to 8 Kbytes Xof encoded data, this transport cannot be used for procedures Xthat take large arguments or return huge results. X.SH Xxdr_accepted_reply() X.LP X.BS X.LS Xxdr_accepted_reply(xdrs, ar) X XDR *xdrs; X struct accepted_reply *ar; X.Lf X.BE XUsed for describing RPC messages, externally. XThis routine is useful for users who wish to generate XRPC-style messages without using the RPC package. X.SH Xxdr_array() X.LP X.BS X.LS Xxdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc) X XDR *xdrs; X char **arrp; X u_int *sizep, maxsize, elsize; X xdrproc_t elproc; X.Lf X.BE XA filter primitive that translates between arrays Xand their corresponding external representations. XThe parameter X.LW arrp Xis the address of the pointer to the array, while X.LW sizep Xis the address of the element count of the array; Xthis element count cannot exceed X.LW maxsize . XThe parameter X.LW elsize Xis the X.LW sizeof() Xeach of the array's elements, and X.LW elproc Xis an XDR filter that translates between Xthe array elements' C form, and their external representation. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_authunix_parms() X.LP X.BS X.LS Xxdr_authunix_parms(xdrs, aupp) X XDR *xdrs; X struct authunix_parms *aupp; X.Lf X.BE XUsed for describing UNIX credentials, externally. XThis routine is useful for users who wish to generate Xthese credentials without using the RPC authentication package. X.SH Xxdr_bool() X.LP X.BS X.LS Xxdr_bool(xdrs, bp) X XDR *xdrs; X bool_t *bp; X.Lf X.BE XA filter primitive that translates between booleans (C integers) Xand their external representations. XWhen encoding data, this filter produces values of either one or zero. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_bytes() X.LP X.BS X.LS Xxdr_bytes(xdrs, sp, sizep, maxsize) X XDR *xdrs; X char **sp; X u_int *sizep, maxsize; X.Lf X.BE XA filter primitive that translates between counted byte strings Xand their external representations. XThe parameter X.LW sp Xis the address of the string pointer. XThe length of the string is located at address X.LW sizep ; Xstrings cannot be longer than X.LW maxsize . XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_callhdr() X.LP X.BS X.LS Xvoid Xxdr_callhdr(xdrs, chdr) X XDR *xdrs; X struct rpc_msg *chdr; X.Lf X.BE XUsed for describing RPC messages, externally. XThis routine is useful for users who wish to generate XRPC-style messages without using the RPC package. X.SH Xxdr_callmsg() X.LP X.BS X.LS Xxdr_callmsg(xdrs, cmsg) X XDR *xdrs; X struct rpc_msg *cmsg; X.Lf X.BE XUsed for describing RPC messages, externally. XThis routine is useful for users who wish to generate XRPC-style messages without using the RPC package. X.SH Xxdr_double() X.LP X.BS X.LS Xxdr_double(xdrs, dp) X XDR *xdrs; X double *dp; X.Lf X.BE XA filter primitive that translates between C X.LW double Xprecision numbers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_enum() X.LP X.BS X.LS Xxdr_enum(xdrs, ep) X XDR *xdrs; X enum_t *ep; X.Lf X.BE XA filter primitive that translates between C X.LW enum s X(actually integers) and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_float() X.LP X.BS X.LS Xxdr_float(xdrs, fp) X XDR *xdrs; X float *fp; X.Lf X.BE XA filter primitive that translates between C X.LW float s Xand their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_inline() X.LP X.BS X.LS Xlong * Xxdr_inline(xdrs, len) X XDR *xdrs; X int len; X.Lf X.BE XA macro that invokes the in-line routine associated with the XDR stream, X.LW xdrs . XThe routine returns a pointer Xto a contiguous piece of the stream's buffer; X.LW len Xis the byte length of the desired buffer. XNote that pointer is cast to X.LW "long *" . XWarning: X.LW xdr_inline() Xmay return X.LW NULL X(0) if it cannot allocate a contiguous piece of a buffer. XTherefore the behavior may vary among stream instances; Xit exists for the sake of efficiency. X.SH Xxdr_int() X.LP X.BS X.LS Xxdr_int(xdrs, ip) X XDR *xdrs; X int *ip; X.Lf X.BE XA filter primitive that translates between C integers Xand their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_long() X.LP X.BS X.LS Xxdr_long(xdrs, lp) X XDR *xdrs; X long *lp; X.Lf X.BE XA filter primitive that translates between C X.LW long Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_opaque() X.LP X.BS X.LS Xxdr_opaque(xdrs, cp, cnt) X XDR *xdrs; X char *cp; X u_int cnt; X.Lf X.BE XA filter primitive that translates between fixed size opaque data Xand its external representation. XThe parameter X.LW cp Xis the address of the opaque object, and X.LW cnt Xis its size in bytes. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_opaque_auth() X.LP X.BS X.LS Xxdr_opaque_auth(xdrs, ap) X XDR *xdrs; X struct opaque_auth *ap; X.Lf X.BE XUsed for describing RPC messages, externally. XThis routine is useful for users who wish to generate XRPC-style messages without using the RPC package. X.SH Xxdr_pmap() X.LP X.BS X.LS Xxdr_pmap(xdrs, regs) X XDR *xdrs; X struct pmap *regs; X.Lf X.BE XUsed for describing parameters to various X.I portmap Xprocedures, externally. XThis routine is useful for users who wish to generate Xthese parameters without using the X.LW pmap Xinterface. X.SH Xxdr_pmaplist() X.LP X.BS X.LS Xxdr_pmaplist(xdrs, rp) X XDR *xdrs; X struct pmaplist **rp; X.Lf X.BE XUsed for describing a list of port mappings, externally. XThis routine is useful for users who wish to generate Xthese parameters without using the X.LW pmap Xinterface. X.SH Xxdr_reference() X.LP X.BS X.LS Xxdr_reference(xdrs, pp, size, proc) X XDR *xdrs; X char **pp; X u_int size; X xdrproc_t proc; X.Lf X.BE XA primitive that provides pointer chasing within structures. XThe parameter X.LW pp Xis the address of the pointer; X.LW size Xis the X.LW sizeof() Xthe structure that X.LW *pp Xpoints to; and X.LW proc Xis an XDR procedure that filters the structure Xbetween its C form and its external representation. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_rejected_reply() X.LP X.BS X.LS Xxdr_rejected_reply(xdrs, rr) X XDR *xdrs; X struct rejected_reply *rr; X.Lf X.BE XUsed for describing RPC messages, externally. XThis routine is useful for users who wish to generate XRPC-style messages without using the RPC package. X.SH Xxdr_replymsg() X.LP X.BS X.LS Xxdr_replymsg(xdrs, rmsg) X XDR *xdrs; X struct rpc_msg *rmsg; X.Lf X.BE XUsed for describing RPC messages, externally. XThis routine is useful for users who wish to generate XRPC style messages without using the RPC package. X.SH Xxdr_short() X.LP X.BS X.LS Xxdr_short(xdrs, sp) X XDR *xdrs; X short *sp; X.Lf X.BE XA filter primitive that translates between C X.LW short Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_string() X.LP X.BS X.LS Xxdr_string(xdrs, sp, maxsize) X XDR *xdrs; X char **sp; X u_int maxsize; X.Lf X.BE XA filter primitive that translates between C strings and their Xcorresponding external representations. XStrings cannot be longer than X.LW maxsize . XNote that X.LW sp Xis the address of the string's pointer. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_u_int() X.LP X.BS X.LS Xxdr_u_int(xdrs, up) X XDR *xdrs; X unsigned *up; X.Lf X.BE XA filter primitive that translates between C X.LW unsigned Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_u_long() X.LP X.BS X.LS Xxdr_u_long(xdrs, ulp) X XDR *xdrs; X unsigned long *ulp; X.Lf X.BE XA filter primitive that translates between C X.LW "unsigned long" Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_u_short() X.LP X.BS X.LS Xxdr_u_short(xdrs, usp) X XDR *xdrs; X unsigned short *usp; X.Lf X.BE XA filter primitive that translates between C X.LW "unsigned short" Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_union() X.LP X.BS X.LS Xxdr_union(xdrs, dscmp, unp, choices, dfault) X XDR *xdrs; X int *dscmp; X char *unp; X struct xdr_discrim *choices; X xdrproc_t dfault; X.Lf X.BE XA filter primitive that translates between a discriminated C X.LW union Xand its corresponding external representation. The parameter X.LW dscmp Xis the address of the union's discriminant, while X.LW unp Xin the address of the union. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxdr_void() X.LP X.BS X.LS Xxdr_void() X.Lf X.BE XThis routine always returns one. X.SH Xxdr_wrapstring() X.LP X.BS X.LS Xxdr_wrapstring(xdrs, sp) X XDR *xdrs; X char **sp; X.Lf X.BE XA primitive that calls X.LW xdr_string(xdrs,sp,MAXUNSIGNED); Xwhere X.LW MAXUNSIGNED Xis the maximum value of an unsigned integer. XThis is handy because the RPC package passes Xonly two parameters XDR routines, whereas X.LW xdr_string() , Xone of the most frequently used primitives, requires three parameters. XThis routine returns one if it succeeds, zero otherwise. X.SH Xxprt_register() X.LP X.BS X.LS Xvoid Xxprt_register(xprt) X SVCXPRT *xprt; X.Lf X.BE XAfter RPC service transport handles are created, Xthey should register themselves with the RPC service package. XThis routine modifies the global variable X.LW svc_fds . XService implementors usually don't need this routine. X.SH Xxprt_unregister() X.LP X.BS X.LS Xvoid Xxprt_unregister(xprt) X SVCXPRT *xprt; X.Lf X.BE XBefore an RPC service transport handle is destroyed, Xit should unregister itself with the RPC service package. XThis routine modifies the global variable X.LW svc_fds . XService implementors usually don't need this routine. SHAR_EOF if test 33027 -ne "`wc -c < 'rpc/doc/rpc.prog.p2'`" then echo shar: "error transmitting 'rpc/doc/rpc.prog.p2'" '(should have been 33027 characters)' fi chmod 444 'rpc/doc/rpc.prog.p2' fi echo shar: "extracting 'rpc/doc/xdr.spec.p2'" '(16007 characters)' if test -f 'rpc/doc/xdr.spec.p2' then echo shar: "will not over-write existing file 'rpc/doc/xdr.spec.p2'" else sed 's/^X//' << \SHAR_EOF > 'rpc/doc/xdr.spec.p2' X.LS Xbool_t Xxdr_wrap_list(xdrs, glp) X XDR *xdrs; X gnumbers_list *glp; X{ X return(xdr_reference(xdrs, glp, sizeof(struct gnnode), X xdr_gnnode)); X} X.Lf X.LS Xstruct xdr_discrim choices[2] = { X /* X * called if another node needs (de)serializing X */ X { TRUE, xdr_wrap_list }, X /* X * called when no more nodes need (de)serializing X */ X { FALSE, xdr_void } X} X.sp.5 Xbool_t Xxdr_gnumbers_list(xdrs, glp) X XDR *xdrs; X gnumbers_list *glp; X{ X bool_t more_data; X.sp.5 X more_data = (*glp != (gnumbers_list)NULL); X return(xdr_union(xdrs, &more_data, glp, choices, NULL); X} X.Lf XThe entry routine is X.LW xdr_gnumbers_list() ; Xits job is to translate between the boolean value X.LW more_data Xand the list pointer values. XIf there is no more data, the X.LW xdr_union() Xprimitive calls X.LW xdr_void() Xand the recursion is terminated. XOtherwise, X.LW xdr_union() Xcalls X.LW xdr_wrap_list() , Xwhose job is to dereference the list pointers. XThe X.LW xdr_gnnode() Xroutine actually (de)serializes data of the current node Xof the linked list, and recursively calls X.LW xdr_gnumbers_list() Xto handle the remainder of the list. X.LP XYou should convince yourself that these routines Xfunction correctly in all three directions X.LW (XDR_ENCODE , X.LW XDR_DECODE , Xand X.LW XDR_FREE) Xfor linked lists of any length (including zero). XNote that the boolean X.LW more_data Xis always initialized, but in the X.LW XDR_DECODE Xcase it is overwritten by an externally generated value. XAlso note that the value of the X.LW bool_t Xis lost in the stack. XThe essence of the value is reflected in the list's pointers. X.LP XThe unfortunate side effect of (de)serializing a list Xwith these routines is that the C stack grows linearly Xwith respect to the number of nodes in the list. XThis is due to the recursion. XThe routines are also hard to Xcode (and understand) due to the number and nature of primitives involved X(such as X.LW xdr_reference , X.LW xdr_union , Xand X.LW xdr_void ). X.LP XThe following routine collapses the recursive routines. XIt also has other optimizations that are discussed below. X.LS Xbool_t Xxdr_gnumbers_list(xdrs, glp) X XDR *xdrs; X gnumbers_list *glp; X{ X bool_t more_data; X.sp.5 X while (TRUE) { X more_data = (*glp != (gnumbers_list)NULL); X if (!xdr_bool(xdrs, &more_data)) X return(FALSE); X if (!more_data) X return(TRUE); /* we are done */ X if (!xdr_reference(xdrs, glp, sizeof(struct gnnode), X xdr_gnumbers)) X return(FALSE); X glp = &((*glp)->nxt); X } X} X.Lf XThe claim is that this one routine is easier to code and understand than the Xthree recursive routines above. X(It is also buggy, as discussed below.) XThe parameter X.LW glp Xis treated as the address of the pointer Xto the head of the Xremainder of the list to be (de)serialized. XThus, X.LW glp Xis set to the Xaddress of the current node's X.LW nxt Xfield at the end of the while loop. XThe discriminated union is implemented in-line; the variable X.LW more_data Xhas the same use in this routine as in the routines above. XIts value is Xrecomputed and re-(de)serialized each iteration of the loop. XSince X.LW *glp Xis a pointer to a node, the pointer is dereferenced using X.LW xdr_reference() . XNote that the third parameter is truly the size of a node X(data values plus X.LW nxt Xpointer), while X.LW xdr_gnumbers() Xonly (de)serializes the data values. XWe can get away with this tricky optimization only because the X.LW nxt Xdata comes after all legitimate external data. X.LP XThe routine is buggy in the X.LW XDR_FREE Xcase. The bug is that X.LW xdr_reference() Xwill free the node X.LW *glp . XUpon return the assignment X.LW "glp = &((*glp)->nxt)" Xcannot be guaranteed to work since X.LW *glp Xis no longer a legitimate node. XThe following is a rewrite that works in all cases. XThe hard part is to avoid dereferencing a pointer Xwhich has not been initialized or which has been freed. X.LS Xbool_t Xxdr_gnumbers_list(xdrs, glp) X XDR *xdrs; X gnumbers_list *glp; X{ X bool_t more_data; X bool_t freeing; X gnumbers_list *next; /* the next value of glp */ X.sp.5 X freeing = (xdrs->x_op == XDR_FREE); X while (TRUE) { X more_data = (*glp != (gnumbers_list)NULL); X if (!xdr_bool(xdrs, &more_data)) X return(FALSE); X if (!more_data) X return(TRUE); /* we are done */ X if (freeing) X next = &((*glp)->nxt); X if (!xdr_reference(xdrs, glp, sizeof(struct gnnode), X xdr_gnumbers)) X return(FALSE); X glp = (freeing) ? next : &((*glp)->nxt); X } X} X.Lf XNote that this is the first example in this document Xthat actually inspects the direction of the operation X.LW xdrs->x_op ). ( XThe claim is that the correct iterative implementation is still Xeasier to understand or code than the recursive implementation. XIt is certainly more efficient with respect to C stack requirements. X.NH 2 XThe Record Marking Standard X.LP XA record is composed of one or more record fragments. XA record fragment is a four-byte header followed by X$ 0 ~ "\fRto\fP" ~ {2 sup 31} - 1$ bytes of fragment data. XThe bytes encode an unsigned binary number; Xas with XDR integers, the byte order is from highest to lowest. XThe number encodes two values \(em Xa boolean that indicates whether the fragment is the last fragment Xof the record (bit value 1 implies the fragment is the last fragment), Xand a 31-bit unsigned binary value Xwhich is the length in bytes of the fragment's data. XThe boolean value is the high-order bit of the Xheader; the length is the 31 low-order bits. X.LP X(Note that this record specification is X.I not Xin XDR standard form Xand cannot be implemented using XDR primitives!) X.\" X.bp X.SH XAppendix A -- Synopsis of XDR Routines X.LP X.LW xdr_array() X.LS Xxdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc) X XDR *xdrs; X char **arrp; X u_int *sizep, maxsize, elsize; X xdrproc_t elproc; X.Lf XA filter primitive that translates between arrays Xand their corresponding external representations. XThe parameter X.LW arrp Xis the address of the pointer to the array, while X.LW sizep Xis the address of the element count of the array; Xthis element count cannot exceed X.LW maxsize . XThe parameter X.LW elsize Xis the X.LW sizeof() Xeach of the array's elements, and X.LW elproc Xis an XDR filter that translates between Xthe array elements' C form, and their external representation. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_bool() X.LS Xxdr_bool(xdrs, bp) X XDR *xdrs; X bool_t *bp; X.Lf XA filter primitive that translates between booleans (C integers) Xand their external representations. XWhen encoding data, this filter produces values of either one or zero. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_bytes() X.LS Xxdr_bytes(xdrs, sp, sizep, maxsize) X XDR *xdrs; X char **sp; X u_int *sizep, maxsize; X.Lf XA filter primitive that translates between counted byte strings Xand their external representations. XThe parameter X.LW sp Xis the address of the string pointer. XThe length of the string is located at address X.LW sizep ; Xstrings cannot be longer than X.LW maxsize . XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_destroy() X.LS Xvoid Xxdr_destroy(xdrs) X XDR *xdrs; X.Lf XA macro that invokes the destroy routine Xassociated with the XDR stream, X.LW xdrs . XDestruction usually involves freeing private data structures Xassociated with the stream. Using X.LW xdrs Xafter invoking X.LW xdr_destroy() Xis undefined. X.LP X.LW xdr_double() X.LS Xxdr_double(xdrs, dp) X XDR *xdrs; X double *dp; X.Lf XA filter primitive that translates between C X.LW double Xprecision numbers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_enum() X.LS Xxdr_enum(xdrs, ep) X XDR *xdrs; X enum_t *ep; X.Lf XA filter primitive that translates between C X.LW enum s X(actually integers) and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_float() X.LS Xxdr_float(xdrs, fp) X XDR *xdrs; X float *fp; X.Lf XA filter primitive that translates between C X.LW float s Xand their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_getpos() X.LS Xu_int Xxdr_getpos(xdrs) X XDR *xdrs; X.Lf XA macro that invokes the get-position routine Xassociated with the XDR stream, X.LW xdrs . XThe routine returns an unsigned integer, Xwhich indicates the position of the XDR byte stream. XA desirable feature of XDR streams Xis that simple arithmetic works with this number, Xalthough the XDR stream instances need not guarantee this. X.LP X.LW xdr_inline() X.LS Xlong * Xxdr_inline(xdrs, len) X XDR *xdrs; X int len; X.Lf XA macro that invokes the in-line routine associated with the XDR stream, X.LW xdrs . XThe routine returns a pointer Xto a contiguous piece of the stream's buffer; X.LW len Xis the byte length of the desired buffer. XNote that the pointer is cast to X.LW "long *" . XWarning: X.LW xdr_inline() Xmay return X.LW NULL Xif it cannot allocate a contiguous piece of a buffer. XTherefore the behavior may vary among stream instances; Xit exists for the sake of efficiency. X.LP X.LW xdr_int() X.LS Xxdr_int(xdrs, ip) X XDR *xdrs; X int *ip; X.Lf XA filter primitive that translates between C integers Xand their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_long() X.LS Xxdr_long(xdrs, lp) X XDR *xdrs; X long *lp; X.Lf XA filter primitive that translates between C X.LW long Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_opaque() X.LS Xxdr_opaque(xdrs, cp, cnt) X XDR *xdrs; X char *cp; X u_int cnt; X.Lf XA filter primitive that translates between fixed size opaque data Xand its external representation. XThe parameter X.LW cp Xis the address of the opaque object, and X.LW cnt Xis its size in bytes. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_reference() X.LS Xxdr_reference(xdrs, pp, size, proc) X XDR *xdrs; X char **pp; X u_int size; X xdrproc_t proc; X.Lf XA primitive that provides pointer chasing within structures. XThe parameter X.LW pp Xis the address of the pointer; X.LW size Xis the X.LW sizeof() Xthe structure that X.LW *pp Xpoints to; and X.LW proc Xis an XDR procedure that filters the structure Xbetween its C form and its external representation. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_setpos() X.LS Xxdr_setpos(xdrs, pos) X XDR *xdrs; X u_int pos; X.Lf XA macro that invokes the set position routine associated with the XDR stream X.LW xdrs . XThe parameter X.LW pos Xis a position value obtained from X.LW xdr_getpos() . XThis routine returns one if the XDR stream could be repositioned, Xand zero otherwise. XWarning: it is difficult to reposition some types of XDR streams, Xso this routine may fail with one type of stream and succeed with another. X.LP X.LW xdr_short() X.LS Xxdr_short(xdrs, sp) X XDR *xdrs; X short *sp; X.Lf XA filter primitive that translates between C X.LW short Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_string() X.LS Xxdr_string(xdrs, sp, maxsize) X XDR *xdrs; X char **sp; X u_int maxsize; X.Lf XA filter primitive that translates between C strings and their Xcorresponding external representations. XStrings cannot cannot be longer than X.LW maxsize . XNote that X.LW sp Xis the address of the string's pointer. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_u_int() X.LS Xxdr_u_int(xdrs, up) X XDR *xdrs; X unsigned *up; X.Lf XA filter primitive that translates between C X.LW unsigned Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_u_long() X.LS Xxdr_u_long(xdrs, ulp) X XDR *xdrs; X unsigned long *ulp; X.Lf XA filter primitive that translates between C X.LW "unsigned long" Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_u_short() X.LS Xxdr_u_short(xdrs, usp) X XDR *xdrs; X unsigned short *usp; X.Lf XA filter primitive that translates between C X.LW "unsigned short" Xintegers and their external representations. XThis routine returns one if it succeeds, zero otherwise. X.br X.ne 2i X.LW xdr_union() X.LS Xxdr_union(xdrs, dscmp, unp, choices, dfault) X XDR *xdrs; X int *dscmp; X char *unp; X struct xdr_discrim *choices; X xdrproc_t dfault; X.Lf XA filter primitive that translates between a discriminated C X.LW union Xand its corresponding external representation. The parameter X.LW dscmp Xis the address of the union's discriminant, while X.Lunp Xin the address of the union. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdr_void() X.LS Xxdr_void() X.Lf XThis routine always returns one. XIt may be passed to RPC routines that require a function parameter, Xwhere nothing is to be done. X.LP X.LW xdr_wrapstring() X.LS Xxdr_wrapstring(xdrs, sp) X XDR *xdrs; X char **sp; X.Lf XA primitive that calls X.LW xdr_string(xdrs,sp,MAXUNSIGNED); Xwhere X.LW MAXUNSIGNED Xis the maximum value of an unsigned integer. XThis is handy because the RPC package passes Xonly two parameters XDR routines, whereas X.LW xdr_string() , Xone of the most frequently used primitives, requires three parameters. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdrmem_create() X.LS Xvoid Xxdrmem_create(xdrs, addr, size, op) X XDR *xdrs; X char *addr; X u_int size; X enum xdr_op op; X.Lf XThis routine initializes the XDR stream object pointed to by X.LW xdrs . XThe stream's data is written to, or read from, Xa chunk of memory at location X.LW addr Xwhose length is no more than X.LW size Xbytes long. The X.LW op Xdetermines the direction of the XDR stream X(either X.LW XDR_ENCODE , X.LW XDR_DECODE , Xor X.LW XDR_FREE ). X.LP X.LW xdrrec_create() X.LS Xvoid Xxdrrec_create(xdrs, X sendsize, recvsize, handle, readit, writeit) X XDR *xdrs; X u_int sendsize, recvsize; X char *handle; X int (*readit)(), (*writeit)(); X.Lf XThis routine initializes the XDR stream object pointed to by X.LW xdrs . XThe stream's data is written to a buffer of size X.LW sendsize ; Xa value of zero indicates the system should use a suitable default. XThe stream's data is read from a buffer of size X.LW recvsize ; Xit too can be set to a suitable default by passing a zero value. XWhen a stream's output buffer is full, X.LW writeit() Xis called. Similarly, when a stream's input buffer is empty, X.LW readit() Xis called. The behavior of these two routines Xis similar to the X.UX Xsystem calls X.LW read Xand X.LW write , Xexcept that X.LW handle Xis passed to the former routines as the first parameter. XNote that the XDR stream's X.LW op Xfield must be set by the caller. XWarning: this XDR stream implements an intermediate record stream. XTherefore there are additional bytes in the stream Xto provide record boundary information. X.LP X.LW xdrrec_endofrecord() X.LS Xxdrrec_endofrecord(xdrs, sendnow) X XDR *xdrs; X int sendnow; X.Lf XThis routine can be invoked only on streams created by X.LW xdrrec_create() . XThe data in the output buffer is marked as a completed record, Xand the output buffer is optionally written out if X.LW sendnow Xis non-zero. This routine returns one if it succeeds, zero otherwise. X.LP X.LW xdrrec_eof() X.LS Xxdrrec_eof(xdrs) X XDR *xdrs; X int empty; X.Lf XThis routine can be invoked only on streams created by X.LW xdrrec_create() . XAfter consuming the rest of the current record in the stream, Xthis routine returns one if the stream has no more input, zero otherwise. X.LP X.LW xdrrec_skiprecord() X.LS Xxdrrec_skiprecord(xdrs) X XDR *xdrs; X.Lf XThis routine can be invoked only on streams created by X.LW xdrrec_create() . XIt tells the XDR implementation that the rest of the current record Xin the stream's input buffer should be discarded. XThis routine returns one if it succeeds, zero otherwise. X.LP X.LW xdrstdio_create() X.LS Xvoid Xxdrstdio_create(xdrs, file, op) X XDR *xdrs; X FILE *file; X enum xdr_op op; X.Lf XThis routine initializes the XDR stream object pointed to by X.LW xdrs . XThe XDR stream data is written to, or read from, the Standard I/O stream X.LW file . XThe parameter X.LW op Xdetermines the direction of the XDR stream (either X.LW XDR_ENCODE , X.LW XDR_DECODE , Xor X.LW XDR_FREE ). XWarning: the destroy routine associated with such XDR streams calls X.LW fflush() Xon the X.LW file Xstream, but never X.LW fclose() . SHAR_EOF if test 16007 -ne "`wc -c < 'rpc/doc/xdr.spec.p2'`" then echo shar: "error transmitting 'rpc/doc/xdr.spec.p2'" '(should have been 16007 characters)' fi chmod 444 'rpc/doc/xdr.spec.p2' fi exit 0 # End of shell archive