18360efbdSAlfred Perlstein /* $NetBSD: pmap_prot2.c,v 1.14 2000/07/06 03:10:34 christos Exp $ */ 28360efbdSAlfred Perlstein 399064799SGarrett Wollman /* 499064799SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 599064799SGarrett Wollman * unrestricted use provided that this legend is included on all tape 699064799SGarrett Wollman * media and as a part of the software program in whole or part. Users 799064799SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 899064799SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 999064799SGarrett Wollman * program developed by the user. 1099064799SGarrett Wollman * 1199064799SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1299064799SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1399064799SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1499064799SGarrett Wollman * 1599064799SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 1699064799SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 1799064799SGarrett Wollman * modification or enhancement. 1899064799SGarrett Wollman * 1999064799SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2099064799SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2199064799SGarrett Wollman * OR ANY PART THEREOF. 2299064799SGarrett Wollman * 2399064799SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2499064799SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 2599064799SGarrett Wollman * Sun has been advised of the possibility of such damages. 2699064799SGarrett Wollman * 2799064799SGarrett Wollman * Sun Microsystems, Inc. 2899064799SGarrett Wollman * 2550 Garcia Avenue 2999064799SGarrett Wollman * Mountain View, California 94043 3099064799SGarrett Wollman */ 3199064799SGarrett Wollman 328360efbdSAlfred Perlstein #include <sys/cdefs.h> 3399064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 348360efbdSAlfred Perlstein static char *sccsid = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; 358360efbdSAlfred Perlstein static char *sccsid = "@(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC"; 367f3dea24SPeter Wemm static char *rcsid = "$FreeBSD$"; 3799064799SGarrett Wollman #endif 3899064799SGarrett Wollman 3999064799SGarrett Wollman /* 4099064799SGarrett Wollman * pmap_prot2.c 4199064799SGarrett Wollman * Protocol for the local binder service, or pmap. 4299064799SGarrett Wollman * 4399064799SGarrett Wollman * Copyright (C) 1984, Sun Microsystems, Inc. 4499064799SGarrett Wollman */ 4599064799SGarrett Wollman 468360efbdSAlfred Perlstein #include "namespace.h" 478360efbdSAlfred Perlstein #include <assert.h> 488360efbdSAlfred Perlstein 4999064799SGarrett Wollman #include <rpc/types.h> 5099064799SGarrett Wollman #include <rpc/xdr.h> 5199064799SGarrett Wollman #include <rpc/pmap_prot.h> 528360efbdSAlfred Perlstein #include "un-namespace.h" 5399064799SGarrett Wollman 5499064799SGarrett Wollman 5599064799SGarrett Wollman /* 5699064799SGarrett Wollman * What is going on with linked lists? (!) 5799064799SGarrett Wollman * First recall the link list declaration from pmap_prot.h: 5899064799SGarrett Wollman * 5999064799SGarrett Wollman * struct pmaplist { 6099064799SGarrett Wollman * struct pmap pml_map; 6199064799SGarrett Wollman * struct pmaplist *pml_map; 6299064799SGarrett Wollman * }; 6399064799SGarrett Wollman * 6499064799SGarrett Wollman * Compare that declaration with a corresponding xdr declaration that 6599064799SGarrett Wollman * is (a) pointer-less, and (b) recursive: 6699064799SGarrett Wollman * 6799064799SGarrett Wollman * typedef union switch (bool_t) { 6899064799SGarrett Wollman * 6999064799SGarrett Wollman * case TRUE: struct { 7099064799SGarrett Wollman * struct pmap; 7199064799SGarrett Wollman * pmaplist_t foo; 7299064799SGarrett Wollman * }; 7399064799SGarrett Wollman * 7499064799SGarrett Wollman * case FALSE: struct {}; 7599064799SGarrett Wollman * } pmaplist_t; 7699064799SGarrett Wollman * 7799064799SGarrett Wollman * Notice that the xdr declaration has no nxt pointer while 7899064799SGarrett Wollman * the C declaration has no bool_t variable. The bool_t can be 7999064799SGarrett Wollman * interpreted as ``more data follows me''; if FALSE then nothing 8099064799SGarrett Wollman * follows this bool_t; if TRUE then the bool_t is followed by 8199064799SGarrett Wollman * an actual struct pmap, and then (recursively) by the 8299064799SGarrett Wollman * xdr union, pamplist_t. 8399064799SGarrett Wollman * 8499064799SGarrett Wollman * This could be implemented via the xdr_union primitive, though this 8599064799SGarrett Wollman * would cause a one recursive call per element in the list. Rather than do 8699064799SGarrett Wollman * that we can ``unwind'' the recursion 8799064799SGarrett Wollman * into a while loop and do the union arms in-place. 8899064799SGarrett Wollman * 8999064799SGarrett Wollman * The head of the list is what the C programmer wishes to past around 9099064799SGarrett Wollman * the net, yet is the data that the pointer points to which is interesting; 9199064799SGarrett Wollman * this sounds like a job for xdr_reference! 9299064799SGarrett Wollman */ 9399064799SGarrett Wollman bool_t 9499064799SGarrett Wollman xdr_pmaplist(xdrs, rp) 958360efbdSAlfred Perlstein XDR *xdrs; 968360efbdSAlfred Perlstein struct pmaplist **rp; 9799064799SGarrett Wollman { 9899064799SGarrett Wollman /* 9999064799SGarrett Wollman * more_elements is pre-computed in case the direction is 10099064799SGarrett Wollman * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 10199064799SGarrett Wollman * xdr_bool when the direction is XDR_DECODE. 10299064799SGarrett Wollman */ 10399064799SGarrett Wollman bool_t more_elements; 1048360efbdSAlfred Perlstein int freeing; 1058360efbdSAlfred Perlstein struct pmaplist **next = NULL; /* pacify gcc */ 10699064799SGarrett Wollman 1078360efbdSAlfred Perlstein assert(xdrs != NULL); 1088360efbdSAlfred Perlstein assert(rp != NULL); 1098360efbdSAlfred Perlstein 1108360efbdSAlfred Perlstein freeing = (xdrs->x_op == XDR_FREE); 1118360efbdSAlfred Perlstein 1128360efbdSAlfred Perlstein for (;;) { 11399064799SGarrett Wollman more_elements = (bool_t)(*rp != NULL); 11499064799SGarrett Wollman if (! xdr_bool(xdrs, &more_elements)) 11599064799SGarrett Wollman return (FALSE); 11699064799SGarrett Wollman if (! more_elements) 11799064799SGarrett Wollman return (TRUE); /* we are done */ 11899064799SGarrett Wollman /* 11999064799SGarrett Wollman * the unfortunate side effect of non-recursion is that in 12099064799SGarrett Wollman * the case of freeing we must remember the next object 12199064799SGarrett Wollman * before we free the current object ... 12299064799SGarrett Wollman */ 12399064799SGarrett Wollman if (freeing) 12499064799SGarrett Wollman next = &((*rp)->pml_next); 12599064799SGarrett Wollman if (! xdr_reference(xdrs, (caddr_t *)rp, 1268360efbdSAlfred Perlstein (u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap)) 12799064799SGarrett Wollman return (FALSE); 12899064799SGarrett Wollman rp = (freeing) ? next : &((*rp)->pml_next); 12999064799SGarrett Wollman } 13099064799SGarrett Wollman } 1318360efbdSAlfred Perlstein 1328360efbdSAlfred Perlstein 1338360efbdSAlfred Perlstein /* 1348360efbdSAlfred Perlstein * xdr_pmaplist_ptr() is specified to take a PMAPLIST *, but is identical in 1358360efbdSAlfred Perlstein * functionality to xdr_pmaplist(). 1368360efbdSAlfred Perlstein */ 1378360efbdSAlfred Perlstein bool_t 1388360efbdSAlfred Perlstein xdr_pmaplist_ptr(xdrs, rp) 1398360efbdSAlfred Perlstein XDR *xdrs; 1408360efbdSAlfred Perlstein struct pmaplist *rp; 1418360efbdSAlfred Perlstein { 1428360efbdSAlfred Perlstein return xdr_pmaplist(xdrs, (struct pmaplist **)(void *)rp); 1438360efbdSAlfred Perlstein } 144