Skip Navigation Links | |
Exit Print View | |
ONC+ Developer's Guide Oracle Solaris 11.1 Information Library |
1. Introduction to ONC+ Technologies
4. Programmer's Interface to RPC
Client Side of Simplified Interface
Server Side of the Simplified Interface
Hand-Coded Registration Routine
Client Side of the Top-Level Interface
Client Side of the Intermediate-Level Interface
Server Side of the Intermediate-Level Interface
Client Side of the Expert-Level Interface
Server Side of the Expert-Level Interface
Client Side of the Bottom-Level Interface
Server Side of the Bottom-Level Interface
Testing Programs Using Low-Level Raw RPC
5. Advanced RPC Programming Techniques
6. Porting From TS-RPC to TI-RPC
7. Multithreaded RPC Programming
8. Extensions to the Oracle Solaris RPC Library
Example 4-20 copies a file from one host to another. The RPC send() call reads standard input and sends the data to the server receive(), which writes the data to standard output. This example also illustrates an XDR procedure that behaves differently on serialization and on deserialization. A connection-oriented transport is used.
Example 4-20 Remote Copy (Two-Way XDR Routine)
/* * The xdr routine: * on decode, read wire, write to fp * on encode, read fp, write to wire */ #include <stdio.h> #include <rpc/rpc.h> bool_t xdr_rcp(xdrs, fp) XDR *xdrs; FILE *fp; { unsigned long size; char buf[BUFSIZ], *p; if (xdrs->x_op == XDR_FREE) /* nothing to free */ return(TRUE); while (TRUE) { if (xdrs->x_op == XDR_ENCODE) { if ((size = fread( buf, sizeof( char ), BUFSIZ, fp)) == 0 && ferror(fp)) { fprintf(stderr, "can't fread\n"); return(FALSE); } else return(TRUE); } p = buf; if (! xdr_bytes( xdrs, &p, &size, BUFSIZ)) return(0); if (size == 0) return(1); if (xdrs->x_op == XDR_DECODE) { if (fwrite( buf, sizeof(char), size, fp) != size) { fprintf(stderr, "can't fwrite\n"); return(FALSE); } else return(TRUE); } } }
In Example 4-21 and Example 4-22, the serializing and deserializing are done only by the xdr_rcp() routine shown in Example 4-20.
Example 4-21 Remote Copy Client Routines
/* The sender routines */ #include <stdio.h> #include <netdb.h> #include <rpc/rpc.h> #include <sys/socket.h> #include <sys/time.h> #include "rcp.h" main(argc, argv) int argc; char **argv; { int xdr_rcp(); if (argc != 2 7) { fprintf(stderr, "usage: %s servername\n", argv[0]); exit(1); } if( callcots( argv[1], RCPPROG, RCPPROC, RCPVERS, xdr_rcp, stdin, xdr_void, 0 ) != 0 ) exit(1); exit(0); } callcots(host, prognum, procnum, versnum, inproc, in, outproc, out) char *host, *in, *out; xdrproc_t inproc, outproc; { enum clnt_stat clnt_stat; register CLIENT *client; struct timeval total_timeout; if ((client = clnt_create( host, prognum, versnum, "circuit_v") == (CLIENT *) NULL)) { clnt_pcreateerror("clnt_create"); return(-1); } total_timeout.tv_sec = 20; total_timeout.tv_usec = 0; clnt_stat = clnt_call(client, procnum, inproc, in, outproc, out, total_timeout); clnt_destroy(client); if (clnt_stat != RPC_SUCCESS) clnt_perror("callcots"); return((int)clnt_stat); }
The following code example defines the receiving routines. Note that in the server, xdr_rcp() did all the work automatically.
Example 4-22 Remote Copy Server Routines
/* * The receiving routines */ #include <stdio.h> #include <rpc/rpc.h #include "rcp.h" main() { void rcp_service(); if (svc_create(rpc_service,RCPPROG,RCPVERS,"circuit_v") == 0) { fprintf(stderr, "svc_create: errpr\n"); exit(1); } svc_run(); /* never returns */ fprintf(stderr, "svc_run should never return\n"); } void rcp_service(rqstp, transp) register struct svc_req *rqstp; register SVCXPRT *transp; { switch(rqstp->rq_proc) { case NULLPROC: if (svc_sendreply(transp, xdr_void, (caddr_t) NULL) == FALSE) fprintf(stderr, "err: rcp_service"); return; case RCPPROC: if (!svc_getargs( transp, xdr_rcp, stdout)) { svcerr_decode(transp); return(); } if(!svc_sendreply(transp, xdr_void, (caddr_t) NULL)) { fprintf(stderr, "can't reply\n"); return(); } return(); default: svcerr_noproc(transp); return(); } }