ONC+ Developer's Guide

Multiple Client Versions

Because different hosts can run different versions of RPC servers, a client should be capable of accommodating the variations. For example, one server can run the old version of RUSERSPROG(RUSERSVERS_ORIG) while another server runs the newer version (RUSERSVERS_SHORT).

If the version on a server does not match the version number in the client creation call, clnt_call() fails with an RPCPROGVERSMISMATCH error. You can get the version numbers supported by a server and then create a client handle with the appropriate version number. Use either the routine in the following example, or clnt_create_vers(). See the rpc(3NSL) man page for more details.


Example 5–17 RPC Versions on Client Side

main()
{
	enum clnt_stat status;
	u_short num_s;
	u_int num_l;
	struct rpc_err rpcerr;
	int maxvers, minvers;
	CLIENT *clnt;
 
	clnt = clnt_create("remote", RUSERSPROG, RUSERSVERS_SHORT,
			             "datagram_v");
	if (clnt == (CLIENT *) NULL) {
		clnt_pcreateerror("unable to create client handle");
		exit(1);
	}
	to.tv_sec = 10;							      /* set the time outs */
	to.tv_usec = 0;
 
	status = clnt_call(clnt, RUSERSPROC_NUM, xdr_void,
	                  (caddr_t) NULL, xdr_u_short, 
 (caddr_t)&num_s, to);
	if (status == RPC_SUCCESS) {		/* Found latest version number */
		printf("num = %d\n", num_s);
		exit(0);
	}
	if (status != RPC_PROGVERSMISMATCH) {		/* Some other error */
		clnt_perror(clnt, "rusers");
		exit(1);
	}
	/* This version not supported */
	clnt_geterr(clnt, &rpcerr);
	maxvers = rpcerr.re_vers.high;		  /* highest version supported */
	minvers = rpcerr.re_vers.low;		     /*lowest version supported */

	if (RUSERSVERS_SHORT < minvers || RUSERSVERS_SHORT > maxvers)
{
			                           /* doesn't meet minimum standards */
		clnt_perror(clnt, "version mismatch");
		exit(1);
	}
	(void) clnt_control(clnt, CLSET_VERSION, RUSERSVERS_ORIG);
	status = clnt_call(clnt, RUSERSPROC_NUM, xdr_void,
(caddr_t) NULL, xdr_u_int, (caddr_t)&num_l, to);
	if (status == RPC_SUCCESS)
			                 /* We found a version number we recognize */
		printf("num = %d\n", num_l);
	else {
		clnt_perror(clnt, "rusers");
		exit(1);
	}
}