pmap_prot2.c revision 1901
1153761Swollman/* 2204566Sedwin * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3192886Sedwin * unrestricted use provided that this legend is included on all tape 4192886Sedwin * media and as a part of the software program in whole or part. Users 564499Swollman * may copy or modify Sun RPC without charge, but are not authorized 62742Swollman * to license or distribute it to anyone else except as part of a product or 72742Swollman * program developed by the user. 82742Swollman * 92742Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 10158421Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 112742Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 12158421Swollman * 13158421Swollman * Sun RPC is provided with no support and without any obligation on the 142742Swollman * part of Sun Microsystems, Inc. to assist in its use, correction, 1586222Swollman * modification or enhancement. 1620094Swollman * 1720094Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1820094Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 1920094Swollman * OR ANY PART THEREOF. 2020094Swollman * 21158421Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 22158421Swollman * or profits or other special, indirect and consequential damages, even if 2320094Swollman * Sun has been advised of the possibility of such damages. 2419878Swollman * 2519878Swollman * Sun Microsystems, Inc. 2619878Swollman * 2550 Garcia Avenue 2719878Swollman * Mountain View, California 94043 2819878Swollman */ 2919878Swollman 3019878Swollman#if defined(LIBC_SCCS) && !defined(lint) 3119878Swollman/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/ 3258787Sru/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/ 3358787Srustatic char *rcsid = "$Id: pmap_prot2.c,v 1.1 1993/10/27 05:40:39 paul Exp $"; 3458787Sru#endif 3558787Sru 3658787Sru/* 3758787Sru * pmap_prot2.c 3858787Sru * Protocol for the local binder service, or pmap. 3958787Sru * 4058787Sru * Copyright (C) 1984, Sun Microsystems, Inc. 4158787Sru */ 4258787Sru 4358787Sru#include <rpc/types.h> 4458787Sru#include <rpc/xdr.h> 4558787Sru#include <rpc/pmap_prot.h> 4658787Sru 4758787Sru 4858787Sru/* 4958787Sru * What is going on with linked lists? (!) 502742Swollman * First recall the link list declaration from pmap_prot.h: 512742Swollman * 522742Swollman * struct pmaplist { 532742Swollman * struct pmap pml_map; 542742Swollman * struct pmaplist *pml_map; 552742Swollman * }; 562742Swollman * 5719878Swollman * Compare that declaration with a corresponding xdr declaration that 582742Swollman * is (a) pointer-less, and (b) recursive: 592742Swollman * 602742Swollman * typedef union switch (bool_t) { 6119878Swollman * 622742Swollman * case TRUE: struct { 632742Swollman * struct pmap; 64149514Swollman * pmaplist_t foo; 6521217Swollman * }; 669908Swollman * 679908Swollman * case FALSE: struct {}; 682742Swollman * } pmaplist_t; 6919878Swollman * 7019878Swollman * Notice that the xdr declaration has no nxt pointer while 7119878Swollman * the C declaration has no bool_t variable. The bool_t can be 7219878Swollman * interpreted as ``more data follows me''; if FALSE then nothing 7319878Swollman * follows this bool_t; if TRUE then the bool_t is followed by 7419878Swollman * an actual struct pmap, and then (recursively) by the 7519878Swollman * xdr union, pamplist_t. 7619878Swollman * 7719878Swollman * This could be implemented via the xdr_union primitive, though this 7819878Swollman * would cause a one recursive call per element in the list. Rather than do 7919878Swollman * that we can ``unwind'' the recursion 8019878Swollman * into a while loop and do the union arms in-place. 8119878Swollman * 8219878Swollman * The head of the list is what the C programmer wishes to past around 8319878Swollman * the net, yet is the data that the pointer points to which is interesting; 8419878Swollman * this sounds like a job for xdr_reference! 8593799Swollman */ 8658787Srubool_t 8758787Sruxdr_pmaplist(xdrs, rp) 8819878Swollman register XDR *xdrs; 8919878Swollman register struct pmaplist **rp; 9019878Swollman{ 919908Swollman /* 92149514Swollman * more_elements is pre-computed in case the direction is 939908Swollman * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 949908Swollman * xdr_bool when the direction is XDR_DECODE. 959908Swollman */ 9621217Swollman bool_t more_elements; 9719878Swollman register int freeing = (xdrs->x_op == XDR_FREE); 9819878Swollman register struct pmaplist **next; 999908Swollman 100149514Swollman while (TRUE) { 1019908Swollman more_elements = (bool_t)(*rp != NULL); 1029908Swollman if (! xdr_bool(xdrs, &more_elements)) 1039908Swollman return (FALSE); 1049908Swollman if (! more_elements) 10558787Sru return (TRUE); /* we are done */ 10658787Sru /* 10758787Sru * the unfortunate side effect of non-recursion is that in 10864499Swollman * the case of freeing we must remember the next object 10964499Swollman * before we free the current object ... 110175034Sedwin */ 111175034Sedwin if (freeing) 112175034Sedwin next = &((*rp)->pml_next); 113175034Sedwin if (! xdr_reference(xdrs, (caddr_t *)rp, 114175034Sedwin (u_int)sizeof(struct pmaplist), xdr_pmap)) 11558787Sru return (FALSE); 11658787Sru rp = (freeing) ? next : &((*rp)->pml_next); 11767578Swollman } 11858787Sru} 11958787Sru