From 0a3522bab588d8308769f8696e3e7bc9fe5eb5af Mon Sep 17 00:00:00 2001 From: Olaf Kirch Date: Mon, 20 Jan 2014 11:43:37 +0100 Subject: [PATCH 19/23] rpcinfo: introduce new helper function ip_getclient This function tries to obtain the address of a given host/program/version, using the specified protocol (one of udp or tcp), and create a client handle for it. This loops over all netconfig entries (according to the order given by netpath and the config file), and tries to resolve the hostname, and obtain the address using rpcb_getaddr. Signed-off-by: Olaf Kirch --- src/rpcinfo.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/rpcinfo.c b/src/rpcinfo.c index 5983b07..89dee56 100644 --- a/src/rpcinfo.c +++ b/src/rpcinfo.c @@ -119,6 +119,7 @@ static CLIENT *clnt_com_create (struct sockaddr_in *, u_long, u_long, int *, char *); static void pmapdump (int, char **); static void get_inet_address (struct sockaddr_in *, char *); +static CLIENT *ip_getclient(const char *hostname, rpcprog_t prognum, rpcvers_t versnum, const char *proto); #endif static bool_t reply_proc (void *, struct netbuf *, struct netconfig *); @@ -649,6 +650,76 @@ get_inet_address (addr, host) addr->sin_family = AF_INET; } } + +/* + * Try to obtain the address of a given host/program/version, using the + * specified protocol (one of udp or tcp). + * This loops over all netconfig entries (according to the order given by + * netpath and the config file), and tries to resolve the hostname, and obtain + * the address using rpcb_getaddr. + */ +CLIENT * +ip_getclient(hostname, prognum, versnum, proto) + const char *hostname; + rpcprog_t prognum; + rpcvers_t versnum; + const char *proto; +{ + void *handle; + enum clnt_stat saved_stat = RPC_SUCCESS; + struct netconfig *nconf, *result = NULL; + struct netbuf bind_address; + struct sockaddr_storage __sa; + CLIENT *client; + + memset(&bind_address, 0, sizeof(bind_address)); + bind_address.maxlen = sizeof(__sa); + bind_address.buf = &__sa; + + handle = setnetconfig(); + while ((nconf = getnetconfig(handle)) != NULL) + { + if (!strcmp(nconf->nc_proto, proto)) { + if (rpcb_getaddr(prognum, versnum, nconf, &bind_address, hostname)) + { + result = getnetconfigent(nconf->nc_netid); + endnetconfig(handle); + break; + } + + if (rpc_createerr.cf_stat != RPC_UNKNOWNHOST) + { + clnt_pcreateerror (hostname); + exit (1); + } + + saved_stat = rpc_createerr.cf_stat; + } + } + + if (result == NULL) + { + if (saved_stat != RPC_SUCCESS) + { + rpc_createerr.cf_stat = saved_stat; + clnt_pcreateerror (hostname); + } + else + fprintf (stderr, "Cannot find suitable transport for protocol %s\n", proto); + + exit (1); + } + + client = clnt_tli_create(RPC_ANYFD, result, &bind_address, prognum, versnum, 0, 0); + if (client == NULL) + { + clnt_pcreateerror(hostname); + exit (1); + } + + freenetconfigent(result); + return client; +} #endif /* PORTMAP */ static int -- 1.7.12.4