ONC+ 開発ガイド

クライアント側

単純インタフェースのクライアント側には、rpc_call() という関数が 1 つだけあります。次の 9 個のパラメタがあります。

int	0 or error code
rpc_call (  
       char				*host		/* サーバホストの名前 */
       u_long			prognum		/* サーバプログラム番号 */
       u_long			versnum		/* サーババージョン番号 */
       xdrproc_t		inproc		/* 引数を符号化する XDR フィルタ */
       char				*in			/* 引数へのポインタ */
       xdr_proc_t		outproc		/* 結果を復号化するフィルタ */
       char				*out		/* 結果を格納するアドレス */
       char				*nettype	/* トランスポートの選択 */
);

この関数は、host 上で、prognumversumprocnum によって指定する手続きを呼び出します。遠隔手続きに渡される引数は、in パラメタによって指定され、inproc はこの引数を符号化するための XDR フィルタです。out パラメタは、遠隔手続きから戻される結果が置かれるアドレスです。outproc は、結果を復号化してこのアドレスに置く XDR フィルタです。

クライアントプログラムは、サーバから応答を得るまで rpc_call() のところで停止します。サーバが呼び出しを受け入れると、0 の値で RPC_SUCCESS を返します。呼び出しが失敗した場合は、0 以外の値が返されます。この値は、clnt_stat で指定される型に型変換されます。これは RPC インクルードファイルの中で定義される列挙型で、clnt_sperrno() 関数により解釈されます。この関数は、このエラーコードに対応する標準 RPC エラーメッセージへのポインタを返します。

この例では、/etc/netconfig に列挙されているすべての選択可能な可視トランスポートが試されます。試行回数を指定するには、下位レベルの RPC ライブラリを使用する必要があります。

複数の引数と複数の結果は、構造体に収集して扱われます。

例 4-1 を単純インタフェースを使用するために変更すると、例 4-2 のようになります。


例 4-2 単純インタフェースを使用する rusers プログラム

#include <stdio.h>
#include <utmp.h>
#include <rpc/rpc.h>
#include <rpcsvc/rusers.h>

/*
 *RUSERSPROG RPC プログラムを呼び出すプログラム
 */

main(argc, argv)
	int argc;
	char **argv;
{
	unsigned long nusers;
	enum clnt_stat cs;

	if (argc != 2) {
		   fprintf(stderr, "usage: rusers hostname¥n");
		   exit(1);
	}
	if( cs = rpc_call(argv[1], RUSERSPROG,
			 	RUSERSVERS,	RUSERSPROC_NUM, xdr_void,
					(char *)0, xdr_u_long, (char *)&nusers,
                    "visible")  !=  RPC_SUCCESS )  {
		          clnt_perrno(cs);
		          exit(1);
	           }
	fprintf(stderr, "%d users on %s¥n", nusers,
						argv[1] );
	exit(0);
}

マシンが異なれば、データ型も異なる表現になるため、rpc_call() は RPC 引数の型と RPC 引数へのポインタを必要とします (サーバから返される結果についても同様です)。RUSERSPROC_NUM の場合、戻り値は unsigned long 型であるため、rpc_call() の最初の戻りパラメタは xdr_u_long (unsigned long 用) で、2 番目は &nusers (unsigned long 型の値があるメモリへのポインタ)です。RUSERSPROC_NUM には引数がないため、rpc_call() の XDR 符号化関数は xdr_void() で、その引数は NULL です。