1 1.3 christos /* $NetBSD: xdr_array.c,v 1.3 2019/06/16 16:01:44 christos Exp $ */ 2 1.1 hannken 3 1.1 hannken /* 4 1.1 hannken * Copyright (c) 2010, Oracle America, Inc. 5 1.1 hannken * 6 1.1 hannken * Redistribution and use in source and binary forms, with or without 7 1.1 hannken * modification, are permitted provided that the following conditions are 8 1.1 hannken * met: 9 1.1 hannken * 10 1.1 hannken * * Redistributions of source code must retain the above copyright 11 1.1 hannken * notice, this list of conditions and the following disclaimer. 12 1.1 hannken * * Redistributions in binary form must reproduce the above 13 1.1 hannken * copyright notice, this list of conditions and the following 14 1.1 hannken * disclaimer in the documentation and/or other materials 15 1.1 hannken * provided with the distribution. 16 1.1 hannken * * Neither the name of the "Oracle America, Inc." nor the names of its 17 1.1 hannken * contributors may be used to endorse or promote products derived 18 1.1 hannken * from this software without specific prior written permission. 19 1.1 hannken * 20 1.1 hannken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 1.1 hannken * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 1.1 hannken * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 1.1 hannken * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 1.1 hannken * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 1.1 hannken * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 1.1 hannken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 1.1 hannken * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 hannken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 hannken * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 1.1 hannken * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 1.1 hannken * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 hannken */ 33 1.1 hannken 34 1.1 hannken #include <sys/cdefs.h> 35 1.1 hannken #if defined(LIBC_SCCS) && !defined(lint) 36 1.1 hannken #if 0 37 1.1 hannken static char *sccsid = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro"; 38 1.1 hannken static char *sccsid = "@(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC"; 39 1.1 hannken #else 40 1.3 christos __RCSID("$NetBSD: xdr_array.c,v 1.3 2019/06/16 16:01:44 christos Exp $"); 41 1.1 hannken #endif 42 1.1 hannken #endif 43 1.1 hannken 44 1.1 hannken /* 45 1.1 hannken * xdr_array.c, Generic XDR routines implementation. 46 1.1 hannken * 47 1.1 hannken * Copyright (C) 1984, Sun Microsystems, Inc. 48 1.1 hannken * 49 1.1 hannken * These are the "non-trivial" xdr primitives used to serialize and de-serialize 50 1.1 hannken * arrays. See xdr.h for more info on the interface to xdr. 51 1.1 hannken */ 52 1.1 hannken 53 1.2 hannken #if defined(_KERNEL) || defined(_STANDALONE) 54 1.2 hannken 55 1.2 hannken #include <sys/param.h> 56 1.2 hannken #include <lib/libkern/libkern.h> 57 1.2 hannken #include <rpc/types.h> 58 1.2 hannken #include <rpc/xdr.h> 59 1.2 hannken 60 1.2 hannken #else /* _KERNEL || _STANDALONE */ 61 1.2 hannken 62 1.1 hannken #include "namespace.h" 63 1.1 hannken 64 1.1 hannken #include <err.h> 65 1.1 hannken #include <stdio.h> 66 1.1 hannken #include <stdlib.h> 67 1.1 hannken #include <string.h> 68 1.1 hannken #include <limits.h> 69 1.1 hannken 70 1.1 hannken #include <rpc/types.h> 71 1.1 hannken #include <rpc/xdr.h> 72 1.1 hannken 73 1.1 hannken #ifdef __weak_alias 74 1.1 hannken __weak_alias(xdr_array,_xdr_array) 75 1.1 hannken __weak_alias(xdr_vector,_xdr_vector) 76 1.1 hannken #endif 77 1.1 hannken 78 1.2 hannken #endif /* _KERNEL || _STANDALONE */ 79 1.2 hannken 80 1.1 hannken /* 81 1.1 hannken * XDR an array of arbitrary elements 82 1.1 hannken * *addrp is a pointer to the array, *sizep is the number of elements. 83 1.1 hannken * If addrp is NULL (*sizep * elsize) bytes are allocated. 84 1.1 hannken * elsize is the size (in bytes) of each element, and elproc is the 85 1.1 hannken * xdr procedure to call to handle each element of the array. 86 1.1 hannken */ 87 1.1 hannken bool_t 88 1.3 christos xdr_array(XDR *xdrs, char **addrp, u_int *sizep, u_int maxsize, u_int elsize, 89 1.1 hannken xdrproc_t elproc) 90 1.1 hannken { 91 1.1 hannken u_int i; 92 1.3 christos char *target = *addrp; 93 1.1 hannken u_int c; /* the actual element count */ 94 1.1 hannken bool_t stat = TRUE; 95 1.1 hannken u_int nodesize; 96 1.1 hannken 97 1.1 hannken /* like strings, arrays are really counted arrays */ 98 1.1 hannken if (!xdr_u_int(xdrs, sizep)) 99 1.1 hannken return (FALSE); 100 1.1 hannken 101 1.1 hannken c = *sizep; 102 1.1 hannken if ((c > maxsize || UINT_MAX/elsize < c) && 103 1.1 hannken (xdrs->x_op != XDR_FREE)) 104 1.1 hannken return (FALSE); 105 1.1 hannken nodesize = c * elsize; 106 1.1 hannken 107 1.1 hannken /* 108 1.1 hannken * if we are deserializing, we may need to allocate an array. 109 1.1 hannken * We also save time by checking for a null array if we are freeing. 110 1.1 hannken */ 111 1.1 hannken if (target == NULL) 112 1.1 hannken switch (xdrs->x_op) { 113 1.1 hannken case XDR_DECODE: 114 1.1 hannken if (c == 0) 115 1.1 hannken return (TRUE); 116 1.1 hannken *addrp = target = mem_alloc(nodesize); 117 1.1 hannken if (target == NULL) { 118 1.1 hannken warn("%s: out of memory", __func__); 119 1.1 hannken return (FALSE); 120 1.1 hannken } 121 1.1 hannken memset(target, 0, nodesize); 122 1.1 hannken break; 123 1.1 hannken 124 1.1 hannken case XDR_FREE: 125 1.1 hannken return (TRUE); 126 1.1 hannken 127 1.1 hannken case XDR_ENCODE: 128 1.1 hannken break; 129 1.1 hannken } 130 1.1 hannken 131 1.1 hannken /* 132 1.1 hannken * now we xdr each element of array 133 1.1 hannken */ 134 1.1 hannken for (i = 0; (i < c) && stat; i++) { 135 1.1 hannken stat = (*elproc)(xdrs, target); 136 1.1 hannken target += elsize; 137 1.1 hannken } 138 1.1 hannken 139 1.1 hannken /* 140 1.1 hannken * the array may need freeing 141 1.1 hannken */ 142 1.1 hannken if (xdrs->x_op == XDR_FREE) { 143 1.1 hannken mem_free(*addrp, nodesize); 144 1.1 hannken *addrp = NULL; 145 1.1 hannken } 146 1.1 hannken return (stat); 147 1.1 hannken } 148 1.1 hannken 149 1.1 hannken /* 150 1.1 hannken * xdr_vector(): 151 1.1 hannken * 152 1.1 hannken * XDR a fixed length array. Unlike variable-length arrays, 153 1.1 hannken * the storage of fixed length arrays is static and unfreeable. 154 1.1 hannken * > basep: base of the array 155 1.1 hannken * > size: size of the array 156 1.1 hannken * > elemsize: size of each element 157 1.1 hannken * > xdr_elem: routine to XDR each element 158 1.1 hannken */ 159 1.1 hannken bool_t 160 1.1 hannken xdr_vector(XDR *xdrs, char *basep, u_int nelem, u_int elemsize, 161 1.1 hannken xdrproc_t xdr_elem) 162 1.1 hannken { 163 1.1 hannken u_int i; 164 1.1 hannken char *elptr; 165 1.1 hannken 166 1.1 hannken elptr = basep; 167 1.1 hannken for (i = 0; i < nelem; i++) { 168 1.1 hannken if (!(*xdr_elem)(xdrs, elptr)) { 169 1.1 hannken return(FALSE); 170 1.1 hannken } 171 1.1 hannken elptr += elemsize; 172 1.1 hannken } 173 1.1 hannken return(TRUE); 174 1.1 hannken } 175