Home | History | Annotate | Download | only in rpc
      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