Esempio n. 1
0
char *
clnt_spcreateerror(
	char *s)
{
	char *str = _buf();

	if (str == 0)
		return(0);
	(void) sprintf(str, "%s: ", s);
	(void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat));
	switch (rpc_createerr.cf_stat) {
	case RPC_PMAPFAILURE:
		(void) strcat(str, " - ");
		(void) strcat(str,
		    clnt_sperrno(rpc_createerr.cf_error.re_status));
		break;

	case RPC_SYSTEMERROR: {
		const char*	errmsg =
		    strerror(rpc_createerr.cf_error.re_errno);

		(void) strcat(str, " - ");
		if (NULL != errmsg)
			(void) strcat(str, errmsg);
		else
			(void) sprintf(&str[strlen(str)], "Error %d",
			    rpc_createerr.cf_error.re_errno);
		break;
	    }
	}
	(void) strcat(str, "\n");
	return (str);
}
Esempio n. 2
0
char *
clnt_spcreateerror (const char *msg)
{
  char chrbuf[1024];
  char *str = _buf ();
  char *cp;
  int len;
  struct rpc_createerr *ce;

  if (str == NULL)
    return NULL;
  ce = &get_rpc_createerr ();
  len = sprintf (str, "%s: ", msg);
  cp = str + len;
  cp = stpcpy (cp, clnt_sperrno (ce->cf_stat));
  switch (ce->cf_stat)
    {
    case RPC_PMAPFAILURE:
      cp = stpcpy (stpcpy (cp, " - "),
		   clnt_sperrno (ce->cf_error.re_status));
      break;

    case RPC_SYSTEMERROR:
      cp = stpcpy (stpcpy (cp, " - "),
		   __strerror_r (ce->cf_error.re_errno,
				 chrbuf, sizeof chrbuf));
      break;
    default:
      break;
    }
  *cp = '\n';
  *++cp = '\0';
  return str;
}
Esempio n. 3
0
char *
clnt_spcreateerror(
	const char *s)
{
	char *str = _buf();

	if (str == 0)
		return(0);
	switch (rpc_createerr.cf_stat) {
	case RPC_PMAPFAILURE:
		(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
		    clnt_sperrno(rpc_createerr.cf_stat),
		    clnt_sperrno(rpc_createerr.cf_error.re_status));
		break;

	case RPC_SYSTEMERROR:
		(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
		    clnt_sperrno(rpc_createerr.cf_stat),
		    strerror(rpc_createerr.cf_error.re_errno));
		break;
	default:
		(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
		clnt_sperrno(rpc_createerr.cf_stat));
		break;
	}
	str[CLNT_PERROR_BUFLEN-2] = '\n';
	str[CLNT_PERROR_BUFLEN-1] = '\0';
	return (str);
}
Esempio n. 4
0
char *
clnt_spcreateerror(char *s)
{
	switch (rpc_createerr.cf_stat) {
	case RPC_PMAPFAILURE:
		(void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
		    clnt_sperrno(rpc_createerr.cf_stat),
		    clnt_sperrno(rpc_createerr.cf_error.re_status));
		break;

	case RPC_SYSTEMERROR:
		(void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
		    clnt_sperrno(rpc_createerr.cf_stat),
		    strerror(rpc_createerr.cf_error.re_errno));
		break;

	default:
		(void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
		    clnt_sperrno(rpc_createerr.cf_stat));
		break;
	}
	buf[CLNT_PERROR_BUFLEN-2] = '\n';
	buf[CLNT_PERROR_BUFLEN-1] = '\0';
	return (buf);
}
Esempio n. 5
0
void
clnt_perrno (enum clnt_stat num)
{
#ifdef USE_IN_LIBIO
  if (_IO_fwide (stderr, 0) > 0)
    (void) fwprintf (stderr, L"%s", clnt_sperrno (num));
  else
#endif
    (void) fputs (clnt_sperrno (num), stderr);
}
Esempio n. 6
0
char *
clnt_spcreateerror(char *s)
{
	char *str = get_buf();
	char *strend;

	if (str == 0)
		return(0);
	strend = str+BUFSIZ;
	(void) snprintf(str, strend-str, "%s: ", s);
	str[BUFSIZ - 1] = '\0';
	(void) strncat(str, clnt_sperrno(rpc_createerr.cf_stat), BUFSIZ - 1);
	switch (rpc_createerr.cf_stat) {
	case RPC_PMAPFAILURE:
		(void) strncat(str, " - ", BUFSIZ - 1 - strlen(str));
		(void) strncat(str,
		    clnt_sperrno(rpc_createerr.cf_error.re_status),
		    BUFSIZ - 1 - strlen(str));
		break;

	case RPC_SYSTEMERROR:
		(void) strncat(str, " - ", BUFSIZ - 1 - strlen(str));
		{
		    const char *m = strerror(rpc_createerr.cf_error.re_errno);
		    if (m)
			(void) strncat(str, m, BUFSIZ - 1 - strlen(str));
		    else
			(void) snprintf(&str[strlen(str)], BUFSIZ - strlen(str),
					"Error %d",
					rpc_createerr.cf_error.re_errno);
		}
		break;

	case RPC_CANTSEND:
	case RPC_CANTDECODERES:
	case RPC_CANTENCODEARGS:
	case RPC_SUCCESS:
	case RPC_UNKNOWNPROTO:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
	case RPC_UNKNOWNHOST:
	case RPC_CANTDECODEARGS:
	case RPC_PROCUNAVAIL:
	case RPC_PROGVERSMISMATCH:
	case RPC_PROGUNAVAIL:
	case RPC_AUTHERROR:
	case RPC_VERSMISMATCH:
	case RPC_TIMEDOUT:
	case RPC_CANTRECV:
	default:
	    break;
	}
	(void) strncat(str, "\n", BUFSIZ - 1 - strlen(str));
	return (str);
}
Esempio n. 7
0
char *
clnt_spcreateerror(const char *s)
{
	char *str;
	size_t len, i;

	assert(s != NULL);

	str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
	if (str == NULL)
		return(0);
	len = CLNT_PERROR_BUFLEN;
	i = snprintf(str, len, "%s: ", s);
	if (i > 0)
		len -= i;
	(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
	switch (rpc_createerr.cf_stat) {
	case RPC_PMAPFAILURE:
		(void) strncat(str, " - ", len - 1);
		(void) strncat(str,
		    clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
		break;

	case RPC_SYSTEMERROR:
		(void)strncat(str, " - ", len - 1);
		(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
		    len - 4);
		break;

	case RPC_CANTSEND:
	case RPC_CANTDECODERES:
	case RPC_CANTENCODEARGS:
	case RPC_SUCCESS:
	case RPC_UNKNOWNPROTO:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
	case RPC_UNKNOWNHOST:
	case RPC_CANTDECODEARGS:
	case RPC_PROCUNAVAIL:
	case RPC_PROGVERSMISMATCH:
	case RPC_PROGUNAVAIL:
	case RPC_AUTHERROR:
	case RPC_VERSMISMATCH:
	case RPC_TIMEDOUT:
	case RPC_CANTRECV:
	default:
		break;
	}
	str[CLNT_PERROR_BUFLEN-1] = '\0';
	return (str);
}
Esempio n. 8
0
static int
test_read_cb(nct_req_t *req)
{
    test_read_priv_t *priv = req->req_priv;
    nct_mnt_t *mnt = req->req_mnt;
    nct_vn_t *vn = mnt->mnt_vn;
    off_t offset;

    XDR_DESTROY(&req->req_msg->msg_xdr);

    if (req->req_msg->msg_stat != RPC_SUCCESS) {
        eprint("read failed: %d %s\n",
               req->req_msg->msg_stat, clnt_sperrno(req->req_msg->msg_stat));
        nct_req_free(req);
        return req->req_msg->msg_stat;
    }

    if (req->req_tsc_stop >= req->req_tsc_finish) {
        nct_req_free(req);
        return ETIMEDOUT;
    }

    offset = __sync_fetch_and_add(&priv->pr_offset, priv->pr_length);

    if (offset + priv->pr_length > vn->xvn_fattr.size) {
        offset = __sync_fetch_and_sub(&priv->pr_offset, priv->pr_offset);
    }

    nct_nfs_read3_encode(req, offset, priv->pr_length);
    nct_req_send(req);

    return 0;
}
Esempio n. 9
0
char * clnt_sperror(struct client *clnt, const char *msg) {
	/* FIXME should use snprintf instead sprintf */
	static char buff[ERROR_STR_MAX_SZ];
	struct rpc_err err;
	char *curr, *auth_msg;

	assert((clnt != NULL) && (msg != NULL));

	clnt_geterr(clnt, &err);

	curr = buff;
	curr += sprintf(curr, "%s: %s", msg, clnt_sperrno(err.status));
	switch (err.status) {
	default:
		curr += sprintf(curr, "; s1 = %u, s2 = %u", err.extra.mminfo.low,
				err.extra.mminfo.high);
		break;
	case RPC_SUCCESS:
	case RPC_CANTENCODEARGS:
	case RPC_CANTDECODERES:
	case RPC_TIMEDOUT:
	case RPC_PROGUNAVAIL:
	case RPC_PROCUNAVAIL:
	case RPC_CANTDECODEARGS:
	case RPC_SYSTEMERROR:
	case RPC_UNKNOWNHOST:
	case RPC_PMAPFAILURE:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
	case RPC_UNKNOWNPROTO:
		break;
	case RPC_CANTSEND:
	case RPC_CANTRECV:
		curr += sprintf(curr, "; errno = %s", strerror(err.extra.error));
		break;
	case RPC_VERSMISMATCH:
		curr += sprintf(curr, "; low version = %u, high version = %u",
				err.extra.mminfo.low, err.extra.mminfo.high);
		break;
	case RPC_AUTHERROR:
		auth_msg = get_auth_msg(err.extra.reason);
		if (auth_msg != NULL) {
			curr += sprintf(curr, "; why = %s", auth_msg);
		}
		else {
			curr += sprintf(curr, "; why = (unknown authentication error - %d)",
					err.extra.reason);
		}
		break;
	case RPC_PROGVERSMISMATCH:
		curr += sprintf(curr, "; low version = %u, high version = %u",
				err.extra.mminfo.low, err.extra.mminfo.high);
		break;
	}

	assert(curr < buff + sizeof buff); // TODO remove this

	return buff;
}
Esempio n. 10
0
/*
 * init_nsm --
 *	Reset the NSM state-of-the-world and acquire its state.
 */
void
init_nsm(void)
{
	enum clnt_stat ret;
	my_id id;
	sm_stat stat;
	char name[] = "NFS NLM";

	/*
	 * !!!
	 * The my_id structure isn't used by the SM_UNMON_ALL call, as far
	 * as I know.  Leave it empty for now.
	 */
	memset(&id, 0, sizeof(id));
	id.my_name = name;

	/*
	 * !!!
	 * The statd program must already be registered when lockd runs.
	 */
	do {
		ret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON_ALL,
		    (xdrproc_t)xdr_my_id, &id, (xdrproc_t)xdr_sm_stat, &stat);
		if (ret == RPC_PROGUNAVAIL) {
			syslog(LOG_WARNING, "%lu %s", SM_PROG,
			    clnt_sperrno(ret));
			sleep(2);
			continue;
		}
		break;
	} while (0);

	if (ret != 0) {
		syslog(LOG_ERR, "%lu %s", SM_PROG, clnt_sperrno(ret));
		exit(1);
	}

	nsm_state = stat.state;

	/* setup constant data for SM_MON calls */
	mon_host.mon_id.my_id.my_name = localhost;
	mon_host.mon_id.my_id.my_prog = NLM_PROG;
	mon_host.mon_id.my_id.my_vers = NLM_SM;
	mon_host.mon_id.my_id.my_proc = NLM_SM_NOTIFY;  /* bsdi addition */
}
Esempio n. 11
0
/*
 * Send a product from file-descriptor to clnt using LDM-5 protocol.
 */
static void
send_product_5(CLIENT *clnt, int fd, prod_info *infop)
{
        static ldm_replyt reply;
        enum clnt_stat rpc_stat;
        datapkt pkt;
        ssize_t unsent;
        ssize_t nread;
        char buf[DBUFMAX];

        rpc_stat = my_comingsoon_5(clnt, infop, DBUFMAX, &reply);
        if(rpc_stat != RPC_SUCCESS)
        {
                uerror("send_product_5: %s %s",
                        infop->ident,
                        clnt_sperrno(rpc_stat));
                return;
        }
        /* else */

        if(reply.code != OK)
        {
                if(reply.code == DONT_SEND)
                   uinfo("send_product_5: %s: %s",
                        infop->ident,
                        s_ldm_errt(reply.code));
                else
                   uerror("send_product_5: %s: %s",
                        infop->ident,
                        s_ldm_errt(reply.code));
                return;
        }

        pkt.signaturep = &infop->signature;
        pkt.pktnum = 0;

        for(unsent = (ssize_t)infop->sz; unsent > 0;
                        unsent -= nread )
        {
                nread = read(fd, buf, DBUFMAX);
                if(nread <= 0)
                {
                        serror("read: %s (seqno %d)",
                                infop->ident, infop->seqno);
                        break;
                } /* else */
                pkt.data.dbuf_len = (u_int)nread;
                pkt.data.dbuf_val = buf;
                rpc_stat = my_blkdata_5(clnt, &pkt, &reply);
                if(rpc_stat != RPC_SUCCESS)
                        break;
                if(reply.code != OK)
                        break;
                pkt.pktnum++;
        }
}
Esempio n. 12
0
/*
 * Create a unix style authenticator.
 * Returns an auth handle with the given stuff in it.
 */
AUTH *
authunix_ncreate(char *machname, uid_t uid, gid_t gid, int len,
		 gid_t *aup_gids)
{
	struct audata *au = mem_alloc(sizeof(*au));
	AUTH *auth = &au->au_auth;
	struct authunix_parms aup;
	struct timespec now;
	XDR xdrs;

	/*
	 * Allocate and set up auth handle
	 */
	auth->ah_ops = authunix_ops();
	auth->ah_private = NULL;
	auth->ah_error.re_status = RPC_SUCCESS;
	auth->ah_verf = au->au_shcred = _null_auth;
	auth->ah_refcnt = 1;
	au->au_shfaults = 0;

	/*
	 * fill in param struct from the given params
	 */
	(void)clock_gettime(CLOCK_MONOTONIC_FAST, &now);
	aup.aup_time = now.tv_sec;
	aup.aup_machname = machname;
	aup.aup_uid = uid;
	aup.aup_gid = gid;
	aup.aup_len = (u_int) len;
	aup.aup_gids = aup_gids;

	/*
	 * Serialize the parameters into origcred
	 */
	xdrmem_create(&xdrs, au->au_origcred.oa_body, MAX_AUTH_BYTES,
		      XDR_ENCODE);
	if (!xdr_authunix_parms(&xdrs, &aup)) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH, "%s: %s",
			__func__, clnt_sperrno(RPC_CANTENCODEARGS));
		auth->ah_error.re_status = RPC_CANTENCODEARGS;
		return (auth);
	}
	au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
	au->au_origcred.oa_flavor = AUTH_UNIX;

	/*
	 * set auth handle to reflect new cred.
	 */
	auth->ah_cred = au->au_origcred;
	/* auth_get not needed:  ah_refcnt == 1, as desired */
	marshal_new_auth(auth);
	/* */
	return (auth);
}
Esempio n. 13
0
static void
allhosts(void)
{
    statstime host_stat;
    enum clnt_stat clnt_stat;

    clnt_stat = clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
                               (xdrproc_t)xdr_void, NULL,
                               (xdrproc_t)xdr_statstime, &host_stat,
                               (resultproc_t)rstat_reply);
    if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
        errx(1, "%s", clnt_sperrno(clnt_stat));
}
Esempio n. 14
0
static int
bind_tohost(struct sockaddr_in *sin, char *dom, char *server)
{
	struct ypbind_setdom ypsd;
	struct in_addr iaddr;
	struct hostent *hp;
	struct timeval tv;
	CLIENT *client;
	int sock, port, r;

	port = getrpcport(server, YPPROG, YPPROC_NULL, IPPROTO_UDP);
	if (port == 0)
		errx(1, "%s not running ypserv", server);
	port = htons(port);

	memset(&ypsd, 0, sizeof ypsd);

	if (inet_aton(server, &iaddr) == 0) {
		hp = gethostbyname(server);
		if (hp == NULL)
			errx(1, "can't find address for %s", server);
		memmove(&iaddr.s_addr, hp->h_addr, sizeof(iaddr.s_addr));
	}
	ypsd.ypsetdom_domain = dom;
	bcopy(&iaddr.s_addr, &ypsd.ypsetdom_binding.ypbind_binding_addr,
	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_addr));
	bcopy(&port, &ypsd.ypsetdom_binding.ypbind_binding_port,
	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_port));
	ypsd.ypsetdom_vers = YPVERS;

	tv.tv_sec = 15;
	tv.tv_usec = 0;
	sock = RPC_ANYSOCK;
	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
	if (client == NULL) {
		warnx("can't yp_bind: reason: %s", yperr_string(YPERR_YPBIND));
		return YPERR_YPBIND;
	}
	client->cl_auth = authunix_create_default();

	r = clnt_call(client, YPBINDPROC_SETDOM,
	    xdr_ypbind_setdom, &ypsd, xdr_void, NULL, tv);
	if (r) {
		warnx("Cannot ypset for domain %s on host %s: %s", dom,
		    server, clnt_sperrno(r));
		clnt_destroy(client);
		return YPERR_YPBIND;
	}
	clnt_destroy(client);
	return 0;
}
Esempio n. 15
0
static void
allhosts(void)
{
	utmpidlearr up;
	enum clnt_stat clnt_stat;

	bzero((char *)&up, sizeof(up));
	clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE,
	    RUSERSPROC_NAMES, (xdrproc_t)xdr_void, NULL,
	    (xdrproc_t)xdr_utmpidlearr, (char *)&up,
	    (resultproc_t)rusers_reply);
	if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
		errx(1, "%s", clnt_sperrno(clnt_stat));
}
Esempio n. 16
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1; //Default test result set to FAILED
	int progNum = atoi(argc[2]);
	char nettype[16] = "udp";
	CLIENT *clnt = NULL;
	enum clnt_stat rslt;
    int recVar = -1;
    struct timeval total_timeout;
    char *chrRslt = NULL;

	if (run_mode == 1)
	{
		printf("Server : %s\n", argc[1]);
		printf("Server # %d\n", progNum);
		printf("Net : %s\n", nettype);
	}

	//Initialisation
	total_timeout.tv_sec = 1;
	total_timeout.tv_usec = 1;/**/

	//First of all, create client using top level API
	clnt = clnt_create(argc[1], progNum, VERSNUM, nettype);

	//Then call remote procedure
	rslt = clnt_call((CLIENT *)clnt, PROCNUM,
						    (xdrproc_t)xdr_int, (char *)&recVar, // xdr_in
                    		(xdrproc_t)xdr_int, (char *)&recVar, // xdr_out
						    total_timeout);	/**/

	chrRslt = clnt_sperrno(rslt);

	//If we are here, test has passed
	test_status = (chrRslt == NULL);

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Esempio n. 17
0
char * clnt_spcreateerror(const char *msg) {
	/* FIXME should use snprintf instead sprintf */
	static char buff[ERROR_STR_MAX_SZ];
	char *curr;

	assert(msg != NULL);

	curr = buff;
	curr += sprintf(curr, "%s: %s", msg, clnt_sperrno(rpc_create_error.stat));
	switch (rpc_create_error.stat) {
	default:
		break;
	case RPC_PMAPFAILURE:
		curr += sprintf(curr, " - %s", clnt_sperrno(rpc_create_error.err.status));
		break;
	case RPC_SYSTEMERROR:
		curr += sprintf(curr, " - %s", strerror(rpc_create_error.err.extra.error));
		break;
	}

	assert(curr < buff + sizeof buff); // TODO remove this

	return buff;
}
Esempio n. 18
0
static int lpm_call (int type, char *ip, char *op)
{
	struct timeval tv;
	Parm *pm;

	if (type < LPMINIT || type > LPMMAXPROC)
		return 0;

	pm = &LpmParm[type];

	if (!lpm_cl)
		if (!lpm_clnt_create ())
			return 0;
	
	tv.tv_sec = 25;
	tv.tv_usec = 0;

	LpmRpcError = clnt_call (lpm_cl, type, (xdrproc_t)pm->ixdr, ip, (xdrproc_t)pm->oxdr, op, tv);
	if (LpmRpcError != RPC_SUCCESS)
	{

		strcpy (lpm_errmsg, clnt_sperrno (LpmRpcError));

		switch (LpmRpcError) {
		default:
			return 0;
		case RPC_CANTSEND:				/* failure in sending call */
		case RPC_CANTRECV:				/* failure in receiving result */
		case RPC_TIMEDOUT:				/* call timed out */
			break;
		}

		lpm_clnt_create ();
		if (!lpm_cl)
			return 0;

		if (clnt_call (lpm_cl, type, (xdrproc_t)pm->ixdr, ip, (xdrproc_t)pm->oxdr, op, tv) != RPC_SUCCESS)
			return 0;
	}

	return 1;
}
Esempio n. 19
0
/*
 * Purpose:	Transmit result for nlm4_xxx_msg pseudo-RPCs
 * Returns:	Nothing - we have no idea if the datagram got there
 * Notes:	clnt_call() will always fail (with timeout) as we are
 *		calling it with timeout 0 as a hack to just issue a datagram
 *		without expecting a result
 */
