/* $NetBSD: xdr_array.c,v 1.12 2000/01/22 22:19:18 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_array.c, Generic XDR routines implementation.37*38* These are the "non-trivial" xdr primitives used to serialize and de-serialize39* arrays. See xdr.h for more info on the interface to xdr.40*/4142#include "namespace.h"43#include <err.h>44#include <limits.h>45#include <stdio.h>46#include <stdlib.h>47#include <string.h>4849#include <rpc/types.h>50#include <rpc/xdr.h>51#include "un-namespace.h"5253/*54* XDR an array of arbitrary elements55* *addrp is a pointer to the array, *sizep is the number of elements.56* If addrp is NULL (*sizep * elsize) bytes are allocated.57* elsize is the size (in bytes) of each element, and elproc is the58* xdr procedure to call to handle each element of the array.59*/60bool_t61xdr_array(XDR *xdrs, caddr_t *addrp, u_int *sizep, u_int maxsize, u_int elsize, xdrproc_t elproc)62/*63* XDR *xdrs;64* caddr_t *addrp; // array pointer65* u_int *sizep; // number of elements66* u_int maxsize; // max numberof elements67* u_int elsize; // size in bytes of each element68* xdrproc_t elproc; // xdr routine to handle each element69*/70{71u_int i;72caddr_t target = *addrp;73u_int c; /* the actual element count */74bool_t stat = TRUE;75u_int nodesize;7677/* like strings, arrays are really counted arrays */78if (!xdr_u_int(xdrs, sizep)) {79return (FALSE);80}81c = *sizep;82if ((c > maxsize || UINT_MAX/elsize < c) &&83(xdrs->x_op != XDR_FREE)) {84return (FALSE);85}86nodesize = c * elsize;8788/*89* if we are deserializing, we may need to allocate an array.90* We also save time by checking for a null array if we are freeing.91*/92if (target == NULL)93switch (xdrs->x_op) {94case XDR_DECODE:95if (c == 0)96return (TRUE);97*addrp = target = mem_alloc(nodesize);98if (target == NULL) {99warnx("xdr_array: out of memory");100return (FALSE);101}102memset(target, 0, nodesize);103break;104105case XDR_FREE:106return (TRUE);107108case XDR_ENCODE:109break;110}111112/*113* now we xdr each element of array114*/115for (i = 0; (i < c) && stat; i++) {116stat = (*elproc)(xdrs, target);117target += elsize;118}119120/*121* the array may need freeing122*/123if (xdrs->x_op == XDR_FREE) {124mem_free(*addrp, nodesize);125*addrp = NULL;126}127return (stat);128}129130/*131* xdr_vector():132*133* XDR a fixed length array. Unlike variable-length arrays,134* the storage of fixed length arrays is static and unfreeable.135* > basep: base of the array136* > size: size of the array137* > elemsize: size of each element138* > xdr_elem: routine to XDR each element139*/140bool_t141xdr_vector(XDR *xdrs, char *basep, u_int nelem, u_int elemsize, xdrproc_t xdr_elem)142{143u_int i;144char *elptr;145146elptr = basep;147for (i = 0; i < nelem; i++) {148if (!(*xdr_elem)(xdrs, elptr)) {149return(FALSE);150}151elptr += elemsize;152}153return(TRUE);154}155156157