174462Salfred/* $NetBSD: pmap_prot2.c,v 1.14 2000/07/06 03:10:34 christos Exp $ */ 274462Salfred 3261057Smav/*- 4261057Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261057Smav * All rights reserved. 68870Srgrimes * 7261057Smav * Redistribution and use in source and binary forms, with or without 8261057Smav * modification, are permitted provided that the following conditions are met: 9261057Smav * - Redistributions of source code must retain the above copyright notice, 10261057Smav * this list of conditions and the following disclaimer. 11261057Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261057Smav * this list of conditions and the following disclaimer in the documentation 13261057Smav * and/or other materials provided with the distribution. 14261057Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261057Smav * contributors may be used to endorse or promote products derived 16261057Smav * from this software without specific prior written permission. 17261057Smav * 18261057Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261057Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261057Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261057Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261057Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261057Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261057Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261057Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261057Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261057Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261057Smav * POSSIBILITY OF SUCH DAMAGE. 291901Swollman */ 301901Swollman 311901Swollman#if defined(LIBC_SCCS) && !defined(lint) 32136581Sobrienstatic char *sccsid2 = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; 3374462Salfredstatic char *sccsid = "@(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC"; 341901Swollman#endif 3592990Sobrien#include <sys/cdefs.h> 3692990Sobrien__FBSDID("$FreeBSD$"); 371901Swollman 381901Swollman/* 391901Swollman * pmap_prot2.c 401901Swollman * Protocol for the local binder service, or pmap. 411901Swollman * 421901Swollman * Copyright (C) 1984, Sun Microsystems, Inc. 431901Swollman */ 441901Swollman 4574462Salfred#include "namespace.h" 4674462Salfred#include <assert.h> 4774462Salfred 481901Swollman#include <rpc/types.h> 491901Swollman#include <rpc/xdr.h> 501901Swollman#include <rpc/pmap_prot.h> 5174462Salfred#include "un-namespace.h" 521901Swollman 531901Swollman 548870Srgrimes/* 551901Swollman * What is going on with linked lists? (!) 561901Swollman * First recall the link list declaration from pmap_prot.h: 571901Swollman * 581901Swollman * struct pmaplist { 591901Swollman * struct pmap pml_map; 601901Swollman * struct pmaplist *pml_map; 611901Swollman * }; 621901Swollman * 638870Srgrimes * Compare that declaration with a corresponding xdr declaration that 641901Swollman * is (a) pointer-less, and (b) recursive: 651901Swollman * 661901Swollman * typedef union switch (bool_t) { 678870Srgrimes * 681901Swollman * case TRUE: struct { 691901Swollman * struct pmap; 701901Swollman * pmaplist_t foo; 711901Swollman * }; 721901Swollman * 731901Swollman * case FALSE: struct {}; 741901Swollman * } pmaplist_t; 751901Swollman * 761901Swollman * Notice that the xdr declaration has no nxt pointer while 771901Swollman * the C declaration has no bool_t variable. The bool_t can be 781901Swollman * interpreted as ``more data follows me''; if FALSE then nothing 791901Swollman * follows this bool_t; if TRUE then the bool_t is followed by 808870Srgrimes * an actual struct pmap, and then (recursively) by the 818870Srgrimes * xdr union, pamplist_t. 821901Swollman * 831901Swollman * This could be implemented via the xdr_union primitive, though this 841901Swollman * would cause a one recursive call per element in the list. Rather than do 851901Swollman * that we can ``unwind'' the recursion 861901Swollman * into a while loop and do the union arms in-place. 871901Swollman * 881901Swollman * The head of the list is what the C programmer wishes to past around 891901Swollman * the net, yet is the data that the pointer points to which is interesting; 901901Swollman * this sounds like a job for xdr_reference! 911901Swollman */ 921901Swollmanbool_t 931901Swollmanxdr_pmaplist(xdrs, rp) 9474462Salfred XDR *xdrs; 9574462Salfred struct pmaplist **rp; 961901Swollman{ 971901Swollman /* 981901Swollman * more_elements is pre-computed in case the direction is 991901Swollman * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 1001901Swollman * xdr_bool when the direction is XDR_DECODE. 1011901Swollman */ 1021901Swollman bool_t more_elements; 10374462Salfred int freeing; 10474462Salfred struct pmaplist **next = NULL; /* pacify gcc */ 1051901Swollman 10674462Salfred assert(xdrs != NULL); 10774462Salfred assert(rp != NULL); 10874462Salfred 10974462Salfred freeing = (xdrs->x_op == XDR_FREE); 11074462Salfred 11174462Salfred for (;;) { 1121901Swollman more_elements = (bool_t)(*rp != NULL); 1131901Swollman if (! xdr_bool(xdrs, &more_elements)) 1141901Swollman return (FALSE); 1151901Swollman if (! more_elements) 1161901Swollman return (TRUE); /* we are done */ 1171901Swollman /* 1181901Swollman * the unfortunate side effect of non-recursion is that in 1191901Swollman * the case of freeing we must remember the next object 1201901Swollman * before we free the current object ... 1211901Swollman */ 1221901Swollman if (freeing) 12374462Salfred next = &((*rp)->pml_next); 1241901Swollman if (! xdr_reference(xdrs, (caddr_t *)rp, 12574462Salfred (u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap)) 1261901Swollman return (FALSE); 1271901Swollman rp = (freeing) ? next : &((*rp)->pml_next); 1281901Swollman } 1291901Swollman} 13074462Salfred 13174462Salfred 13274462Salfred/* 13374462Salfred * xdr_pmaplist_ptr() is specified to take a PMAPLIST *, but is identical in 13474462Salfred * functionality to xdr_pmaplist(). 13574462Salfred */ 13674462Salfredbool_t 13774462Salfredxdr_pmaplist_ptr(xdrs, rp) 13874462Salfred XDR *xdrs; 13974462Salfred struct pmaplist *rp; 14074462Salfred{ 14174462Salfred return xdr_pmaplist(xdrs, (struct pmaplist **)(void *)rp); 14274462Salfred} 143