1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * Portions of this source code were derived from Berkeley 4.3 BSD 31 * under license from the Regents of the University of California. 32 */ 33 34 /* 35 * xdr_array.c, Generic XDR routines impelmentation. 36 * These are the "non-trivial" xdr primitives used to serialize and de-serialize 37 * arrays. See xdr.h for more info on the interface to xdr. 38 */ 39 40 #include <sys/param.h> 41 #include <sys/cmn_err.h> 42 #include <sys/types.h> 43 #include <sys/systm.h> 44 45 #include <rpc/types.h> 46 #include <rpc/xdr.h> 47 48 #define LASTUNSIGNED ((uint_t)0-1) 49 50 /* 51 * XDR an array of arbitrary elements 52 * *addrp is a pointer to the array, *sizep is the number of elements. 53 * If addrp is NULL (*sizep * elsize) bytes are allocated. 54 * elsize is the size (in bytes) of each element, and elproc is the 55 * xdr procedure to call to handle each element of the array. 56 */ 57 bool_t 58 xdr_array(XDR *xdrs, caddr_t *addrp, uint_t *sizep, const uint_t maxsize, 59 const uint_t elsize, const xdrproc_t elproc) 60 { 61 uint_t i; 62 caddr_t target = *addrp; 63 uint_t c; /* the actual element count */ 64 bool_t stat = TRUE; 65 uint_t nodesize; 66 67 /* like strings, arrays are really counted arrays */ 68 if (!xdr_u_int(xdrs, sizep)) { 69 return (FALSE); 70 } 71 c = *sizep; 72 if ((c > maxsize || LASTUNSIGNED / elsize < c) && 73 xdrs->x_op != XDR_FREE) { 74 return (FALSE); 75 } 76 nodesize = c * elsize; 77 78 /* 79 * if we are deserializing, we may need to allocate an array. 80 * We also save time by checking for a null array if we are freeing. 81 */ 82 if (target == NULL) 83 switch (xdrs->x_op) { 84 case XDR_DECODE: 85 if (c == 0) 86 return (TRUE); 87 *addrp = target = (char *)mem_alloc(nodesize); 88 bzero(target, nodesize); 89 break; 90 91 case XDR_FREE: 92 return (TRUE); 93 94 case XDR_ENCODE: 95 break; 96 } 97 98 /* 99 * now we xdr each element of array 100 */ 101 for (i = 0; (i < c) && stat; i++) { 102 stat = (*elproc)(xdrs, target, LASTUNSIGNED); 103 target += elsize; 104 } 105 106 /* 107 * the array may need freeing 108 */ 109 if (xdrs->x_op == XDR_FREE) { 110 mem_free(*addrp, nodesize); 111 *addrp = NULL; 112 } 113 return (stat); 114 } 115