void
transmit4_result(int opcode, nlm4_res *result, struct sockaddr_in *addr)
{
	static char dummy;
	CLIENT *cli;
	struct timeval timeo;
	int success;

	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
		/* No timeout - not expecting response */
		timerclear(&timeo);

		success = clnt_call(cli, opcode, xdr_nlm4_res,
		    result, xdr_void, &dummy, timeo);

		if (debug_level > 2)
			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
			    success, clnt_sperrno(success));
	}
}
Esempio n. 20
0
static int
my_hiya_5(CLIENT *clnt, prod_class_t **clsspp)
{
        static ldm_replyt reply;
        enum clnt_stat rpc_stat;

        memset(&reply, 0, sizeof(ldm_replyt));

        rpc_stat = clnt_call(clnt, HIYA,
                xdr_prod_class, (caddr_t)*clsspp,
                xdr_ldm_replyt, (caddr_t)&reply,
                timeo);

        if(rpc_stat != RPC_SUCCESS)
        {
                uerror("hiya %s:  %s", remote, clnt_sperrno(rpc_stat));
                return ECONNABORTED; /* Perhaps could be more descriptive */
        }
        switch (reply.code) {
                case OK:
                        break;
                case SHUTTING_DOWN:
                        uerror("%s is shutting down", remote);
                        return ECONNABORTED;
                case DONT_SEND:
                case RESTART:
                case REDIRECT: /* TODO */
                default:
                        uerror("%s: unexpected reply type %s",
                                remote, s_ldm_errt(reply.code));
                        return ECONNABORTED;
                case RECLASS:
                        *clsspp = reply.ldm_replyt_u.newclssp;
                        clss_regcomp(*clsspp);
                        /* N.B. we use the downstream patterns */
                        unotice("%s: reclass: %s",
                                remote, s_prod_class(NULL, 0, *clsspp));
                        break;
        }
        return 0;
}
Esempio n. 21
0
/*
 * Check if the portmapper is running and reachable: 0==down, 1==up
 */
