#if defined(LIBC_SCCS) && !defined(lint)
static char *sccsid = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";
#endif
#include <sys/cdefs.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include "sec_xdr.h"
static void sec_xdrmem_destroy(XDR *);
#ifdef __LP64__
#define long_callback_ptr_t int *
#else
#define long_callback_ptr_t long *
#endif
static bool_t sec_xdrmem_getlong_aligned(XDR *, long_callback_ptr_t);
static bool_t sec_xdrmem_putlong_aligned(XDR *, const long_callback_ptr_t);
static bool_t sec_xdrmem_getlong_unaligned(XDR *, long_callback_ptr_t);
static bool_t sec_xdrmem_putlong_unaligned(XDR *, const long_callback_ptr_t);
static bool_t sec_xdrmem_getbytes(XDR *, char *, u_int);
static bool_t sec_xdrmem_putbytes(XDR *, const char *, u_int);
static u_int sec_xdrmem_getpos(XDR *);
static bool_t sec_xdrmem_setpos(XDR *, u_int);
static int32_t *sec_xdrmem_inline_aligned(XDR *, u_int);
static int32_t *sec_xdrmem_inline_unaligned(XDR *, u_int);
static const struct xdr_ops sec_xdrmem_ops_aligned = {
sec_xdrmem_getlong_aligned,
sec_xdrmem_putlong_aligned,
sec_xdrmem_getbytes,
sec_xdrmem_putbytes,
sec_xdrmem_getpos,
sec_xdrmem_setpos,
sec_xdrmem_inline_aligned,
sec_xdrmem_destroy
};
static const struct xdr_ops sec_xdrmem_ops_unaligned = {
sec_xdrmem_getlong_unaligned,
sec_xdrmem_putlong_unaligned,
sec_xdrmem_getbytes,
sec_xdrmem_putbytes,
sec_xdrmem_getpos,
sec_xdrmem_setpos,
sec_xdrmem_inline_unaligned,
sec_xdrmem_destroy
};
void
sec_xdrmem_create(xdrs, addr, size, op)
XDR *xdrs;
char *addr;
u_int size;
enum xdr_op op;
{
xdrs->x_op = op;
xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1))
? &sec_xdrmem_ops_unaligned : &sec_xdrmem_ops_aligned;
xdrs->x_private = xdrs->x_base = addr;
xdrs->x_public = NULL;
xdrs->x_handy = size;
}
static void
sec_xdrmem_destroy(xdrs)
XDR *xdrs;
{
}
static bool_t
sec_xdrmem_getlong_aligned(xdrs, lp)
XDR *xdrs;
long_callback_ptr_t lp;
{
if (xdrs->x_handy < sizeof(int32_t))
return (FALSE);
xdrs->x_handy -= sizeof(int32_t);
if (lp) *lp = ntohl(*(u_int32_t *)xdrs->x_private);
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
return (TRUE);
}
static bool_t
sec_xdrmem_putlong_aligned(xdrs, lp)
XDR *xdrs;
const long_callback_ptr_t lp;
{
if (xdrs->x_handy < sizeof(int32_t))
return (FALSE);
xdrs->x_handy -= sizeof(int32_t);
if (lp) *(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
return (TRUE);
}
static bool_t
sec_xdrmem_getlong_unaligned(xdrs, lp)
XDR *xdrs;
long_callback_ptr_t lp;
{
u_int32_t l;
if (xdrs->x_handy < sizeof(int32_t))
return (FALSE);
xdrs->x_handy -= sizeof(int32_t);
memmove(&l, xdrs->x_private, sizeof(int32_t));
if (lp) *lp = ntohl(l);
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
return (TRUE);
}
static bool_t
sec_xdrmem_putlong_unaligned(xdrs, lp)
XDR *xdrs;
const long_callback_ptr_t lp;
{
u_int32_t l = 0;
if (xdrs->x_handy < sizeof(int32_t))
return (FALSE);
xdrs->x_handy -= sizeof(int32_t);
if (lp) l = htonl((u_int32_t)*lp);
memmove(xdrs->x_private, &l, sizeof(int32_t));
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
return (TRUE);
}
static bool_t
sec_xdrmem_getbytes(xdrs, addr, len)
XDR *xdrs;
char *addr;
u_int len;
{
if (xdrs->x_handy < len)
return (FALSE);
xdrs->x_handy -= len;
if (addr) memmove(addr, xdrs->x_private, len);
xdrs->x_private = (char *)xdrs->x_private + len;
return (TRUE);
}
static bool_t
sec_xdrmem_putbytes(xdrs, addr, len)
XDR *xdrs;
const char *addr;
u_int len;
{
if (xdrs->x_handy < len)
return (FALSE);
xdrs->x_handy -= len;
if (addr) memmove(xdrs->x_private, addr, len);
xdrs->x_private = (char *)xdrs->x_private + len;
return (TRUE);
}
static u_int
sec_xdrmem_getpos(xdrs)
XDR *xdrs;
{
return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base);
}
static bool_t
sec_xdrmem_setpos(xdrs, pos)
XDR *xdrs;
u_int pos;
{
char *newaddr = xdrs->x_base + pos;
char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
if (newaddr > lastaddr)
return (FALSE);
xdrs->x_private = newaddr;
xdrs->x_handy = (u_int)(lastaddr - newaddr);
return (TRUE);
}
static int32_t *
sec_xdrmem_inline_aligned(xdrs, len)
XDR *xdrs;
u_int len;
{
int32_t *buf = 0;
if (xdrs->x_handy >= len) {
xdrs->x_handy -= len;
buf = (int32_t *)xdrs->x_private;
xdrs->x_private = (char *)xdrs->x_private + len;
}
return (buf);
}
static int32_t *
sec_xdrmem_inline_unaligned(xdrs, len)
XDR *xdrs;
u_int len;
{
return (0);
}