1 /* $OpenBSD: xdr_array.c,v 1.9 2005/08/08 08:05:36 espie Exp $ */ 2 /* 3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4 * unrestricted use provided that this legend is included on all tape 5 * media and as a part of the software program in whole or part. Users 6 * may copy or modify Sun RPC without charge, but are not authorized 7 * to license or distribute it to anyone else except as part of a product or 8 * program developed by the user. 9 * 10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * 14 * Sun RPC is provided with no support and without any obligation on the 15 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * modification or enhancement. 17 * 18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * OR ANY PART THEREOF. 21 * 22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * or profits or other special, indirect and consequential damages, even if 24 * Sun has been advised of the possibility of such damages. 25 * 26 * Sun Microsystems, Inc. 27 * 2550 Garcia Avenue 28 * Mountain View, California 94043 29 */ 30 31 /* 32 * xdr_array.c, Generic XDR routines implementation. 33 * 34 * Copyright (C) 1984, Sun Microsystems, Inc. 35 * 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 41 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <limits.h> 46 #include <rpc/types.h> 47 #include <rpc/xdr.h> 48 49 /* 50 * XDR an array of arbitrary elements 51 * *addrp is a pointer to the array, *sizep is the number of elements. 52 * If addrp is NULL (*sizep * elsize) bytes are allocated. 53 * elsize is the size (in bytes) of each element, and elproc is the 54 * xdr procedure to call to handle each element of the array. 55 */ 56 bool_t 57 xdr_array(XDR *xdrs, 58 caddr_t *addrp, /* array pointer */ 59 u_int *sizep, /* number of elements */ 60 u_int maxsize, /* max numberof elements */ 61 u_int elsize, /* size in bytes of each element */ 62 xdrproc_t elproc) /* xdr routine to handle each element */ 63 { 64 caddr_t target = *addrp; 65 u_int nodesize, c, i; 66 bool_t stat = TRUE; 67 68 /* like strings, arrays are really counted arrays */ 69 if (!xdr_u_int(xdrs, sizep)) 70 return (FALSE); 71 72 c = *sizep; 73 if ((c > maxsize || c > UINT_MAX/elsize) && 74 xdrs->x_op != XDR_FREE) 75 return (FALSE); 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 = mem_alloc(nodesize); 88 if (target == NULL) { 89 (void) fprintf(stderr, 90 "xdr_array: out of memory\n"); 91 return (FALSE); 92 } 93 memset(target, 0, nodesize); 94 break; 95 case XDR_FREE: 96 return (TRUE); 97 } 98 } 99 100 /* 101 * now we xdr each element of array 102 */ 103 for (i = 0; (i < c) && stat; i++) { 104 stat = (*elproc)(xdrs, target); 105 target += elsize; 106 } 107 108 /* 109 * the array may need freeing 110 */ 111 if (xdrs->x_op == XDR_FREE) { 112 mem_free(*addrp, nodesize); 113 *addrp = NULL; 114 } 115 return (stat); 116 } 117 118 /* 119 * xdr_vector(): 120 * 121 * XDR a fixed length array. Unlike variable-length arrays, 122 * the storage of fixed length arrays is static and unfreeable. 123 * > basep: base of the array 124 * > size: size of the array 125 * > elemsize: size of each element 126 * > xdr_elem: routine to XDR each element 127 */ 128 bool_t 129 xdr_vector(XDR *xdrs, char *basep, u_int nelem, u_int elemsize, 130 xdrproc_t xdr_elem) 131 { 132 char *elptr; 133 u_int i; 134 135 elptr = basep; 136 for (i = 0; i < nelem; i++) { 137 if (!(*xdr_elem)(xdrs, elptr)) 138 return(FALSE); 139 elptr += elemsize; 140 } 141 return(TRUE); 142 } 143