/*
 * rpc_callmsg.c
 *
 * Copyright (c) 2010, Oracle America, Inc.
 *
 * 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 the "Oracle America, 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.
 */

#include <string.h>
#include <sys/param.h>
#include <rpc/rpc.h>
#include <shlib-compat.h>

/*
 * XDR a call message
 */
bool_t
xdr_callmsg (XDR *xdrs, struct rpc_msg *cmsg)
{
  int32_t *buf;
  struct opaque_auth *oa;

  if (xdrs->x_op == XDR_ENCODE)
    {
      if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES)
	{
	  return (FALSE);
	}
      if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES)
	{
	  return (FALSE);
	}
      buf = XDR_INLINE (xdrs, 8 * BYTES_PER_XDR_UNIT
			+ RNDUP (cmsg->rm_call.cb_cred.oa_length)
			+ 2 * BYTES_PER_XDR_UNIT
			+ RNDUP (cmsg->rm_call.cb_verf.oa_length));
      if (buf != NULL)
	{
	  (void) IXDR_PUT_LONG (buf, cmsg->rm_xid);
	  (void) IXDR_PUT_ENUM (buf, cmsg->rm_direction);
	  if (cmsg->rm_direction != CALL)
	    return FALSE;
	  (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_rpcvers);
	  if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION)
	    return FALSE;
	  (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_prog);
	  (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_vers);
	  (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_proc);
	  oa = &cmsg->rm_call.cb_cred;
	  (void) IXDR_PUT_ENUM (buf, oa->oa_flavor);
	  (void) IXDR_PUT_INT32 (buf, oa->oa_length);
	  if (oa->oa_length)
	    {
	      memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length);
	      buf = (int32_t *) ((char *) buf + RNDUP (oa->oa_length));
	    }
	  oa = &cmsg->rm_call.cb_verf;
	  (void) IXDR_PUT_ENUM (buf, oa->oa_flavor);
	  (void) IXDR_PUT_INT32 (buf, oa->oa_length);
	  if (oa->oa_length)
	    {
	      memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length);
	      /* no real need....
		 buf = (long *) ((char *) buf + RNDUP(oa->oa_length));
	       */
	    }
	  return TRUE;
	}
    }
  if (xdrs->x_op == XDR_DECODE)
    {
      buf = XDR_INLINE (xdrs, 8 * BYTES_PER_XDR_UNIT);
      if (buf != NULL)
	{
	  cmsg->rm_xid = IXDR_GET_LONG (buf);
	  cmsg->rm_direction = IXDR_GET_ENUM (buf, enum msg_type);
	  if (cmsg->rm_direction != CALL)
	    {
	      return FALSE;
	    }
	  cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG (buf);
	  if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION)
	    {
	      return FALSE;
	    }
	  cmsg->rm_call.cb_prog = IXDR_GET_LONG (buf);
	  cmsg->rm_call.cb_vers = IXDR_GET_LONG (buf);
	  cmsg->rm_call.cb_proc = IXDR_GET_LONG (buf);
	  oa = &cmsg->rm_call.cb_cred;
	  oa->oa_flavor = IXDR_GET_ENUM (buf, enum_t);
	  oa->oa_length = IXDR_GET_INT32 (buf);
	  if (oa->oa_length)
	    {
	      if (oa->oa_length > MAX_AUTH_BYTES)
		return FALSE;
	      if (oa->oa_base == NULL)
		{
		  oa->oa_base = (caddr_t)
		    mem_alloc (oa->oa_length);
		}
	      buf = XDR_INLINE (xdrs, RNDUP (oa->oa_length));
	      if (buf == NULL)
		{
		  if (xdr_opaque (xdrs, oa->oa_base,
				  oa->oa_length) == FALSE)
		    return FALSE;
		}
	      else
		{
		  memcpy (oa->oa_base, (caddr_t) buf, oa->oa_length);
		  /* no real need....
		     buf = (long *) ((char *) buf
		     + RNDUP(oa->oa_length));
		   */
		}
	    }
	  oa = &cmsg->rm_call.cb_verf;
	  buf = XDR_INLINE (xdrs, 2 * BYTES_PER_XDR_UNIT);
	  if (buf == NULL)
	    {
	      if (xdr_enum (xdrs, &oa->oa_flavor) == FALSE ||
		  xdr_u_int (xdrs, &oa->oa_length) == FALSE)
		{
		  return FALSE;
		}
	    }
	  else
	    {
	      oa->oa_flavor = IXDR_GET_ENUM (buf, enum_t);
	      oa->oa_length = IXDR_GET_INT32 (buf);
	    }
	  if (oa->oa_length)
	    {
	      if (oa->oa_length > MAX_AUTH_BYTES)
		return FALSE;
	      if (oa->oa_base == NULL)
		{
		  oa->oa_base = (caddr_t)
		    mem_alloc (oa->oa_length);
		}
	      buf = XDR_INLINE (xdrs, RNDUP (oa->oa_length));
	      if (buf == NULL)
		{
		  if (xdr_opaque (xdrs, oa->oa_base,
				  oa->oa_length) == FALSE)
		    return FALSE;
		}
	      else
		{
		  memcpy (oa->oa_base, (caddr_t) buf, oa->oa_length);
		  /* no real need...
		     buf = (long *) ((char *) buf
		     + RNDUP(oa->oa_length));
		   */
		}
	    }
	  return TRUE;
	}
    }
  if (
       xdr_u_long (xdrs, &(cmsg->rm_xid)) &&
       xdr_enum (xdrs, (enum_t *) & (cmsg->rm_direction)) &&
       (cmsg->rm_direction == CALL) &&
       xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
       (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
       xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog)) &&
       xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers)) &&
       xdr_u_long (xdrs, &(cmsg->rm_call.cb_proc)) &&
       xdr_opaque_auth (xdrs, &(cmsg->rm_call.cb_cred)))
    return xdr_opaque_auth (xdrs, &(cmsg->rm_call.cb_verf));
  return FALSE;
}
libc_hidden_nolink_sunrpc (xdr_callmsg, GLIBC_2_0)
