The following example shows a simple interface that makes explicit remote procedure calls using the callrpc routine at the intermediate layer of Remote Procedure Call (RPC). The interface can be used on both the client and server sides.
Normally, the server registers each procedure, and then goes into an infinite loop waiting to service requests. Since there is only a single procedure to register, the main body of the server message would look like the following:
#include <stdio.h> #include <rpc/rpc.h> #include <utmp.h> #include <rpcsvc/rusers.h>
char *nuser();
main() { registerrpc(RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, nuser, xdr_void, xdr_u_long); svc_run(); /* Never returns */ fprintf(stderr, "Error: svc_run returned!\n"); exit(1); }
The registerrpc routine registers a C procedure as corresponding to a given RPC procedure number. The first three parameters, RUSERSPROG, RUSERSVERS, and RUSERSPROC_NUM, specify the program, version, and procedure numbers of the remote procedure to be registered. The nuser parameter is the name of the local procedure that implements the remote procedure, and the xdr_void and xdr_u_long parameters are the eXternal Data Representation (XDR) filters for the remote procedure's arguments and results, respectively.
#include <stdio.h> #include <rpc/rpc.h> #include <utmp.h> #include <rpcsvc/rusers.h>
main(argc, argv) int argc; char **argv; { unsigned long nusers; int stat;
if (argc != 2) { fprintf(stderr, "usage: nusers hostname\n"); exit(-1); } if (stat = callrpc(argv[1], RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, xdr_void, 0, xdr_u_long, &nusers) != 0) { clnt_perrno(stat); exit(1); } printf("%d users on %s\n", nusers, argv[1]); exit(0); }
The callrpc subroutine has eight parameters. The first, host, specifies the name of the remote server machine. The next three parameters, prognum, versnum, and procnum, specify the program, version, and procedure numbers. The fifth and sixth parameters, inproc and in, are an XDR filter and an argument to be encoded and passed to the remote procedure. The final two parameters, outproc and out, are a filter for decoding the results returned by the remote procedure and a pointer to the place where the procedure's results are to be stored. Multiple arguments and results are handled by embedding them in structures. If the callrpc subroutine completes successfully, it returns zero. Otherwise, it returns a nonzero value.
Since data types may be represented differently on different machines, the callrpc subroutine needs both the type of the RPC argument and a pointer to the argument itself. The return value for the RUSERSPROC_NUM parameter is unsigned long, so the callrpc subroutine has xdr_u_long as its first return parameter. This parameter specifies that the result is of the unsigned long type. The second return parameter, &nusers, is a pointer to where the long result is placed. Since the RUSERSPROC_NUM parameter takes no argument, the argument parameter of the callrpc subroutine is xdr_void.