/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#include <rpc/key_prot.h>
/*
 * Copyright (c) 2009, Sun Microsystems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of Sun Microsystems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/* Copyright (c)  1990, 1991 Sun Microsystems, Inc. */

#include <sys/cdefs.h>

/*
 * Compiled from key_prot.x using rpcgen.
 * DO NOT EDIT THIS FILE!
 * This is NOT source code!
 */

bool
xdr_keystatus(XDR *xdrs, keystatus *objp)
{
	if (!xdr_enum(xdrs, (enum_t *) objp))
		return (false);
	return (true);
}

bool
xdr_keybuf(XDR *xdrs, keybuf objp)
{
	if (!xdr_opaque(xdrs, objp, HEXKEYBYTES))
		return (false);
	return (true);
}

bool
xdr_netnamestr(XDR *xdrs, netnamestr *objp)
{
	if (!xdr_string(xdrs, objp, MAXNETNAMELEN))
		return (false);
	return (true);
}

bool
xdr_cryptkeyarg(XDR *xdrs, cryptkeyarg *objp)
{
	if (!xdr_netnamestr(xdrs, &objp->remotename))
		return (false);
	if (!xdr_des_block(xdrs, &objp->deskey))
		return (false);
	return (true);
}

bool
xdr_cryptkeyarg2(XDR *xdrs, cryptkeyarg2 *objp)
{
	if (!xdr_netnamestr(xdrs, &objp->remotename))
		return (false);
	if (!xdr_netobj(xdrs, &objp->remotekey))
		return (false);
	if (!xdr_des_block(xdrs, &objp->deskey))
		return (false);
	return (true);
}

bool
xdr_cryptkeyres(XDR *xdrs, cryptkeyres *objp)
{
	if (!xdr_keystatus(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case KEY_SUCCESS:
		if (!xdr_des_block(xdrs, &objp->cryptkeyres_u.deskey))
			return (false);
		break;
	default:
		break;
	}
	return (true);
}

bool
xdr_unixcred(XDR *xdrs, unixcred *objp)
{
	if (!xdr_u_int(xdrs, &objp->uid))
		return (false);
	if (!xdr_u_int(xdrs, &objp->gid))
		return (false);
	if (!xdr_array
	    (xdrs, (char **)&objp->gids.gids_val,
	     (u_int *) &objp->gids.gids_len, MAXGIDS, sizeof(u_int),
	     (xdrproc_t) xdr_u_int))
		return (false);
	return (true);
}

bool
xdr_getcredres(register XDR *xdrs, getcredres *objp)
{
	if (!xdr_keystatus(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case KEY_SUCCESS:
		if (!xdr_unixcred(xdrs, &objp->getcredres_u.cred))
			return (false);
		break;
	default:
		break;
	}
	return (true);
}

bool
xdr_key_netstarg(XDR *xdrs, key_netstarg *objp)
{
	if (!xdr_keybuf(xdrs, objp->st_priv_key))
		return (false);
	if (!xdr_keybuf(xdrs, objp->st_pub_key))
		return (false);
	if (!xdr_netnamestr(xdrs, &objp->st_netname))
		return (false);
	return (true);
}

bool
xdr_key_netstres(register XDR *xdrs, key_netstres *objp)
{
	if (!xdr_keystatus(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case KEY_SUCCESS:
		if (!xdr_key_netstarg(xdrs, &objp->key_netstres_u.knet))
			return (false);
		break;
	default:
		break;
	}
	return (true);
}
