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, 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 /*
     23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 /*
     31  * Portions of this source code were derived from Berkeley 4.3 BSD
     32  * under license from the Regents of the University of California.
     33  */
     34 
     35 #pragma ident	"@(#)xdr_refer.c	1.10	05/06/08 SMI"
     36 
     37 /*
     38  * #if !defined(lint) && defined(SCCSIDS)
     39  * static char sccsid[] = "@(#)xdr_refer.c 1.21 89/02/28 SMI";
     40  * #endif
     41  */
     42 
     43 /*
     44  * xdr_refer.c, Generic XDR routines impelmentation.
     45  *
     46  * These are the "non-trivial" xdr primitives used to serialize and de-serialize
     47  * "pointers".  See xdr.h for more info on the interface to xdr.
     48  */
     49 
     50 #include <sys/param.h>
     51 #include <sys/systm.h>
     52 
     53 #include <rpc/types.h>
     54 #include <rpc/xdr.h>
     55 
     56 #define	LASTUNSIGNED	((uint_t)0-1)
     57 
     58 /*
     59  * XDR an indirect pointer
     60  * xdr_reference is for recursively translating a structure that is
     61  * referenced by a pointer inside the structure that is currently being
     62  * translated.  pp references a pointer to storage. If *pp is null
     63  * the  necessary storage is allocated.
     64  * size is the sizeof the referneced structure.
     65  * proc is the routine to handle the referenced structure.
     66  */
     67 bool_t
     68 xdr_reference(XDR *xdrs, caddr_t *pp, uint_t size, const xdrproc_t proc)
     69 {
     70 	caddr_t loc = *pp;
     71 	bool_t stat;
     72 
     73 	if (loc == NULL) {
     74 		switch (xdrs->x_op) {
     75 		case XDR_FREE:
     76 			return (TRUE);
     77 
     78 		case XDR_DECODE:
     79 			*pp = loc = (caddr_t)mem_alloc(size);
     80 			bzero(loc, size);
     81 			break;
     82 
     83 		case XDR_ENCODE:
     84 			break;
     85 		}
     86 	}
     87 
     88 	stat = (*proc)(xdrs, loc, LASTUNSIGNED);
     89 
     90 	if (xdrs->x_op == XDR_FREE) {
     91 		mem_free(loc, size);
     92 		*pp = NULL;
     93 	}
     94 	return (stat);
     95 }
     96 
     97 /*
     98  * xdr_pointer():
     99  *
    100  * XDR a pointer to a possibly recursive data structure. This
    101  * differs with xdr_reference in that it can serialize/deserialiaze
    102  * trees correctly.
    103  *
    104  *  What's sent is actually a union:
    105  *
    106  *  union object_pointer switch (boolean b) {
    107  *  case TRUE: object_data data;
    108  *  case FALSE: void nothing;
    109  *  }
    110  *
    111  * > objpp: Pointer to the pointer to the object.
    112  * > obj_size: size of the object.
    113  * > xdr_obj: routine to XDR an object.
    114  *
    115  */
    116 bool_t
    117 xdr_pointer(XDR *xdrs, char **objpp, uint_t obj_size, const xdrproc_t xdr_obj)
    118 {
    119 	bool_t more_data;
    120 
    121 	more_data = (*objpp != NULL);
    122 	if (!xdr_bool(xdrs, &more_data))
    123 		return (FALSE);
    124 	if (!more_data) {
    125 		*objpp = NULL;
    126 		return (TRUE);
    127 	}
    128 	return (xdr_reference(xdrs, objpp, obj_size, xdr_obj));
    129 }
    130