00001 /* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */ 00002 /* 00003 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 00004 * unrestricted use provided that this legend is included on all tape 00005 * media and as a part of the software program in whole or part. Users 00006 * may copy or modify Sun RPC without charge, but are not authorized 00007 * to license or distribute it to anyone else except as part of a product or 00008 * program developed by the user. 00009 * 00010 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 00011 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 00012 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 00013 * 00014 * Sun RPC is provided with no support and without any obligation on the 00015 * part of Sun Microsystems, Inc. to assist in its use, correction, 00016 * modification or enhancement. 00017 * 00018 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 00019 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 00020 * OR ANY PART THEREOF. 00021 * 00022 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 00023 * or profits or other special, indirect and consequential damages, even if 00024 * Sun has been advised of the possibility of such damages. 00025 * 00026 * Sun Microsystems, Inc. 00027 * 2550 Garcia Avenue 00028 * Mountain View, California 94043 00029 */ 00030 #if !defined(lint) && defined(SCCSIDS) 00031 static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI"; 00032 #endif 00033 00034 /* 00035 * xdr_reference.c, Generic XDR routines impelmentation. 00036 * 00037 * Copyright (C) 1987, Sun Microsystems, Inc. 00038 * 00039 * These are the "non-trivial" xdr primitives used to serialize and de-serialize 00040 * "pointers". See xdr.h for more info on the interface to xdr. 00041 */ 00042 00047 #include <stdio.h> 00048 #include <rpc/types.h> 00049 #include <rpc/xdr.h> 00050 #include <string.h> /* CUBEOS: for bzero */ 00051 00052 00053 #define LASTUNSIGNED ((u_int)0-1) 00054 00055 /* 00056 * XDR an indirect pointer 00057 * xdr_reference is for recursively translating a structure that is 00058 * referenced by a pointer inside the structure that is currently being 00059 * translated. pp references a pointer to storage. If *pp is null 00060 * the necessary storage is allocated. 00061 * size is the sizeof the referneced structure. 00062 * proc is the routine to handle the referenced structure. 00063 */ 00064 bool_t 00065 xdr_reference (xdrs, pp, size, proc) 00066 register XDR *xdrs; 00067 caddr_t *pp; /* the pointer to work on */ 00068 u_int size; /* size of the object pointed to */ 00069 xdrproc_t proc; /* xdr routine to handle the object */ 00070 { 00071 register caddr_t loc = *pp; 00072 register bool_t stat; 00073 00074 if (loc == NULL) 00075 switch (xdrs->x_op) { 00076 case XDR_FREE: 00077 return (TRUE); 00078 00079 case XDR_DECODE: 00080 *pp = loc = (caddr_t) mem_alloc (size); 00081 if (loc == NULL) { 00082 (void) fprintf (stderr, 00083 "xdr_reference: out of memory\n"); 00084 return (FALSE); 00085 } 00086 bzero (loc, (int) size); 00087 break; 00088 } 00089 stat = (*proc) (xdrs, loc, LASTUNSIGNED); 00090 00091 if (xdrs->x_op == XDR_FREE) { 00092 mem_free (loc, size); 00093 *pp = NULL; 00094 } 00095 return (stat); 00096 } 00097 00098 00099 /* 00100 * xdr_pointer(): 00101 * 00102 * XDR a pointer to a possibly recursive data structure. This 00103 * differs with xdr_reference in that it can serialize/deserialiaze 00104 * trees correctly. 00105 * 00106 * What's sent is actually a union: 00107 * 00108 * union object_pointer switch (boolean b) { 00109 * case TRUE: object_data data; 00110 * case FALSE: void nothing; 00111 * } 00112 * 00113 * > objpp: Pointer to the pointer to the object. 00114 * > obj_size: size of the object. 00115 * > xdr_obj: routine to XDR an object. 00116 * 00117 */ 00118 bool_t 00119 xdr_pointer (xdrs, objpp, obj_size, xdr_obj) 00120 register XDR *xdrs; 00121 char **objpp; 00122 u_int obj_size; 00123 xdrproc_t xdr_obj; 00124 { 00125 00126 bool_t more_data; 00127 00128 more_data = (*objpp != NULL); 00129 if (!xdr_bool (xdrs, &more_data)) { 00130 return (FALSE); 00131 } 00132 if (!more_data) { 00133 *objpp = NULL; 00134 return (TRUE); 00135 } 00136 return (xdr_reference (xdrs, objpp, obj_size, xdr_obj)); 00137 }