/* $NetBSD: xdr_stdio.c,v 1.14 2000/01/22 22:19:19 mycroft Exp $ */12/*-3* SPDX-License-Identifier: BSD-3-Clause4*5* Copyright (c) 2010, Oracle America, Inc.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions are9* met:10*11* * Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* * Redistributions in binary form must reproduce the above14* copyright notice, this list of conditions and the following15* disclaimer in the documentation and/or other materials16* provided with the distribution.17* * Neither the name of the "Oracle America, Inc." nor the names of its18* contributors may be used to endorse or promote products derived19* from this software without specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS22* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT23* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS24* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE25* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,26* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL27* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE28* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS29* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,30* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING31* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE32* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.33*/3435/*36* xdr_stdio.c, XDR implementation on standard i/o file.37*38* This set of routines implements a XDR on a stdio stream.39* XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes40* from the stream.41*/4243#include "namespace.h"44#include <stdio.h>4546#include <arpa/inet.h>47#include <rpc/types.h>48#include <rpc/xdr.h>49#include "un-namespace.h"5051static void xdrstdio_destroy(XDR *);52static bool_t xdrstdio_getlong(XDR *, long *);53static bool_t xdrstdio_putlong(XDR *, const long *);54static bool_t xdrstdio_getbytes(XDR *, char *, u_int);55static bool_t xdrstdio_putbytes(XDR *, const char *, u_int);56static u_int xdrstdio_getpos(XDR *);57static bool_t xdrstdio_setpos(XDR *, u_int);58static int32_t *xdrstdio_inline(XDR *, u_int);5960/*61* Ops vector for stdio type XDR62*/63static const struct xdr_ops xdrstdio_ops = {64xdrstdio_getlong, /* deseraialize a long int */65xdrstdio_putlong, /* seraialize a long int */66xdrstdio_getbytes, /* deserialize counted bytes */67xdrstdio_putbytes, /* serialize counted bytes */68xdrstdio_getpos, /* get offset in the stream */69xdrstdio_setpos, /* set offset in the stream */70xdrstdio_inline, /* prime stream for inline macros */71xdrstdio_destroy /* destroy stream */72};7374/*75* Initialize a stdio xdr stream.76* Sets the xdr stream handle xdrs for use on the stream file.77* Operation flag is set to op.78*/79void80xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op)81{8283xdrs->x_op = op;84xdrs->x_ops = &xdrstdio_ops;85xdrs->x_private = file;86xdrs->x_handy = 0;87xdrs->x_base = 0;88}8990/*91* Destroy a stdio xdr stream.92* Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.93*/94static void95xdrstdio_destroy(XDR *xdrs)96{97(void)fflush((FILE *)xdrs->x_private);98/* XXX: should we close the file ?? */99}100101static bool_t102xdrstdio_getlong(XDR *xdrs, long *lp)103{104u_int32_t temp;105106if (fread(&temp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)107return (FALSE);108*lp = (long)ntohl(temp);109return (TRUE);110}111112static bool_t113xdrstdio_putlong(XDR *xdrs, const long *lp)114{115int32_t mycopy = htonl((u_int32_t)*lp);116117if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)118return (FALSE);119return (TRUE);120}121122static bool_t123xdrstdio_getbytes(XDR *xdrs, char *addr, u_int len)124{125126if ((len != 0) && (fread(addr, (size_t)len, 1, (FILE *)xdrs->x_private) != 1))127return (FALSE);128return (TRUE);129}130131static bool_t132xdrstdio_putbytes(XDR *xdrs, const char *addr, u_int len)133{134135if ((len != 0) && (fwrite(addr, (size_t)len, 1,136(FILE *)xdrs->x_private) != 1))137return (FALSE);138return (TRUE);139}140141static u_int142xdrstdio_getpos(XDR *xdrs)143{144145return ((u_int) ftell((FILE *)xdrs->x_private));146}147148static bool_t149xdrstdio_setpos(XDR *xdrs, u_int pos)150{151152return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?153FALSE : TRUE);154}155156/* ARGSUSED */157static int32_t *158xdrstdio_inline(XDR *xdrs, u_int len)159{160161/*162* Must do some work to implement this: must insure163* enough data in the underlying stdio buffer,164* that the buffer is aligned so that we can indirect through a165* long *, and stuff this pointer in xdrs->x_buf. Doing166* a fread or fwrite to a scratch buffer would defeat167* most of the gains to be had here and require storage168* management on this buffer, so we don't do this.169*/170return (NULL);171}172173174