-
-/*
- * Sigh... getport() doesn't actually check the version number.
- * In order to make sure that the server actually supports the service
- * we're requesting, we open and RPC client, and fire off a NULL
- * RPC call.
- */
-int
-clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
- const u_int prot, struct sockaddr_in *caddr)
-{
- CLIENT *clnt=NULL;
- int sock, stat;
- static char clnt_res;
- struct sockaddr dissolve;
-
- rpc_createerr.cf_stat = stat = errno = 0;
- sock = get_socket(saddr, prot, FALSE, TRUE);
- if (sock == RPC_ANYSOCK) {
- if (errno == ETIMEDOUT) {
- /*
- * TCP timeout. Bubble up the error to see
- * how it should be handled.
- */
- rpc_createerr.cf_stat = RPC_TIMEDOUT;
- }
- return 0;
- }
-
- if (caddr) {
- /* Get the address of our end of this connection */
- socklen_t len = sizeof(*caddr);
- if (getsockname(sock, caddr, &len) != 0)
- caddr->sin_family = 0;
- }
-
- switch(prot) {
- case IPPROTO_UDP:
- /* The socket is connected (so we could getsockname successfully),
- * but some servers on multi-homed hosts reply from
- * the wrong address, so if we stay connected, we lose the reply.
- */
- dissolve.sa_family = AF_UNSPEC;
- connect(sock, &dissolve, sizeof(dissolve));
-
- clnt = clntudp_bufcreate(saddr, prog, vers,
- RETRY_TIMEOUT, &sock,
- RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
- break;
- case IPPROTO_TCP:
- clnt = clnttcp_create(saddr, prog, vers, &sock,
- RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
- break;
- }
- if (!clnt) {
- close(sock);
- return 0;
- }
- memset(&clnt_res, 0, sizeof(clnt_res));
- stat = clnt_call(clnt, NULLPROC,
- (xdrproc_t)xdr_void, (caddr_t)NULL,
- (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
- TIMEOUT);
- if (stat) {
- clnt_geterr(clnt, &rpc_createerr.cf_error);
- rpc_createerr.cf_stat = stat;
- }
- clnt_destroy(clnt);
- close(sock);
-
- if (stat == RPC_SUCCESS)
- return 1;
- else
- return 0;
-}
-
-CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
-{
- struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
- struct pmap *mnt_pmap = &mnt_server->pmap;
- CLIENT *clnt = NULL;
-
- /* contact the mount daemon via TCP */
- mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
- *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE, FALSE);
-
- switch (mnt_pmap->pm_prot) {
- case IPPROTO_UDP:
- clnt = clntudp_bufcreate(mnt_saddr,
- mnt_pmap->pm_prog, mnt_pmap->pm_vers,
- RETRY_TIMEOUT, msock,
- MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
- break;
- case IPPROTO_TCP:
- clnt = clnttcp_create(mnt_saddr,
- mnt_pmap->pm_prog, mnt_pmap->pm_vers,
- msock,
- MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
- break;
- }
- if (clnt) {
- /* try to mount hostname:dirname */
- clnt->cl_auth = authunix_create_default();
- return clnt;
- }
- return NULL;
-}
-
-void mnt_closeclnt(CLIENT *clnt, int msock)
-{
- auth_destroy(clnt->cl_auth);
- clnt_destroy(clnt);
- close(msock);
-}
-