|
|
This is an example that copies a file from one system to another. The initiator of the RPC send call takes its standard input and sends it to the server receive, which prints it on standard output. This also illustrates an XDR procedure that behaves differently on serialization than on deserialization.
/* * The xdr routine: on decode, read from wire, write onto fp * on encode, read from fp, write onto wire */ #include <stdio.h> #include <rpc/rpc.h>Note that in the following two screens, the serializing and deserializing is done only by xdr_bytes.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 1; while (1) { if (xdrs->x_op == XDR_ENCODE) { if ((size = fread(buf, sizeof(char), BUFSIZ, fp)) == 0 && ferror(fp)) { fprintf(stderr, "can't fread\n"); return (1); } } 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 (1); } } } }
/* The sender routines */#include <stdio.h> #include <netdb.h> #include <rpc/rpc.h> #include <sys/socket.h> #include <sys/time.h>
main(argc, argv) int argc; char **argv; { int xdr_rcp();
if (argc < 2) { 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")) == NULL) { perror("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 receiving routines */ #include <stdio.h> #include <rpc/rpc.h>Note that on the server side no explicit action was taken after receiving the arguments. This is because xdr_rcp did all the necessary dirty work automatically.main () { int rcp_service(), xdr_rcp();
if (svc_create(rpc_service, RCPPROG, RCPVERS, "circuit_v") == 0) { fprintf("svc_create: error\n"); exit(1); } svc_run(); /* never returns */ fprintf(stderr, "svc_run should never return\n"); }
rcp_service(rqstp, transp) register struct svc_req *rqstp; register SVCXPRT *transp; { switch (rqstp->rq_proc) { case NULLPROC: if (svc_sendreply(transp, xdr_void, 0) == 0) { fprintf(stderr, "err: rcp_service"); return (1); } return; case RCPPROC: if (!svc_getargs(transp, xdr_rcp, stdout)) { svcerr_decode(transp); return (1); } if (!svc_sendreply(transp, xdr_void, 0)) { fprintf(stderr, "can't reply\n"); return (1); } return (0); default: svcerr_noproc(transp); return (1); } }