int check_pmap_up(char *host, struct sockaddr_in* sin)
{
  CLIENT *client;
  enum clnt_stat clnt_stat = RPC_TIMEDOUT; /* assume failure */
  int socket = RPC_ANYSOCK;
  struct timeval timeout;

  timeout.tv_sec = 2;
  timeout.tv_usec = 0;
  sin->sin_port = htons(PMAPPORT);
  client = clntudp_create(sin, PMAPPROG, PMAPVERS, timeout, &socket);

  if (client == (CLIENT *) NULL) {
    plog(XLOG_ERROR,
	 "check_pmap_up: cannot create connection to contact portmapper on host \"%s\"%s",
	 host, clnt_spcreateerror(""));
    return 0;
  }

  timeout.tv_sec = 6;
  /* Ping the portmapper on a remote system by calling the nullproc */
  clnt_stat = clnt_call(client,
			PMAPPROC_NULL,
			(XDRPROC_T_TYPE) xdr_void,
			NULL,
			(XDRPROC_T_TYPE) xdr_void,
			NULL,
			timeout);
  clnt_destroy(client);
  close(socket);
  sin->sin_port = 0;

  if (clnt_stat == RPC_TIMEDOUT) {
    plog(XLOG_ERROR,
	 "check_pmap_up: failed to contact portmapper on host \"%s\": %s",
	 host, clnt_sperrno(clnt_stat));
    return 0;
  }
  return 1;
}
Esempio n. 22
0
/* Convert RPC errors into strings */
static int rpc_strerror(int spos)
{
	int cf_stat = rpc_createerr.cf_stat;
	int pos = 0, cf_errno = rpc_createerr.cf_error.re_errno;
	char *ptr, *estr = clnt_sperrno(cf_stat);
	char *tmp;

	if (estr) {
		if ((ptr = index(estr, ':')))
			estr = ++ptr;

		tmp = &errbuf[spos];
		if (cf_stat == RPC_SYSTEMERROR)
			pos = snprintf(tmp, (erreob - tmp),
					_("System Error: %s"),
						strerror(cf_errno));
		else
			pos = snprintf(tmp, (erreob - tmp),
					_("RPC Error:%s"), estr);
	}
	return pos;
}
Esempio n. 23
0
/*
 * Print reply error info
 */
