4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
31 * Portions of this source code were derived from Berkeley
32 * 4.3 BSD under license from the Regents of the University of
36 #pragma ident "%Z%%M% %I% %E% SMI"
39 * Protocol for the local binder service, or pmap.
40 * All the pmap xdr routines here.
44 #include <rpc/types.h>
46 #include <rpc/pmap_prot.h>
47 #include <rpc/pmap_rmt.h>
50 xdr_pmap(XDR
*xdrs
, struct pmap
*objp
)
56 buf
= XDR_INLINE(xdrs
, 4 * BYTES_PER_XDR_UNIT
);
58 if (!XDR_PUTINT32(xdrs
, (int32_t *)&objp
->pm_prog
))
60 if (!XDR_PUTINT32(xdrs
, (int32_t *)&objp
->pm_vers
))
62 if (!XDR_PUTINT32(xdrs
, (int32_t *)&objp
->pm_prot
))
64 if (!XDR_PUTINT32(xdrs
, (int32_t *)&objp
->pm_port
))
67 IXDR_PUT_U_INT32(buf
, objp
->pm_prog
);
68 IXDR_PUT_U_INT32(buf
, objp
->pm_vers
);
69 IXDR_PUT_U_INT32(buf
, objp
->pm_prot
);
70 IXDR_PUT_U_INT32(buf
, objp
->pm_port
);
74 buf
= XDR_INLINE(xdrs
, 4 * BYTES_PER_XDR_UNIT
);
76 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->pm_prog
))
78 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->pm_vers
))
80 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->pm_prot
))
82 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->pm_port
))
85 objp
->pm_prog
= IXDR_GET_U_INT32(buf
);
86 objp
->pm_vers
= IXDR_GET_U_INT32(buf
);
87 objp
->pm_prot
= IXDR_GET_U_INT32(buf
);
88 objp
->pm_port
= IXDR_GET_U_INT32(buf
);
98 * pmaplist_ptr implements a linked list. The RPCL definition from
103 * struct pm__list *pml_next;
105 * typedef pm__list *pmaplist_ptr;
107 * Recall that "pointers" in XDR are encoded as a boolean, indicating whether
108 * there's any data behind the pointer, followed by the data (if any exists).
109 * The boolean can be interpreted as ``more data follows me''; if FALSE then
110 * nothing follows the boolean; if TRUE then the boolean is followed by an
111 * actual struct pmap, and another pmaplist_ptr (declared in RPCL as "struct
114 * This could be implemented via the xdr_pointer type, though this would
115 * result in one recursive call per element in the list. Rather than do that
116 * we can ``unwind'' the recursion into a while loop and use xdr_reference to
117 * serialize the pmap elements.
120 xdr_pmaplist_ptr(XDR
*xdrs
, pmaplist_ptr
*rp
)
123 * more_elements is pre-computed in case the direction is
124 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by
125 * xdr_bool when the direction is XDR_DECODE.
127 bool_t more_elements
;
128 int freeing
= (xdrs
->x_op
== XDR_FREE
);
130 pmaplist_ptr next_copy
;
133 more_elements
= (bool_t
)(*rp
!= NULL
);
134 if (!xdr_bool(xdrs
, &more_elements
))
137 return (TRUE
); /* we are done */
139 * the unfortunate side effect of non-recursion is that in
140 * the case of freeing we must remember the next object
141 * before we free the current object ...
144 next
= (*rp
)->pml_next
;
145 if (!xdr_reference(xdrs
, (caddr_t
*)rp
,
146 (uint_t
)sizeof (struct pmaplist
), (xdrproc_t
)xdr_pmap
))
152 * Note that in the subsequent iteration, next_copy
153 * gets nulled out by the xdr_reference
154 * but next itself survives.
157 rp
= &((*rp
)->pml_next
);
164 * xdr_pmaplist() is specified to take a PMAPLIST **, but is identical in
165 * functionality to xdr_pmaplist_ptr().
168 xdr_pmaplist(XDR
*xdrs
, PMAPLIST
**rp
)
170 return (xdr_pmaplist_ptr(xdrs
, (pmaplist_ptr
*)rp
));
175 * XDR remote call arguments
176 * written for XDR_ENCODE direction only
179 xdr_rmtcallargs(XDR
*xdrs
, struct p_rmtcallargs
*cap
)
181 uint_t lenposition
, argposition
, position
;
184 buf
= XDR_INLINE(xdrs
, 3 * BYTES_PER_XDR_UNIT
);
186 if (!xdr_u_int(xdrs
, (uint_t
*)&(cap
->prog
)) ||
187 !xdr_u_int(xdrs
, (uint_t
*)&(cap
->vers
)) ||
188 !xdr_u_int(xdrs
, (uint_t
*)&(cap
->proc
)))
191 IXDR_PUT_U_INT32(buf
, cap
->prog
);
192 IXDR_PUT_U_INT32(buf
, cap
->vers
);
193 IXDR_PUT_U_INT32(buf
, cap
->proc
);
197 * All the jugglery for just getting the size of the arguments
199 lenposition
= XDR_GETPOS(xdrs
);
200 if (!xdr_u_int(xdrs
, &(cap
->args
.args_len
)))
202 argposition
= XDR_GETPOS(xdrs
);
203 if (!(*cap
->xdr_args
)(xdrs
, cap
->args
.args_val
))
205 position
= XDR_GETPOS(xdrs
);
206 cap
->args
.args_len
= position
- argposition
;
207 XDR_SETPOS(xdrs
, lenposition
);
208 if (!xdr_u_int(xdrs
, &(cap
->args
.args_len
)))
210 XDR_SETPOS(xdrs
, position
);
215 * XDR remote call results
216 * written for XDR_DECODE direction only
219 xdr_rmtcallres(XDR
*xdrs
, struct p_rmtcallres
*crp
)
221 if (xdr_u_int(xdrs
, (uint_t
*)&crp
->port
) &&
222 xdr_u_int(xdrs
, &crp
->res
.res_len
))
223 return ((*(crp
->xdr_res
))(xdrs
, crp
->res
.res_val
));