1272850Shrs/*- 2272850Shrs * Copyright (c) 2010, Oracle America, Inc. 3272850Shrs * 4272850Shrs * Redistribution and use in source and binary forms, with or without 5272850Shrs * modification, are permitted provided that the following conditions are 6272850Shrs * met: 7272850Shrs * 8272850Shrs * * Redistributions of source code must retain the above copyright 9272850Shrs * notice, this list of conditions and the following disclaimer. 10272850Shrs * * Redistributions in binary form must reproduce the above 11272850Shrs * copyright notice, this list of conditions and the following 12272850Shrs * disclaimer in the documentation and/or other materials 13272850Shrs * provided with the distribution. 14272850Shrs * * Neither the name of the "Oracle America, Inc." nor the names of its 15272850Shrs * contributors may be used to endorse or promote products derived 16272850Shrs * from this software without specific prior written permission. 17272850Shrs * 18272850Shrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19272850Shrs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20272850Shrs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21272850Shrs * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22272850Shrs * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23272850Shrs * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24272850Shrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 25272850Shrs * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26272850Shrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27272850Shrs * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28272850Shrs * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29272850Shrs * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3026216Swpaul */ 3126216Swpaul/* 3226216Swpaul * xdr_sizeof.c 3326216Swpaul * 3426216Swpaul * General purpose routine to see how much space something will use 3526216Swpaul * when serialized using XDR. 3626216Swpaul */ 3726216Swpaul 3892986Sobrien#include <sys/cdefs.h> 3992986Sobrien__FBSDID("$FreeBSD: releng/10.2/lib/libc/xdr/xdr_sizeof.c 272850 2014-10-09 23:05:32Z hrs $"); 4092986Sobrien 4174462Salfred#include "namespace.h" 4226216Swpaul#include <rpc/types.h> 4326216Swpaul#include <rpc/xdr.h> 4426216Swpaul#include <sys/types.h> 4526216Swpaul#include <stdlib.h> 4674462Salfred#include "un-namespace.h" 4726216Swpaul 4826216Swpaul/* ARGSUSED */ 4926216Swpaulstatic bool_t 5026216Swpaulx_putlong(xdrs, longp) 5126216Swpaul XDR *xdrs; 5226216Swpaul long *longp; 5326216Swpaul{ 5426216Swpaul xdrs->x_handy += BYTES_PER_XDR_UNIT; 5526216Swpaul return (TRUE); 5626216Swpaul} 5726216Swpaul 5826216Swpaul/* ARGSUSED */ 5926216Swpaulstatic bool_t 6026216Swpaulx_putbytes(xdrs, bp, len) 6126216Swpaul XDR *xdrs; 6226216Swpaul char *bp; 63111962Snectar u_int len; 6426216Swpaul{ 6526216Swpaul xdrs->x_handy += len; 6626216Swpaul return (TRUE); 6726216Swpaul} 6826216Swpaul 6926216Swpaulstatic u_int 7026216Swpaulx_getpostn(xdrs) 7126216Swpaul XDR *xdrs; 7226216Swpaul{ 7326216Swpaul return (xdrs->x_handy); 7426216Swpaul} 7526216Swpaul 7626216Swpaul/* ARGSUSED */ 7726216Swpaulstatic bool_t 7826216Swpaulx_setpostn(xdrs, pos) 7926216Swpaul XDR *xdrs; 8026216Swpaul u_int pos; 8126216Swpaul{ 8226216Swpaul /* This is not allowed */ 8326216Swpaul return (FALSE); 8426216Swpaul} 8526216Swpaul 8626216Swpaulstatic int32_t * 8726216Swpaulx_inline(xdrs, len) 8826216Swpaul XDR *xdrs; 89111962Snectar u_int len; 9026216Swpaul{ 9126216Swpaul if (len == 0) { 9226216Swpaul return (NULL); 9326216Swpaul } 9426216Swpaul if (xdrs->x_op != XDR_ENCODE) { 9526216Swpaul return (NULL); 9626216Swpaul } 97223877Skevlo if (len < (u_int)(uintptr_t)xdrs->x_base) { 9826216Swpaul /* x_private was already allocated */ 9926216Swpaul xdrs->x_handy += len; 10026216Swpaul return ((int32_t *) xdrs->x_private); 10126216Swpaul } else { 10226216Swpaul /* Free the earlier space and allocate new area */ 10326216Swpaul if (xdrs->x_private) 10426216Swpaul free(xdrs->x_private); 10526216Swpaul if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) { 10626216Swpaul xdrs->x_base = 0; 10726216Swpaul return (NULL); 10826216Swpaul } 109223877Skevlo xdrs->x_base = (caddr_t)(uintptr_t)len; 11026216Swpaul xdrs->x_handy += len; 11126216Swpaul return ((int32_t *) xdrs->x_private); 11226216Swpaul } 11326216Swpaul} 11426216Swpaul 11526216Swpaulstatic int 11626216Swpaulharmless() 11726216Swpaul{ 11826216Swpaul /* Always return FALSE/NULL, as the case may be */ 11926216Swpaul return (0); 12026216Swpaul} 12126216Swpaul 12226216Swpaulstatic void 12326216Swpaulx_destroy(xdrs) 12426216Swpaul XDR *xdrs; 12526216Swpaul{ 12626216Swpaul xdrs->x_handy = 0; 12726216Swpaul xdrs->x_base = 0; 12826216Swpaul if (xdrs->x_private) { 12926216Swpaul free(xdrs->x_private); 13026216Swpaul xdrs->x_private = NULL; 13126216Swpaul } 13226216Swpaul return; 13326216Swpaul} 13426216Swpaul 13526216Swpaulunsigned long 13626216Swpaulxdr_sizeof(func, data) 13726216Swpaul xdrproc_t func; 13826216Swpaul void *data; 13926216Swpaul{ 14026216Swpaul XDR x; 14126216Swpaul struct xdr_ops ops; 14226216Swpaul bool_t stat; 14326216Swpaul /* to stop ANSI-C compiler from complaining */ 14426216Swpaul typedef bool_t (* dummyfunc1)(XDR *, long *); 14526216Swpaul typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int); 14626216Swpaul 14726216Swpaul ops.x_putlong = x_putlong; 14826216Swpaul ops.x_putbytes = x_putbytes; 14926216Swpaul ops.x_inline = x_inline; 15026216Swpaul ops.x_getpostn = x_getpostn; 15126216Swpaul ops.x_setpostn = x_setpostn; 15226216Swpaul ops.x_destroy = x_destroy; 15326216Swpaul 15426216Swpaul /* the other harmless ones */ 15526216Swpaul ops.x_getlong = (dummyfunc1) harmless; 15626216Swpaul ops.x_getbytes = (dummyfunc2) harmless; 15726216Swpaul 15826216Swpaul x.x_op = XDR_ENCODE; 15926216Swpaul x.x_ops = &ops; 16026216Swpaul x.x_handy = 0; 16126216Swpaul x.x_private = (caddr_t) NULL; 16226216Swpaul x.x_base = (caddr_t) 0; 16326216Swpaul 16426216Swpaul stat = func(&x, data); 16526216Swpaul if (x.x_private) 16626216Swpaul free(x.x_private); 16726216Swpaul return (stat == TRUE ? (unsigned) x.x_handy: 0); 16826216Swpaul} 169