char *
clnt_sperror (CLIENT * rpch, const char *msg)
{
  char chrbuf[1024];
  struct rpc_err e;
  char *err;
  char *str = _buf ();
  char *strstart = str;
  int len;

  if (str == NULL)
    return NULL;
  CLNT_GETERR (rpch, &e);

  len = sprintf (str, "%s: ", msg);
  str += len;

  (void) strcpy(str, clnt_sperrno(e.re_status));
  str += strlen(str);

  switch (e.re_status)
    {
    case RPC_SUCCESS:
    case RPC_CANTENCODEARGS:
    case RPC_CANTDECODERES:
    case RPC_TIMEDOUT:
    case RPC_PROGUNAVAIL:
    case RPC_PROCUNAVAIL:
    case RPC_CANTDECODEARGS:
    case RPC_SYSTEMERROR:
    case RPC_UNKNOWNHOST:
    case RPC_UNKNOWNPROTO:
    case RPC_PMAPFAILURE:
    case RPC_PROGNOTREGISTERED:
    case RPC_FAILED:
      break;

    case RPC_CANTSEND:
    case RPC_CANTRECV:
      strerror_r (e.re_errno, chrbuf, sizeof chrbuf);
      len = sprintf (str, "; errno = %s", chrbuf);
      str += len;
      break;

    case RPC_VERSMISMATCH:
      len= sprintf (str, _("; low version = %lu, high version = %lu"),
		    e.re_vers.low, e.re_vers.high);
      str += len;
      break;

    case RPC_AUTHERROR:
      err = auth_errmsg (e.re_why);
      (void) strcpy(str, _("; why = "));
      str += strlen(str);

      if (err != NULL)
	{
	  (void) strcpy(str, err);
	  str += strlen(str);
	}
      else
	{
	  len = sprintf (str, _("(unknown authentication error - %d)"),
			 (int) e.re_why);
	  str += len;
	}
      break;

    case RPC_PROGVERSMISMATCH:
      len = sprintf (str, _("; low version = %lu, high version = %lu"),
		     e.re_vers.low, e.re_vers.high);
      str += len;
      break;

    default:			/* unknown */
      len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2);
      str += len;
      break;
    }
  *str = '\n';
  *++str = '\0';
  return (strstart);
}
Esempio n. 24
0
static int
do_rquota_user(struct fs_quota_root *root,
	       uint64_t *bytes_value_r, uint64_t *bytes_limit_r,
	       uint64_t *count_value_r, uint64_t *count_limit_r)
{
	struct getquota_rslt result;
	struct getquota_args args;
	struct timeval timeout;
	enum clnt_stat call_status;
	CLIENT *cl;
	struct fs_quota_mountpoint *mount = root->mount;
	const char *host;
	char *path;

	path = strchr(mount->device_path, ':');
	i_assert(path != NULL);

	host = t_strdup_until(mount->device_path, path);
	path++;

	/* For NFSv4, we send the filesystem path without initial /. Server
	   prepends proper NFS pseudoroot automatically and uses this for
	   detection of NFSv4 mounts. */
	if (strcmp(root->mount->type, "nfs4") == 0) {
		while (*path == '/')
			path++;
	}

	if (root->root.quota->set->debug) {
		i_debug("quota-fs: host=%s, path=%s, uid=%s",
			host, path, dec2str(root->uid));
	}

	/* clnt_create() polls for a while to establish a connection */
	cl = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp");
	if (cl == NULL) {
		i_error("quota-fs: could not contact RPC service on %s",
			host);
		return -1;
	}

	/* Establish some RPC credentials */
	auth_destroy(cl->cl_auth);
	cl->cl_auth = authunix_create_default();

	/* make the rquota call on the remote host */
	args.gqa_pathp = path;
	args.gqa_uid = root->uid;

	timeout.tv_sec = RQUOTA_GETQUOTA_TIMEOUT_SECS;
	timeout.tv_usec = 0;
	call_status = clnt_call(cl, RQUOTAPROC_GETQUOTA,
				(xdrproc_t)xdr_getquota_args, (char *)&args,
				(xdrproc_t)xdr_getquota_rslt, (char *)&result,
				timeout);
	
	/* the result has been deserialized, let the client go */
	auth_destroy(cl->cl_auth);
	clnt_destroy(cl);

	if (call_status != RPC_SUCCESS) {
		const char *rpc_error_msg = clnt_sperrno(call_status);

		i_error("quota-fs: remote rquota call failed: %s",
			rpc_error_msg);
		return -1;
	}

	switch (result.status) {
	case Q_OK: {
		rquota_get_result(&result.getquota_rslt_u.gqr_rquota,
				  bytes_value_r, bytes_limit_r,
				  count_value_r, count_limit_r);
		if (root->root.quota->set->debug) {
			i_debug("quota-fs: uid=%s, bytes=%llu/%llu files=%llu/%llu",
				dec2str(root->uid),
				(unsigned long long)*bytes_value_r,
				(unsigned long long)*bytes_limit_r,
				(unsigned long long)*count_value_r,
				(unsigned long long)*count_limit_r);
		}
		return 1;
	}
	case Q_NOQUOTA:
		if (root->root.quota->set->debug) {
			i_debug("quota-fs: uid=%s, limit=unlimited",
				dec2str(root->uid));
		}
		fs_quota_root_disable(root, FALSE);
		return 0;
	case Q_EPERM:
		i_error("quota-fs: permission denied to rquota service");
		return -1;
	default:
		i_error("quota-fs: unrecognized status code (%d) "
			"from rquota service", result.status);
		return -1;
	}
}
Esempio n. 25
0
int main(int argc, char *argv[])
{	
	char *svraddr = NULL;
	CLIENT *clntp = NULL;
	char *fpath = NULL;
	char *name = NULL;
	struct mkdir3args args;
	struct diropres3 res;
	/*struct fattr *fattrp = NULL;*/
	struct timeval to = {120, 0};
	enum clnt_stat st;
	int err = 0;
	int argv_len = 0;
	struct hsfs_inode *parent = NULL ;
	struct hsfs_inode *new;
	cliname = basename (argv[0]);
	if (argc < 3) {
			err = EINVAL;
			fprintf(stderr, "%s $svraddr $fpath.\n", cliname);
			goto out;
		}
	parent = (struct hsfs_inode *) malloc(sizeof(struct hsfs_inode));
	svraddr = argv[1];
	fpath = argv[2];
	name = argv[3];
	clntp = clnt_create(svraddr, 100003, NFS_V3, "tcp");
	if (NULL == clntp)
	{
		fprintf(stderr, "%s: Create handle to RPC server (%s, %u, %u) failed: (%s).\n", cliname,svraddr, NFSPROC3_MKDIR, NFS_V3, clnt_spcreateerror(cliname));
		err = ENXIO;
		goto out;
	} 
	memset (&args, 0, sizeof(args));
	memset (&res, 0, sizeof(res));
	args.where.name = fpath;
	//args.path.fpath_len = strlen(fpath);
	int st_tmp;
	size_t fh_len = 0;
	unsigned char *fh;
	st_tmp = map_path_to_nfs3fh(svraddr, fpath, &fh_len, &fh);
	args.where.dir.data.data_len  = fh_len;
	args.where.dir.data.data_val = fh;
	parent->sb = (struct hsfs_super *) malloc(sizeof(struct hsfs_super));
	if (NULL == parent->sb)
	{
		printf("No memory:parent->sb.\n");
	}
	parent->sb->clntp = clntp;
	parent->fh.data.data_len = args.where.dir.data.data_len;
	parent->fh.data.data_val = args.where.dir.data.data_val;
	st = hsi_nfs3_rmdir(parent, name);
	if (st) {
		err = EIO;
		fprintf (stderr, "%s: Call RPC Server (%s, %u, %u) failure: (%s).\n", cliname, svraddr, NFSPROC3_MKDIR, NFS_V3,clnt_sperrno(st));
		goto out;
	}
	if (0 == st){
		printf("Rm ok!\n");
	}

out:
	free(parent->sb);
	free(parent);
	if (NULL != clntp)
		clnt_destroy(clntp);
	exit(st);
}
Esempio n. 26
0
/*
 * Print reply error info
 */
