ONC+ 開発ガイド

旧バージョンとの比較

例 6–1例 6–2では、クライアント作成部分が TS-RPC と TI-RPC とでどう違うかを示します。どちらのプログラムも、次のことを実行します。


例 6–1 TS-RPC におけるクライアント作成

	struct hostent *h;
	struct sockaddr_in sin;
 int sock = RPC_ANYSOCK;
	u_short port;
	struct timeval wait;
 
	if ((h = gethostbyname( "host" )) == (struct hostent *) NULL)
{
		syslog(LOG_ERR, "gethostbyname failed");
		exit(1);
	}
 sin.sin_addr.s_addr = *(u_int *) hp->h_addr;
	if ((port = pmap_getport(&sin, PROGRAM, VERSION, "udp")) == 0) {
	 syslog (LOG_ERR, "pmap_getport failed");
		exit(1);
 } else
		sin.sin_port = htons(port);
	wait.tv_sec = 25;
	wait.tv_usec = 0;
	clntudp_create(&sin, PROGRAM, VERSION, wait, &sock);

次の例で示すように、TI-RPC では、UDP トランスポートは netid udp を持つものとみなします。netid はよく知られた名前でなくてもかまいません。


例 6–2 TI-RPC でのクライアント作成

	struct netconfig *nconf;
	struct netconfig *getnetconfigent();
	struct t_bind *tbind;
	struct timeval wait;

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *) NULL) {
		syslog(LOG_ERR, "getnetconfigent for udp failed");
		exit(1);
	}
	fd = t_open(nconf->nc_device, O_RDWR, (struct t_info *)NULL);
	if (fd == -1) {
		syslog(LOG_ERR, "t_open failed");
		exit(1);
	}
	tbind = (struct t_bind *) t_alloc(fd, T_BIND, T_ADDR);
	if (tbind == (struct t_bind *) NULL) {
		syslog(LOG_ERR, "t_bind failed");
		exit(1);
	}
	if (rpcb_getaddr( PROGRAM, VERSION, nconf, &tbind->addr, "host")
								== FALSE) {
		syslog(LOG_ERR, "rpcb_getaddr failed");
		exit(1);
	}
	cl = clnt_tli_create(fd, nconf, &tbind->addr, PROGRAM, VERSION,
	                      0, 0);
	(void) t_free((char *) tbind, T_BIND);
	if (cl == (CLIENT *) NULL) {
		syslog(LOG_ERR, "clnt_tli_create failed");
		exit(1);
	}
	wait.tv_sec = 25;
	wait.tv_usec = 0;
	clnt_control(cl, CLSET_TIMEOUT, (char *) &wait);

例 6–3例 6–4 では、ブロードキャスト部分が旧バージョンと SunOS 5.x とでどう違うかを示します。SunOS 4.xclnt_broadcast() は SunOS 5.xrpc_broadcast() とほぼ同じです。大きく異なるのは、collectnames() 関数です。 collectnames() 関数は、重複アドレスを削除ブロードキャストに応答したホスト名を表示します。


例 6–3 TS-RPC におけるブロードキャスト

statstime sw;
extern int collectnames();
 
clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,         
    	xdr_void, NULL, xdr_statstime, &sw, collectnames);
	...
collectnames(resultsp, raddrp)
	char *resultsp;
	struct sockaddr_in *raddrp;
{
	u_int addr;
	struct entry *entryp, *lim;
	struct hostent *hp;
	extern int curentry;
 
	/* 重複アドレスはカット */
 addr = raddrp->sin_addr.s_addr;
	lim = entry + curentry;
 for (entryp = entry; entryp < lim; entryp++)
		if (addr == entryp->addr)
			return (0);
	...
 /* ホスト名がわかればホスト名、わからなければアドレスを表示 */
	hp = gethostbyaddr(&raddrp->sin_addr.s_addr, sizeof(u_int),
	    AF_INET);
	if( hp == (struct hostent *) NULL)
		printf("0x%x", addr);
	else
 	printf("%s", hp->h_name);
}
 

次に、TI-RPC におけるブロードキャストを示します。


例 6–4 TI-RPC におけるブロードキャスト

statstime sw;
extern int collectnames();
 
rpc_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
     xdr_void, NULL, xdr_statstime, &sw, collectnames, (char *)
0);
	...
collectnames(resultsp, taddr, nconf)
	char *resultsp;
	struct t_bind *taddr;
	struct netconfig *nconf;
{
 struct entry *entryp, *lim;
	struct nd_hostservlist *hs;
 extern int curentry;
	extern int netbufeq();
 
	/* 重複アドレスはカット */
	lim = entry + curentry;
	for (entryp = entry; entryp < lim; entryp++)
		if (netbufeq( &taddr->addr, entryp->addr))
			return (0);
 ...
	/* ホスト名がわかればホスト名、わからなければアドレスを表示 */
	if (netdir_getbyaddr( nconf, &hs, &taddr->addr ) == ND_OK)
 	printf("%s", hs->h_hostservs->h_host);
	else {
 	char *uaddr = taddr2uaddr(nconf, &taddr->addr);
		if (uaddr) {
			printf("%s\n", uaddr);
			(void) free(uaddr);
 	} else
			printf("unknown");
	}
}
netbufeq(a, b)
	struct netbuf *a, *b;
{
	return(a->len == b->len && !memcmp( a->buf, b->buf, a->len));
}