/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 2010, Oracle America, Inc.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions are7* met:8*9* * Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* * Redistributions in binary form must reproduce the above12* copyright notice, this list of conditions and the following13* disclaimer in the documentation and/or other materials14* provided with the distribution.15* * Neither the name of the "Oracle America, Inc." nor the names of its16* contributors may be used to endorse or promote products derived17* from this software without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS20* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT21* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS22* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE23* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,24* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE26* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS27* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,28* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING29* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31*/32/*33* xdr_sizeof.c34*35* General purpose routine to see how much space something will use36* when serialized using XDR.37*/3839#include "namespace.h"40#include <rpc/types.h>41#include <rpc/xdr.h>42#include <sys/types.h>43#include <stdlib.h>44#include "un-namespace.h"4546/* ARGSUSED */47static bool_t48x_putlong(XDR *xdrs, const long *longp)49{50xdrs->x_handy += BYTES_PER_XDR_UNIT;51return (TRUE);52}5354/* ARGSUSED */55static bool_t56x_putbytes(XDR *xdrs, const char *bp, u_int len)57{58xdrs->x_handy += len;59return (TRUE);60}6162static u_int63x_getpostn(XDR *xdrs)64{65return (xdrs->x_handy);66}6768/* ARGSUSED */69static bool_t70x_setpostn(XDR *xdrs, u_int pos)71{72/* This is not allowed */73return (FALSE);74}7576static int32_t *77x_inline(XDR *xdrs, u_int len)78{79if (len == 0) {80return (NULL);81}82if (xdrs->x_op != XDR_ENCODE) {83return (NULL);84}85if (len < (u_int)(uintptr_t)xdrs->x_base) {86/* x_private was already allocated */87xdrs->x_handy += len;88return ((int32_t *) xdrs->x_private);89} else {90/* Free the earlier space and allocate new area */91if (xdrs->x_private)92free(xdrs->x_private);93if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) {94xdrs->x_base = 0;95return (NULL);96}97xdrs->x_base = (caddr_t)(uintptr_t)len;98xdrs->x_handy += len;99return ((int32_t *) xdrs->x_private);100}101}102103static int104harmless(void)105{106/* Always return FALSE/NULL, as the case may be */107return (0);108}109110static void111x_destroy(XDR *xdrs)112{113xdrs->x_handy = 0;114xdrs->x_base = 0;115if (xdrs->x_private) {116free(xdrs->x_private);117xdrs->x_private = NULL;118}119return;120}121122unsigned long123xdr_sizeof(xdrproc_t func, void *data)124{125XDR x;126struct xdr_ops ops;127bool_t stat;128/* to stop ANSI-C compiler from complaining */129typedef bool_t (* dummyfunc1)(XDR *, long *);130typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);131132ops.x_putlong = x_putlong;133ops.x_putbytes = x_putbytes;134ops.x_inline = x_inline;135ops.x_getpostn = x_getpostn;136ops.x_setpostn = x_setpostn;137ops.x_destroy = x_destroy;138139/* the other harmless ones */140ops.x_getlong = (dummyfunc1) harmless;141ops.x_getbytes = (dummyfunc2) harmless;142143x.x_op = XDR_ENCODE;144x.x_ops = &ops;145x.x_handy = 0;146x.x_private = (caddr_t) NULL;147x.x_base = (caddr_t) 0;148149stat = func(&x, data);150if (x.x_private)151free(x.x_private);152return (stat == TRUE ? (unsigned) x.x_handy: 0);153}154155156