char *
clnt_sperror(
	CLIENT *rpch,
	const char *s)
{
	struct rpc_err e;
	char *err;
	char *str = _buf();
	char *strstart = str;

	if (str == 0)
		return (0);
	CLNT_GETERR(rpch, &e);

	(void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status));
	str += strlen(str);

	switch (e.re_status) {
	case RPC_SUCCESS:
	case RPC_CANTENCODEARGS:
	case RPC_CANTDECODERES:
	case RPC_TIMEDOUT:
	case RPC_PROGUNAVAIL:
	case RPC_PROCUNAVAIL:
	case RPC_CANTDECODEARGS:
	case RPC_SYSTEMERROR:
	case RPC_UNKNOWNHOST:
	case RPC_UNKNOWNPROTO:
	case RPC_PMAPFAILURE:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
		break;

	case RPC_CANTSEND:
	case RPC_CANTRECV:
		(void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
			"; errno = %s\n", strerror(e.re_errno));
		break;

	case RPC_VERSMISMATCH:
		(void) sprintf(str,
			"; low version = %lu, high version = %lu\n",
			(u_long)e.re_vers.low, (u_long)e.re_vers.high);
		break;

	case RPC_AUTHERROR:
		err = auth_errmsg(e.re_why);
		(void) sprintf(str,"; why = ");
		str += strlen(str);
		if (err != NULL) {
			(void) sprintf(str, "%s\n",err);
		} else {
			(void) sprintf(str,
				"(unknown authentication error - %d)\n",
				(int) e.re_why);
		}
		break;

	case RPC_PROGVERSMISMATCH:
		(void) sprintf(str,
			"; low version = %lu, high version = %lu\n",
			(u_long)e.re_vers.low, (u_long)e.re_vers.high);
		break;

	default:	/* unknown */
		(void) sprintf(str,
			"; s1 = %lu, s2 = %lu\n",
			(long)e.re_lb.s1, (long)e.re_lb.s2);
		break;
	}
	strstart[CLNT_PERROR_BUFLEN-2] = '\n';
	strstart[CLNT_PERROR_BUFLEN-1] = '\0';
	return(strstart) ;
}
Esempio n. 27
0
void
clnt_perrno(
	enum clnt_stat num)
{
	(void) fprintf(stderr,"%s\n",clnt_sperrno(num));
}
Esempio n. 28
0
/*
 * Tell mountd we're done.
 * This is not quite right, because we may still
 * have other filesystems mounted, but the existing
 * mountd protocol is badly broken anyway.
 */
