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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 /* 28 * Portions of this source code were derived from Berkeley 29 * 4.3 BSD under license from the Regents of the University of 30 * California. 31 */ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 /* 36 * xdr_array.c, Generic XDR routines impelmentation. 37 * 38 * These are the "non-trivial" xdr primitives used to serialize and de-serialize 39 * arrays. See xdr.h for more info on the interface to xdr. 40 */ 41 42 #include <sys/types.h> 43 #include <rpc/trace.h> 44 #include <syslog.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 48 #include <rpc/types.h> 49 #include <rpc/xdr.h> 50 #include <memory.h> 51 52 #define LASTUNSIGNED ((uint_t)0-1) 53 54 char mem_err_msg_arr[] = "xdr_array: out of memory"; 55 /* 56 * XDR an array of arbitrary elements 57 * *addrp is a pointer to the array, *sizep is the number of elements. 58 * If *addrp is NULL (*sizep * elsize) bytes are allocated. 59 * elsize is the size (in bytes) of each element, and elproc is the 60 * xdr procedure to call to handle each element of the array. 61 */ 62 bool_t 63 xdr_array(XDR *xdrs, caddr_t *addrp, uint_t *sizep, uint_t maxsize, 64 uint_t elsize, xdrproc_t elproc) 65 { 66 register uint_t i; 67 register caddr_t target = *addrp; 68 register uint_t c; /* the actual element count */ 69 register bool_t stat = TRUE; 70 register uint_t nodesize; 71 72 trace3(TR_xdr_array, 0, maxsize, elsize); 73 /* like strings, arrays are really counted arrays */ 74 if (! xdr_u_int(xdrs, sizep)) { 75 trace1(TR_xdr_array, 1); 76 return (FALSE); 77 } 78 c = *sizep; 79 if ((c > maxsize || LASTUNSIGNED / elsize < c) && 80 xdrs->x_op != XDR_FREE) { 81 trace1(TR_xdr_array, 1); 82 return (FALSE); 83 } 84 nodesize = c * elsize; 85 86 /* 87 * if we are deserializing, we may need to allocate an array. 88 * We also save time by checking for a null array if we are freeing. 89 */ 90 if (target == NULL) 91 switch (xdrs->x_op) { 92 case XDR_DECODE: 93 if (c == 0) { 94 trace1(TR_xdr_array, 1); 95 return (TRUE); 96 } 97 *addrp = target = (caddr_t)mem_alloc(nodesize); 98 if (target == NULL) { 99 (void) syslog(LOG_ERR, mem_err_msg_arr); 100 trace1(TR_xdr_array, 1); 101 return (FALSE); 102 } 103 (void) memset(target, 0, nodesize); 104 break; 105 106 case XDR_FREE: 107 trace1(TR_xdr_array, 1); 108 return (TRUE); 109 } 110 111 /* 112 * now we xdr each element of array 113 */ 114 for (i = 0; (i < c) && stat; i++) { 115 stat = (*elproc)(xdrs, target); 116 target += elsize; 117 } 118 119 /* 120 * the array may need freeing 121 */ 122 if (xdrs->x_op == XDR_FREE) { 123 mem_free(*addrp, nodesize); 124 *addrp = NULL; 125 } 126 trace1(TR_xdr_array, 1); 127 return (stat); 128 } 129 130 /* 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 array 136 * > size: size of the array 137 * > elemsize: size of each element 138 * > xdr_elem: routine to XDR each element 139 */ 140 bool_t 141 xdr_vector(XDR *xdrs, char *basep, uint_t nelem, 142 uint_t elemsize, xdrproc_t xdr_elem) 143 { 144 register uint_t i; 145 register char *elptr; 146 147 trace3(TR_xdr_vector, 0, nelem, elemsize); 148 elptr = basep; 149 for (i = 0; i < nelem; i++) { 150 if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) { 151 trace1(TR_xdr_vector, 1); 152 return (FALSE); 153 } 154 elptr += elemsize; 155 } 156 trace1(TR_xdr_vector, 1); 157 return (TRUE); 158 } 159