ReactOS 0.4.15-dev-8058-ga7cbb60
pmap_prot2.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009, Sun Microsystems, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * pmap_prot2.c
31 * Protocol for the local binder service, or pmap.
32 *
33 * Copyright (C) 1984, Sun Microsystems, Inc.
34 */
35
36#include <wintirpc.h>
37#include <assert.h>
38
39#include <rpc/types.h>
40#include <rpc/xdr.h>
41#include <rpc/pmap_prot.h>
42
43
44/*
45 * What is going on with linked lists? (!)
46 * First recall the link list declaration from pmap_prot.h:
47 *
48 * struct pmaplist {
49 * struct pmap pml_map;
50 * struct pmaplist *pml_map;
51 * };
52 *
53 * Compare that declaration with a corresponding xdr declaration that
54 * is (a) pointer-less, and (b) recursive:
55 *
56 * typedef union switch (bool_t) {
57 *
58 * case TRUE: struct {
59 * struct pmap;
60 * pmaplist_t foo;
61 * };
62 *
63 * case FALSE: struct {};
64 * } pmaplist_t;
65 *
66 * Notice that the xdr declaration has no nxt pointer while
67 * the C declaration has no bool_t variable. The bool_t can be
68 * interpreted as ``more data follows me''; if FALSE then nothing
69 * follows this bool_t; if TRUE then the bool_t is followed by
70 * an actual struct pmap, and then (recursively) by the
71 * xdr union, pamplist_t.
72 *
73 * This could be implemented via the xdr_union primitive, though this
74 * would cause a one recursive call per element in the list. Rather than do
75 * that we can ``unwind'' the recursion
76 * into a while loop and do the union arms in-place.
77 *
78 * The head of the list is what the C programmer wishes to past around
79 * the net, yet is the data that the pointer points to which is interesting;
80 * this sounds like a job for xdr_reference!
81 */
83xdr_pmaplist(xdrs, rp)
84 XDR *xdrs;
85 struct pmaplist **rp;
86{
87 /*
88 * more_elements is pre-computed in case the direction is
89 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by
90 * xdr_bool when the direction is XDR_DECODE.
91 */
92 bool_t more_elements;
93 int freeing;
94 struct pmaplist **next = NULL; /* pacify gcc */
95
96 assert(xdrs != NULL);
97 assert(rp != NULL);
98
99 freeing = (xdrs->x_op == XDR_FREE);
100
101 for (;;) {
102 more_elements = (bool_t)(*rp != NULL);
103 if (! xdr_bool(xdrs, &more_elements))
104 return (FALSE);
105 if (! more_elements)
106 return (TRUE); /* we are done */
107 /*
108 * the unfortunate side effect of non-recursion is that in
109 * the case of freeing we must remember the next object
110 * before we free the current object ...
111 */
112 if (freeing)
113 next = &((*rp)->pml_next);
114 if (! xdr_reference(xdrs, (caddr_t *)rp,
115 (u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap))
116 return (FALSE);
117 rp = (freeing) ? next : &((*rp)->pml_next);
118 }
119}
120
121
122/*
123 * xdr_pmaplist_ptr() is specified to take a PMAPLIST *, but is identical in
124 * functionality to xdr_pmaplist().
125 */
126bool_t
128 XDR *xdrs;
129 struct pmaplist *rp;
130{
131 return xdr_pmaplist(xdrs, (struct pmaplist **)(void *)rp);
132}
bool_t xdr_bool(XDR *xdrs, bool_t *bp)
Definition: xdr.c:428
UINT32 u_int
Definition: types.h:82
#define NULL
Definition: types.h:112
int32_t bool_t
Definition: types.h:101
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define assert(x)
Definition: debug.h:53
bool_t xdr_pmaplist(XDR *xdrs, struct pmaplist **rp)
Definition: pmap_prot2.c:83
bool_t xdr_pmaplist_ptr(XDR *xdrs, struct pmaplist *rp)
Definition: pmap_prot2.c:127
bool_t xdr_pmap(XDR *xdrs, struct pmap *regs)
Definition: pmap_prot.c:45
static unsigned __int64 next
Definition: rand_nt.c:6
char * caddr_t
Definition: rosdhcp.h:36
Definition: xdr.h:103
enum xdr_op x_op
Definition: xdr.h:104
@ XDR_FREE
Definition: xdr.h:87
bool_t(* xdrproc_t)(XDR *,...)
Definition: xdr.h:144
bool_t xdr_reference(XDR *xdrs, caddr_t *pp, u_int size, xdrproc_t proc)
Definition: xdr_reference.c:62