static void
amfs_host_umounted(mntfs *mf)
{
  char *host;
  CLIENT *client;
  enum clnt_stat clnt_stat;
  struct sockaddr_in sin;
  int sock = RPC_ANYSOCK;
  struct timeval tv;
  u_long mnt_version;

  if (mf->mf_error || mf->mf_refc > 1 || !mf->mf_server)
    return;

  /*
   * WebNFS servers shouldn't ever get here.
   */
  if (mf->mf_flags & MFF_WEBNFS) {
    plog(XLOG_ERROR, "amfs_host_umounted: cannot support WebNFS");
    return;
  }

  /*
   * Take a copy of the server hostname, address, and NFS version
   * to mount version conversion.
   */
  host = mf->mf_server->fs_host;
  sin = *mf->mf_server->fs_ip;
  plog(XLOG_INFO, "amfs_host_umounted: NFS version %d", (int) mf->mf_server->fs_version);
#ifdef HAVE_FS_NFS3
  if (mf->mf_server->fs_version == NFS_VERSION3)
    mnt_version = AM_MOUNTVERS3;
  else
#endif /* HAVE_FS_NFS3 */
    mnt_version = MOUNTVERS;

  /*
   * Create a client attached to mountd
   */
  tv.tv_sec = 10;
  tv.tv_usec = 0;
  client = get_mount_client(host, &sin, &tv, &sock, mnt_version);
  if (client == NULL) {
#ifdef HAVE_CLNT_SPCREATEERROR
    plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
	 host, clnt_spcreateerror(""));
#else /* not HAVE_CLNT_SPCREATEERROR */
    plog(XLOG_ERROR, "get_mount_client failed for %s", host);
#endif /* not HAVE_CLNT_SPCREATEERROR */
    goto out;
  }

  if (!nfs_auth) {
    if (make_nfs_auth())
      goto out;
  }
  client->cl_auth = nfs_auth;

  dlog("Unmounting all from %s", host);

  clnt_stat = clnt_call(client,
			MOUNTPROC_UMNTALL,
			(XDRPROC_T_TYPE) xdr_void,
			0,
			(XDRPROC_T_TYPE) xdr_void,
			0,
			tv);
  if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_SYSTEMERROR) {
    /* RPC_SYSTEMERROR seems to be returned for no good reason ... */
    const char *msg = clnt_sperrno(clnt_stat);
    plog(XLOG_ERROR, "unmount all from %s rpc failed: %s", host, msg);
    goto out;
  }

