199064799SGarrett Wollman /* 299064799SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 399064799SGarrett Wollman * unrestricted use provided that this legend is included on all tape 499064799SGarrett Wollman * media and as a part of the software program in whole or part. Users 599064799SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 699064799SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 799064799SGarrett Wollman * program developed by the user. 899064799SGarrett Wollman * 999064799SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1099064799SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1199064799SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1299064799SGarrett Wollman * 1399064799SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 1499064799SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 1599064799SGarrett Wollman * modification or enhancement. 1699064799SGarrett Wollman * 1799064799SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1899064799SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 1999064799SGarrett Wollman * OR ANY PART THEREOF. 2099064799SGarrett Wollman * 2199064799SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2299064799SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 2399064799SGarrett Wollman * Sun has been advised of the possibility of such damages. 2499064799SGarrett Wollman * 2599064799SGarrett Wollman * Sun Microsystems, Inc. 2699064799SGarrett Wollman * 2550 Garcia Avenue 2799064799SGarrett Wollman * Mountain View, California 94043 2899064799SGarrett Wollman */ 2999064799SGarrett Wollman 3099064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 3199064799SGarrett Wollman /*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/ 3299064799SGarrett Wollman /*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/ 3399064799SGarrett Wollman static char *rcsid = "$Id: pmap_prot2.c,v 1.1 1993/10/27 05:40:39 paul Exp $"; 3499064799SGarrett Wollman #endif 3599064799SGarrett Wollman 3699064799SGarrett Wollman /* 3799064799SGarrett Wollman * pmap_prot2.c 3899064799SGarrett Wollman * Protocol for the local binder service, or pmap. 3999064799SGarrett Wollman * 4099064799SGarrett Wollman * Copyright (C) 1984, Sun Microsystems, Inc. 4199064799SGarrett Wollman */ 4299064799SGarrett Wollman 4399064799SGarrett Wollman #include <rpc/types.h> 4499064799SGarrett Wollman #include <rpc/xdr.h> 4599064799SGarrett Wollman #include <rpc/pmap_prot.h> 4699064799SGarrett Wollman 4799064799SGarrett Wollman 4899064799SGarrett Wollman /* 4999064799SGarrett Wollman * What is going on with linked lists? (!) 5099064799SGarrett Wollman * First recall the link list declaration from pmap_prot.h: 5199064799SGarrett Wollman * 5299064799SGarrett Wollman * struct pmaplist { 5399064799SGarrett Wollman * struct pmap pml_map; 5499064799SGarrett Wollman * struct pmaplist *pml_map; 5599064799SGarrett Wollman * }; 5699064799SGarrett Wollman * 5799064799SGarrett Wollman * Compare that declaration with a corresponding xdr declaration that 5899064799SGarrett Wollman * is (a) pointer-less, and (b) recursive: 5999064799SGarrett Wollman * 6099064799SGarrett Wollman * typedef union switch (bool_t) { 6199064799SGarrett Wollman * 6299064799SGarrett Wollman * case TRUE: struct { 6399064799SGarrett Wollman * struct pmap; 6499064799SGarrett Wollman * pmaplist_t foo; 6599064799SGarrett Wollman * }; 6699064799SGarrett Wollman * 6799064799SGarrett Wollman * case FALSE: struct {}; 6899064799SGarrett Wollman * } pmaplist_t; 6999064799SGarrett Wollman * 7099064799SGarrett Wollman * Notice that the xdr declaration has no nxt pointer while 7199064799SGarrett Wollman * the C declaration has no bool_t variable. The bool_t can be 7299064799SGarrett Wollman * interpreted as ``more data follows me''; if FALSE then nothing 7399064799SGarrett Wollman * follows this bool_t; if TRUE then the bool_t is followed by 7499064799SGarrett Wollman * an actual struct pmap, and then (recursively) by the 7599064799SGarrett Wollman * xdr union, pamplist_t. 7699064799SGarrett Wollman * 7799064799SGarrett Wollman * This could be implemented via the xdr_union primitive, though this 7899064799SGarrett Wollman * would cause a one recursive call per element in the list. Rather than do 7999064799SGarrett Wollman * that we can ``unwind'' the recursion 8099064799SGarrett Wollman * into a while loop and do the union arms in-place. 8199064799SGarrett Wollman * 8299064799SGarrett Wollman * The head of the list is what the C programmer wishes to past around 8399064799SGarrett Wollman * the net, yet is the data that the pointer points to which is interesting; 8499064799SGarrett Wollman * this sounds like a job for xdr_reference! 8599064799SGarrett Wollman */ 8699064799SGarrett Wollman bool_t 8799064799SGarrett Wollman xdr_pmaplist(xdrs, rp) 8899064799SGarrett Wollman register XDR *xdrs; 8999064799SGarrett Wollman register struct pmaplist **rp; 9099064799SGarrett Wollman { 9199064799SGarrett Wollman /* 9299064799SGarrett Wollman * more_elements is pre-computed in case the direction is 9399064799SGarrett Wollman * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 9499064799SGarrett Wollman * xdr_bool when the direction is XDR_DECODE. 9599064799SGarrett Wollman */ 9699064799SGarrett Wollman bool_t more_elements; 9799064799SGarrett Wollman register int freeing = (xdrs->x_op == XDR_FREE); 9899064799SGarrett Wollman register struct pmaplist **next; 9999064799SGarrett Wollman 10099064799SGarrett Wollman while (TRUE) { 10199064799SGarrett Wollman more_elements = (bool_t)(*rp != NULL); 10299064799SGarrett Wollman if (! xdr_bool(xdrs, &more_elements)) 10399064799SGarrett Wollman return (FALSE); 10499064799SGarrett Wollman if (! more_elements) 10599064799SGarrett Wollman return (TRUE); /* we are done */ 10699064799SGarrett Wollman /* 10799064799SGarrett Wollman * the unfortunate side effect of non-recursion is that in 10899064799SGarrett Wollman * the case of freeing we must remember the next object 10999064799SGarrett Wollman * before we free the current object ... 11099064799SGarrett Wollman */ 11199064799SGarrett Wollman if (freeing) 11299064799SGarrett Wollman next = &((*rp)->pml_next); 11399064799SGarrett Wollman if (! xdr_reference(xdrs, (caddr_t *)rp, 11499064799SGarrett Wollman (u_int)sizeof(struct pmaplist), xdr_pmap)) 11599064799SGarrett Wollman return (FALSE); 11699064799SGarrett Wollman rp = (freeing) ? next : &((*rp)->pml_next); 11799064799SGarrett Wollman } 11899064799SGarrett Wollman } 119