out:
  if (sock != RPC_ANYSOCK)
    (void) amu_close(sock);
  if (client)
    clnt_destroy(client);
}
Esempio n. 29
0
static int
amfs_host_mount(am_node *am, mntfs *mf)
{
  struct timeval tv2;
  CLIENT *client;
  enum clnt_stat clnt_stat;
  int n_export;
  int j, k;
  exports exlist = 0, ex;
  exports *ep = NULL;
  am_nfs_handle_t *fp = NULL;
  char *host;
  int error = 0;
  struct sockaddr_in sin;
  int sock = RPC_ANYSOCK;
  int ok = FALSE;
  mntlist *mlist;
  char fs_name[MAXPATHLEN], *rfs_dir;
  char mntpt[MAXPATHLEN];
  struct timeval tv;
  u_long mnt_version;

  /*
   * WebNFS servers don't necessarily run mountd.
   */
  if (mf->mf_flags & MFF_WEBNFS) {
    plog(XLOG_ERROR, "amfs_host_mount: cannot support WebNFS");
    return EIO;
  }

  /*
   * Read the mount list
   */
  mlist = read_mtab(mf->mf_mount, mnttab_file_name);

#ifdef MOUNT_TABLE_ON_FILE
  /*
   * Unlock the mount list
   */
  unlock_mntlist();
#endif /* MOUNT_TABLE_ON_FILE */

  /*
   * Take a copy of the server hostname, address, and nfs version
   * to mount version conversion.
   */
  host = mf->mf_server->fs_host;
  sin = *mf->mf_server->fs_ip;
  plog(XLOG_INFO, "amfs_host_mount: NFS version %d", (int) mf->mf_server->fs_version);
#ifdef HAVE_FS_NFS3
  if (mf->mf_server->fs_version == NFS_VERSION3)
    mnt_version = AM_MOUNTVERS3;
  else
#endif /* HAVE_FS_NFS3 */
    mnt_version = MOUNTVERS;

  /*
   * The original 10 second per try timeout is WAY too large, especially
   * if we're only waiting 10 or 20 seconds max for the response.
   * That would mean we'd try only once in 10 seconds, and we could
   * lose the transmit or receive packet, and never try again.
   * A 2-second per try timeout here is much more reasonable.
   * 09/28/92 Mike Mitchell, [email protected]
   */
  tv.tv_sec = 2;
  tv.tv_usec = 0;

  /*
   * Create a client attached to mountd
   */
  client = get_mount_client(host, &sin, &tv, &sock, mnt_version);
  if (client == NULL) {
#ifdef HAVE_CLNT_SPCREATEERROR
    plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
	 host, clnt_spcreateerror(""));
#else /* not HAVE_CLNT_SPCREATEERROR */
    plog(XLOG_ERROR, "get_mount_client failed for %s", host);
#endif /* not HAVE_CLNT_SPCREATEERROR */
    error = EIO;
    goto out;
  }
  if (!nfs_auth) {
    error = make_nfs_auth();
    if (error)
      goto out;
  }
  client->cl_auth = nfs_auth;

  dlog("Fetching export list from %s", host);

  /*
   * Fetch the export list
   */
  tv2.tv_sec = 10;
  tv2.tv_usec = 0;
  clnt_stat = clnt_call(client,
			MOUNTPROC_EXPORT,
			(XDRPROC_T_TYPE) xdr_void,
			0,
			(XDRPROC_T_TYPE) xdr_exports,
			(SVC_IN_ARG_TYPE) & exlist,
			tv2);
  if (clnt_stat != RPC_SUCCESS) {
    const char *msg = clnt_sperrno(clnt_stat);
    plog(XLOG_ERROR, "host_mount rpc failed: %s", msg);
    /* clnt_perror(client, "rpc"); */
    error = EIO;
    goto out;
  }

  /*
   * Figure out how many exports were returned
   */
  for (n_export = 0, ex = exlist; ex; ex = ex->ex_next) {
    n_export++;
  }

  /*
   * Allocate an array of pointers into the list
   * so that they can be sorted.  If the filesystem
   * is already mounted then ignore it.
   */
  ep = (exports *) xmalloc(n_export * sizeof(exports));
  for (j = 0, ex = exlist; ex; ex = ex->ex_next) {
    make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
    if (already_mounted(mlist, mntpt))
      /* we have at least one mounted f/s, so don't fail the mount */
      ok = TRUE;
    else
      ep[j++] = ex;
  }
  n_export = j;

  /*
   * Sort into order.
   * This way the mounts are done in order down the tree,
   * instead of any random order returned by the mount
   * daemon (the protocol doesn't specify...).
   */
  qsort(ep, n_export, sizeof(exports), sortfun);

  /*
   * Allocate an array of filehandles
   */
  fp = (am_nfs_handle_t *) xmalloc(n_export * sizeof(am_nfs_handle_t));

  /*
   * Try to obtain filehandles for each directory.
   * If a fetch fails then just zero out the array
   * reference but discard the error.
   */
  for (j = k = 0; j < n_export; j++) {
    /* Check and avoid a duplicated export entry */
    if (j > k && ep[k] && STREQ(ep[j]->ex_dir, ep[k]->ex_dir)) {
      dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir);
      ep[j] = NULL;
    } else {
      k = j;
      error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j],
			    mf->mf_server->fs_version);
      if (error)
	ep[j] = NULL;
    }
  }

  /*
   * Mount each filesystem for which we have a filehandle.
   * If any of the mounts succeed then mark "ok" and return
   * error code 0 at the end.  If they all fail then return
   * the last error code.
   */
  xstrlcpy(fs_name, mf->mf_info, sizeof(fs_name));
  if ((rfs_dir = strchr(fs_name, ':')) == (char *) NULL) {
    plog(XLOG_FATAL, "amfs_host_mount: mf_info has no colon");
    error = EINVAL;
    goto out;
  }
  ++rfs_dir;
  for (j = 0; j < n_export; j++) {
    ex = ep[j];
    if (ex) {
      /*
       * Note: the sizeof space left in rfs_dir is what's left in fs_name
       * after strchr() above returned a pointer _inside_ fs_name.  The
       * calculation below also takes into account that rfs_dir was
       * incremented by the ++ above.
       */
      xstrlcpy(rfs_dir, ex->ex_dir, sizeof(fs_name) - (rfs_dir - fs_name));
      make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
      if (do_mount(&fp[j], mntpt, fs_name, mf) == 0)
	ok = TRUE;
    }
  }

  /*
   * Clean up and exit
   */
out:
  discard_mntlist(mlist);
  XFREE(ep);
  XFREE(fp);
  if (sock != RPC_ANYSOCK)
    (void) amu_close(sock);
  if (client)
    clnt_destroy(client);
  if (exlist)
    xdr_pri_free((XDRPROC_T_TYPE) xdr_exports, (caddr_t) &exlist);
  if (ok)
    return 0;
  return error;
}
Esempio n. 30
0
/*
 * Get filehandle
 */
static int
fetch_fhandle(CLIENT *client, char *dir, am_nfs_handle_t *fhp, u_long nfs_version)
{
  struct timeval tv;
  enum clnt_stat clnt_stat;
  struct fhstatus res;
#ifdef HAVE_FS_NFS3
  struct am_mountres3 res3;
#endif /* HAVE_FS_NFS3 */

  /*
   * Pick a number, any number...
   */
  tv.tv_sec = 20;
  tv.tv_usec = 0;

  dlog("Fetching fhandle for %s", dir);

  /*
   * Call the mount daemon on the remote host to
   * get the filehandle.  Use NFS version specific call.
   */

  plog(XLOG_INFO, "fetch_fhandle: NFS version %d", (int) nfs_version);
#ifdef HAVE_FS_NFS3
  if (nfs_version == NFS_VERSION3
#ifdef HAVE_FS_NFS4
#ifndef NO_FALLBACK
      || nfs_version == NFS_VERSION4
#endif /* NO_FALLBACK */
#endif /* HAVE_FS_NFS4 */
    ) {

    memset((char *) &res3, 0, sizeof(res3));
    clnt_stat = clnt_call(client,
			  MOUNTPROC_MNT,
			  (XDRPROC_T_TYPE) xdr_dirpath,
			  (SVC_IN_ARG_TYPE) &dir,
			  (XDRPROC_T_TYPE) xdr_am_mountres3,
			  (SVC_IN_ARG_TYPE) &res3,
			  tv);
    if (clnt_stat != RPC_SUCCESS) {
      plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat));
      return EIO;
    }
    /* Check the status of the filehandle */
    if ((errno = res3.fhs_status)) {
      dlog("fhandle fetch for mount version 3 failed: %m");
      return errno;
    }
    memset((voidp) &fhp->v3, 0, sizeof(am_nfs_fh3));
    fhp->v3.am_fh3_length = res3.mountres3_u.mountinfo.fhandle.fhandle3_len;
    memmove(fhp->v3.am_fh3_data,
	    res3.mountres3_u.mountinfo.fhandle.fhandle3_val,
	    fhp->v3.am_fh3_length);
  } else {			/* not NFS_VERSION3 mount */
#endif /* HAVE_FS_NFS3 */
    clnt_stat = clnt_call(client,
			  MOUNTPROC_MNT,
			  (XDRPROC_T_TYPE) xdr_dirpath,
			  (SVC_IN_ARG_TYPE) &dir,
			  (XDRPROC_T_TYPE) xdr_fhstatus,
			  (SVC_IN_ARG_TYPE) &res,
			  tv);
    if (clnt_stat != RPC_SUCCESS) {
      plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat));
      return EIO;
    }
    /* Check status of filehandle */
    if (res.fhs_status) {
      errno = res.fhs_status;
      dlog("fhandle fetch for mount version 1 failed: %m");
      return errno;
    }
    memmove(&fhp->v2, &res.fhs_fh, NFS_FHSIZE);
#ifdef HAVE_FS_NFS3
  } /* end of "if (nfs_version == NFS_VERSION3)" statement */
#endif /* HAVE_FS_NFS3 */

  /* all is well */
  return 0;
}