xref: /illumos-gate/usr/src/uts/common/rpc/xdr.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
32*7c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
33*7c478bd9Sstevel@tonic-gate  */
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate /*
38*7c478bd9Sstevel@tonic-gate  * xdr.c, generic XDR routines implementation.
39*7c478bd9Sstevel@tonic-gate  * These are the "generic" xdr routines used to serialize and de-serialize
40*7c478bd9Sstevel@tonic-gate  * most common data items.  See xdr.h for more info on the interface to
41*7c478bd9Sstevel@tonic-gate  * xdr.
42*7c478bd9Sstevel@tonic-gate  */
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
45*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
47*7c478bd9Sstevel@tonic-gate #include <sys/systm.h>
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate #include <rpc/types.h>
50*7c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
51*7c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int32_t = xdr_int
54*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint32_t = xdr_u_int
55*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int64_t = xdr_longlong_t
56*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint64_t = xdr_u_longlong_t
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate #if !defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
59*7c478bd9Sstevel@tonic-gate #error "Exactly one of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined"
60*7c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
61*7c478bd9Sstevel@tonic-gate #error "Only one of _BIG_ENDIAN or _LITTLE_ENDIAN may be defined"
62*7c478bd9Sstevel@tonic-gate #endif
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate /*
65*7c478bd9Sstevel@tonic-gate  * constants specific to the xdr "protocol"
66*7c478bd9Sstevel@tonic-gate  */
67*7c478bd9Sstevel@tonic-gate #define	XDR_FALSE	((int32_t)0)
68*7c478bd9Sstevel@tonic-gate #define	XDR_TRUE	((int32_t)1)
69*7c478bd9Sstevel@tonic-gate #define	LASTUNSIGNED	((uint_t)0-1)
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate /*
72*7c478bd9Sstevel@tonic-gate  * for unit alignment
73*7c478bd9Sstevel@tonic-gate  */
74*7c478bd9Sstevel@tonic-gate static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate /*
77*7c478bd9Sstevel@tonic-gate  * Free a data structure using XDR
78*7c478bd9Sstevel@tonic-gate  * Not a filter, but a convenient utility nonetheless
79*7c478bd9Sstevel@tonic-gate  */
80*7c478bd9Sstevel@tonic-gate void
81*7c478bd9Sstevel@tonic-gate xdr_free(xdrproc_t proc, char *objp)
82*7c478bd9Sstevel@tonic-gate {
83*7c478bd9Sstevel@tonic-gate 	XDR x;
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 	x.x_op = XDR_FREE;
86*7c478bd9Sstevel@tonic-gate 	(*proc)(&x, objp);
87*7c478bd9Sstevel@tonic-gate }
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate /*
90*7c478bd9Sstevel@tonic-gate  * XDR nothing
91*7c478bd9Sstevel@tonic-gate  */
92*7c478bd9Sstevel@tonic-gate bool_t
93*7c478bd9Sstevel@tonic-gate xdr_void(void)
94*7c478bd9Sstevel@tonic-gate {
95*7c478bd9Sstevel@tonic-gate 	return (TRUE);
96*7c478bd9Sstevel@tonic-gate }
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate /*
99*7c478bd9Sstevel@tonic-gate  * XDR integers
100*7c478bd9Sstevel@tonic-gate  *
101*7c478bd9Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
102*7c478bd9Sstevel@tonic-gate  * xdr_int
103*7c478bd9Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
104*7c478bd9Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
105*7c478bd9Sstevel@tonic-gate  */
106*7c478bd9Sstevel@tonic-gate bool_t
107*7c478bd9Sstevel@tonic-gate xdr_int(XDR *xdrs, int *ip)
108*7c478bd9Sstevel@tonic-gate {
109*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
110*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs, ip));
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
113*7c478bd9Sstevel@tonic-gate 		return (XDR_GETINT32(xdrs, ip));
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
116*7c478bd9Sstevel@tonic-gate 		return (TRUE);
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
119*7c478bd9Sstevel@tonic-gate 	printf("xdr_int: FAILED\n");
120*7c478bd9Sstevel@tonic-gate #endif
121*7c478bd9Sstevel@tonic-gate 	return (FALSE);
122*7c478bd9Sstevel@tonic-gate }
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate /*
125*7c478bd9Sstevel@tonic-gate  * XDR unsigned integers
126*7c478bd9Sstevel@tonic-gate  *
127*7c478bd9Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
128*7c478bd9Sstevel@tonic-gate  * xdr_u_int
129*7c478bd9Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
130*7c478bd9Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
131*7c478bd9Sstevel@tonic-gate  */
132*7c478bd9Sstevel@tonic-gate bool_t
133*7c478bd9Sstevel@tonic-gate xdr_u_int(XDR *xdrs, uint_t *up)
134*7c478bd9Sstevel@tonic-gate {
135*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
136*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs, (int32_t *)up));
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
139*7c478bd9Sstevel@tonic-gate 		return (XDR_GETINT32(xdrs, (int32_t *)up));
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
142*7c478bd9Sstevel@tonic-gate 		return (TRUE);
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
145*7c478bd9Sstevel@tonic-gate 	printf("xdr_int: FAILED\n");
146*7c478bd9Sstevel@tonic-gate #endif
147*7c478bd9Sstevel@tonic-gate 	return (FALSE);
148*7c478bd9Sstevel@tonic-gate }
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate #if defined(_ILP32)
152*7c478bd9Sstevel@tonic-gate /*
153*7c478bd9Sstevel@tonic-gate  * xdr_long and xdr_u_long for binary compatability on ILP32 kernels.
154*7c478bd9Sstevel@tonic-gate  *
155*7c478bd9Sstevel@tonic-gate  * No prototypes since new code should not be using these interfaces.
156*7c478bd9Sstevel@tonic-gate  */
157*7c478bd9Sstevel@tonic-gate bool_t
158*7c478bd9Sstevel@tonic-gate xdr_long(XDR *xdrs, long *ip)
159*7c478bd9Sstevel@tonic-gate {
160*7c478bd9Sstevel@tonic-gate 	return (xdr_int(xdrs, (int *)ip));
161*7c478bd9Sstevel@tonic-gate }
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate bool_t
164*7c478bd9Sstevel@tonic-gate xdr_u_long(XDR *xdrs, unsigned long *up)
165*7c478bd9Sstevel@tonic-gate {
166*7c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, (uint_t *)up));
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate #endif /* _ILP32 */
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate /*
172*7c478bd9Sstevel@tonic-gate  * XDR long long integers
173*7c478bd9Sstevel@tonic-gate  */
174*7c478bd9Sstevel@tonic-gate bool_t
175*7c478bd9Sstevel@tonic-gate xdr_longlong_t(XDR *xdrs, longlong_t *hp)
176*7c478bd9Sstevel@tonic-gate {
177*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
178*7c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
179*7c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp +
180*7c478bd9Sstevel@tonic-gate 		    BYTES_PER_XDR_UNIT)) == TRUE) {
181*7c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)hp));
182*7c478bd9Sstevel@tonic-gate 		}
183*7c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
184*7c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)hp) == TRUE) {
185*7c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp +
186*7c478bd9Sstevel@tonic-gate 			    BYTES_PER_XDR_UNIT)));
187*7c478bd9Sstevel@tonic-gate 		}
188*7c478bd9Sstevel@tonic-gate #endif
189*7c478bd9Sstevel@tonic-gate 		return (FALSE);
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 	}
192*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
193*7c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
194*7c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)((char *)hp +
195*7c478bd9Sstevel@tonic-gate 		    BYTES_PER_XDR_UNIT)) == TRUE) {
196*7c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)hp));
197*7c478bd9Sstevel@tonic-gate 		}
198*7c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
199*7c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)hp) == TRUE) {
200*7c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)((char *)hp +
201*7c478bd9Sstevel@tonic-gate 			    BYTES_PER_XDR_UNIT)));
202*7c478bd9Sstevel@tonic-gate 		}
203*7c478bd9Sstevel@tonic-gate #endif
204*7c478bd9Sstevel@tonic-gate 		return (FALSE);
205*7c478bd9Sstevel@tonic-gate 	}
206*7c478bd9Sstevel@tonic-gate 	return (TRUE);
207*7c478bd9Sstevel@tonic-gate }
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate /*
210*7c478bd9Sstevel@tonic-gate  * XDR unsigned long long integers
211*7c478bd9Sstevel@tonic-gate  */
212*7c478bd9Sstevel@tonic-gate bool_t
213*7c478bd9Sstevel@tonic-gate xdr_u_longlong_t(XDR *xdrs, u_longlong_t *hp)
214*7c478bd9Sstevel@tonic-gate {
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
217*7c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
218*7c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp +
219*7c478bd9Sstevel@tonic-gate 		    BYTES_PER_XDR_UNIT)) == TRUE) {
220*7c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)hp));
221*7c478bd9Sstevel@tonic-gate 		}
222*7c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
223*7c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)hp) == TRUE) {
224*7c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp +
225*7c478bd9Sstevel@tonic-gate 			    BYTES_PER_XDR_UNIT)));
226*7c478bd9Sstevel@tonic-gate 		}
227*7c478bd9Sstevel@tonic-gate #endif
228*7c478bd9Sstevel@tonic-gate 		return (FALSE);
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate 	}
231*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
232*7c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
233*7c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)((char *)hp +
234*7c478bd9Sstevel@tonic-gate 		    BYTES_PER_XDR_UNIT)) == TRUE) {
235*7c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)hp));
236*7c478bd9Sstevel@tonic-gate 		}
237*7c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
238*7c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)hp) == TRUE) {
239*7c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)((char *)hp +
240*7c478bd9Sstevel@tonic-gate 			    BYTES_PER_XDR_UNIT)));
241*7c478bd9Sstevel@tonic-gate 		}
242*7c478bd9Sstevel@tonic-gate #endif
243*7c478bd9Sstevel@tonic-gate 		return (FALSE);
244*7c478bd9Sstevel@tonic-gate 	}
245*7c478bd9Sstevel@tonic-gate 	return (TRUE);
246*7c478bd9Sstevel@tonic-gate }
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate /*
249*7c478bd9Sstevel@tonic-gate  * XDR short integers
250*7c478bd9Sstevel@tonic-gate  */
251*7c478bd9Sstevel@tonic-gate bool_t
252*7c478bd9Sstevel@tonic-gate xdr_short(XDR *xdrs, short *sp)
253*7c478bd9Sstevel@tonic-gate {
254*7c478bd9Sstevel@tonic-gate 	int32_t l;
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
259*7c478bd9Sstevel@tonic-gate 		l = (int32_t)*sp;
260*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs, &l));
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
263*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, &l))
264*7c478bd9Sstevel@tonic-gate 			return (FALSE);
265*7c478bd9Sstevel@tonic-gate 		*sp = (short)l;
266*7c478bd9Sstevel@tonic-gate 		return (TRUE);
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
269*7c478bd9Sstevel@tonic-gate 		return (TRUE);
270*7c478bd9Sstevel@tonic-gate 	}
271*7c478bd9Sstevel@tonic-gate 	return (FALSE);
272*7c478bd9Sstevel@tonic-gate }
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate /*
275*7c478bd9Sstevel@tonic-gate  * XDR unsigned short integers
276*7c478bd9Sstevel@tonic-gate  */
277*7c478bd9Sstevel@tonic-gate bool_t
278*7c478bd9Sstevel@tonic-gate xdr_u_short(XDR *xdrs, ushort_t *usp)
279*7c478bd9Sstevel@tonic-gate {
280*7c478bd9Sstevel@tonic-gate 	uint32_t l;
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
285*7c478bd9Sstevel@tonic-gate 		l = (uint32_t)*usp;
286*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs, (int32_t *)&l));
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
289*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&l)) {
290*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
291*7c478bd9Sstevel@tonic-gate 			printf("xdr_u_short: decode FAILED\n");
292*7c478bd9Sstevel@tonic-gate #endif
293*7c478bd9Sstevel@tonic-gate 			return (FALSE);
294*7c478bd9Sstevel@tonic-gate 		}
295*7c478bd9Sstevel@tonic-gate 		*usp = (ushort_t)l;
296*7c478bd9Sstevel@tonic-gate 		return (TRUE);
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
299*7c478bd9Sstevel@tonic-gate 		return (TRUE);
300*7c478bd9Sstevel@tonic-gate 	}
301*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
302*7c478bd9Sstevel@tonic-gate 	printf("xdr_u_short: bad op FAILED\n");
303*7c478bd9Sstevel@tonic-gate #endif
304*7c478bd9Sstevel@tonic-gate 	return (FALSE);
305*7c478bd9Sstevel@tonic-gate }
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate /*
309*7c478bd9Sstevel@tonic-gate  * XDR a char
310*7c478bd9Sstevel@tonic-gate  */
311*7c478bd9Sstevel@tonic-gate bool_t
312*7c478bd9Sstevel@tonic-gate xdr_char(XDR *xdrs, char *cp)
313*7c478bd9Sstevel@tonic-gate {
314*7c478bd9Sstevel@tonic-gate 	int i;
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate 	i = (*cp);
317*7c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, &i)) {
318*7c478bd9Sstevel@tonic-gate 		return (FALSE);
319*7c478bd9Sstevel@tonic-gate 	}
320*7c478bd9Sstevel@tonic-gate 	*cp = (char)i;
321*7c478bd9Sstevel@tonic-gate 	return (TRUE);
322*7c478bd9Sstevel@tonic-gate }
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate /*
325*7c478bd9Sstevel@tonic-gate  * XDR booleans
326*7c478bd9Sstevel@tonic-gate  *
327*7c478bd9Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
328*7c478bd9Sstevel@tonic-gate  * xdr_bool
329*7c478bd9Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
330*7c478bd9Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
331*7c478bd9Sstevel@tonic-gate  */
332*7c478bd9Sstevel@tonic-gate bool_t
333*7c478bd9Sstevel@tonic-gate xdr_bool(XDR *xdrs, bool_t *bp)
334*7c478bd9Sstevel@tonic-gate {
335*7c478bd9Sstevel@tonic-gate 	int32_t i32b;
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
340*7c478bd9Sstevel@tonic-gate 		i32b = *bp ? XDR_TRUE : XDR_FALSE;
341*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs, &i32b));
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
344*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, &i32b)) {
345*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
346*7c478bd9Sstevel@tonic-gate 			printf("xdr_bool: decode FAILED\n");
347*7c478bd9Sstevel@tonic-gate #endif
348*7c478bd9Sstevel@tonic-gate 			return (FALSE);
349*7c478bd9Sstevel@tonic-gate 		}
350*7c478bd9Sstevel@tonic-gate 		*bp = (i32b == XDR_FALSE) ? FALSE : TRUE;
351*7c478bd9Sstevel@tonic-gate 		return (TRUE);
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
354*7c478bd9Sstevel@tonic-gate 		return (TRUE);
355*7c478bd9Sstevel@tonic-gate 	}
356*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
357*7c478bd9Sstevel@tonic-gate 	printf("xdr_bool: bad op FAILED\n");
358*7c478bd9Sstevel@tonic-gate #endif
359*7c478bd9Sstevel@tonic-gate 	return (FALSE);
360*7c478bd9Sstevel@tonic-gate }
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate /*
363*7c478bd9Sstevel@tonic-gate  * XDR enumerations
364*7c478bd9Sstevel@tonic-gate  *
365*7c478bd9Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
366*7c478bd9Sstevel@tonic-gate  * xdr_enum
367*7c478bd9Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
368*7c478bd9Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
369*7c478bd9Sstevel@tonic-gate  */
370*7c478bd9Sstevel@tonic-gate #ifndef lint
371*7c478bd9Sstevel@tonic-gate enum sizecheck { SIZEVAL } sizecheckvar;	/* used to find the size of */
372*7c478bd9Sstevel@tonic-gate 						/* an enum */
373*7c478bd9Sstevel@tonic-gate #endif
374*7c478bd9Sstevel@tonic-gate bool_t
375*7c478bd9Sstevel@tonic-gate xdr_enum(XDR *xdrs, enum_t *ep)
376*7c478bd9Sstevel@tonic-gate {
377*7c478bd9Sstevel@tonic-gate #ifndef lint
378*7c478bd9Sstevel@tonic-gate 	/*
379*7c478bd9Sstevel@tonic-gate 	 * enums are treated as ints
380*7c478bd9Sstevel@tonic-gate 	 */
381*7c478bd9Sstevel@tonic-gate 	if (sizeof (sizecheckvar) == sizeof (int32_t)) {
382*7c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs, (int32_t *)ep));
383*7c478bd9Sstevel@tonic-gate 	} else if (sizeof (sizecheckvar) == sizeof (short)) {
384*7c478bd9Sstevel@tonic-gate 		return (xdr_short(xdrs, (short *)ep));
385*7c478bd9Sstevel@tonic-gate 	} else {
386*7c478bd9Sstevel@tonic-gate 		return (FALSE);
387*7c478bd9Sstevel@tonic-gate 	}
388*7c478bd9Sstevel@tonic-gate #else
389*7c478bd9Sstevel@tonic-gate 	(void) (xdr_short(xdrs, (short *)ep));
390*7c478bd9Sstevel@tonic-gate 	return (xdr_int(xdrs, (int32_t *)ep));
391*7c478bd9Sstevel@tonic-gate #endif
392*7c478bd9Sstevel@tonic-gate }
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate /*
395*7c478bd9Sstevel@tonic-gate  * XDR opaque data
396*7c478bd9Sstevel@tonic-gate  * Allows the specification of a fixed size sequence of opaque bytes.
397*7c478bd9Sstevel@tonic-gate  * cp points to the opaque object and cnt gives the byte length.
398*7c478bd9Sstevel@tonic-gate  *
399*7c478bd9Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
400*7c478bd9Sstevel@tonic-gate  * xdr_opaque
401*7c478bd9Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
402*7c478bd9Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
403*7c478bd9Sstevel@tonic-gate  */
404*7c478bd9Sstevel@tonic-gate bool_t
405*7c478bd9Sstevel@tonic-gate xdr_opaque(XDR *xdrs, caddr_t cp, const uint_t cnt)
406*7c478bd9Sstevel@tonic-gate {
407*7c478bd9Sstevel@tonic-gate 	uint_t rndup;
408*7c478bd9Sstevel@tonic-gate 	static char crud[BYTES_PER_XDR_UNIT];
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate 	/*
411*7c478bd9Sstevel@tonic-gate 	 * if no data we are done
412*7c478bd9Sstevel@tonic-gate 	 */
413*7c478bd9Sstevel@tonic-gate 	if (cnt == 0)
414*7c478bd9Sstevel@tonic-gate 		return (TRUE);
415*7c478bd9Sstevel@tonic-gate 
416*7c478bd9Sstevel@tonic-gate 	/*
417*7c478bd9Sstevel@tonic-gate 	 * round byte count to full xdr units
418*7c478bd9Sstevel@tonic-gate 	 */
419*7c478bd9Sstevel@tonic-gate 	rndup = cnt % BYTES_PER_XDR_UNIT;
420*7c478bd9Sstevel@tonic-gate 	if (rndup != 0)
421*7c478bd9Sstevel@tonic-gate 		rndup = BYTES_PER_XDR_UNIT - rndup;
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
424*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
425*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
426*7c478bd9Sstevel@tonic-gate 			printf("xdr_opaque: decode FAILED\n");
427*7c478bd9Sstevel@tonic-gate #endif
428*7c478bd9Sstevel@tonic-gate 			return (FALSE);
429*7c478bd9Sstevel@tonic-gate 		}
430*7c478bd9Sstevel@tonic-gate 		if (rndup == 0)
431*7c478bd9Sstevel@tonic-gate 			return (TRUE);
432*7c478bd9Sstevel@tonic-gate 		return (XDR_GETBYTES(xdrs, (caddr_t)crud, rndup));
433*7c478bd9Sstevel@tonic-gate 	}
434*7c478bd9Sstevel@tonic-gate 
435*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
436*7c478bd9Sstevel@tonic-gate 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
437*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
438*7c478bd9Sstevel@tonic-gate 			printf("xdr_opaque: encode FAILED\n");
439*7c478bd9Sstevel@tonic-gate #endif
440*7c478bd9Sstevel@tonic-gate 			return (FALSE);
441*7c478bd9Sstevel@tonic-gate 		}
442*7c478bd9Sstevel@tonic-gate 		if (rndup == 0)
443*7c478bd9Sstevel@tonic-gate 			return (TRUE);
444*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
445*7c478bd9Sstevel@tonic-gate 	}
446*7c478bd9Sstevel@tonic-gate 
447*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
448*7c478bd9Sstevel@tonic-gate 		return (TRUE);
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
451*7c478bd9Sstevel@tonic-gate 	printf("xdr_opaque: bad op FAILED\n");
452*7c478bd9Sstevel@tonic-gate #endif
453*7c478bd9Sstevel@tonic-gate 	return (FALSE);
454*7c478bd9Sstevel@tonic-gate }
455*7c478bd9Sstevel@tonic-gate 
456*7c478bd9Sstevel@tonic-gate /*
457*7c478bd9Sstevel@tonic-gate  * XDR counted bytes
458*7c478bd9Sstevel@tonic-gate  * *cpp is a pointer to the bytes, *sizep is the count.
459*7c478bd9Sstevel@tonic-gate  * If *cpp is NULL maxsize bytes are allocated
460*7c478bd9Sstevel@tonic-gate  *
461*7c478bd9Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
462*7c478bd9Sstevel@tonic-gate  * xdr_bytes
463*7c478bd9Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
464*7c478bd9Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
465*7c478bd9Sstevel@tonic-gate  */
466*7c478bd9Sstevel@tonic-gate bool_t
467*7c478bd9Sstevel@tonic-gate xdr_bytes(XDR *xdrs, char **cpp, uint_t *sizep, const uint_t maxsize)
468*7c478bd9Sstevel@tonic-gate {
469*7c478bd9Sstevel@tonic-gate 	char *sp = *cpp;  /* sp is the actual string pointer */
470*7c478bd9Sstevel@tonic-gate 	uint_t nodesize;
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate 	/*
473*7c478bd9Sstevel@tonic-gate 	 * first deal with the length since xdr bytes are counted
474*7c478bd9Sstevel@tonic-gate 	 */
475*7c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, sizep)) {
476*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
477*7c478bd9Sstevel@tonic-gate 		printf("xdr_bytes: size FAILED\n");
478*7c478bd9Sstevel@tonic-gate #endif
479*7c478bd9Sstevel@tonic-gate 		return (FALSE);
480*7c478bd9Sstevel@tonic-gate 	}
481*7c478bd9Sstevel@tonic-gate 	nodesize = *sizep;
482*7c478bd9Sstevel@tonic-gate 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
483*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
484*7c478bd9Sstevel@tonic-gate 		printf("xdr_bytes: bad size (%d) FAILED (%d max)\n",
485*7c478bd9Sstevel@tonic-gate 		    nodesize, maxsize);
486*7c478bd9Sstevel@tonic-gate #endif
487*7c478bd9Sstevel@tonic-gate 		return (FALSE);
488*7c478bd9Sstevel@tonic-gate 	}
489*7c478bd9Sstevel@tonic-gate 
490*7c478bd9Sstevel@tonic-gate 	/*
491*7c478bd9Sstevel@tonic-gate 	 * now deal with the actual bytes
492*7c478bd9Sstevel@tonic-gate 	 */
493*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
494*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
495*7c478bd9Sstevel@tonic-gate 		if (nodesize == 0)
496*7c478bd9Sstevel@tonic-gate 			return (TRUE);
497*7c478bd9Sstevel@tonic-gate 		if (sp == NULL)
498*7c478bd9Sstevel@tonic-gate 			*cpp = sp = (char *)mem_alloc(nodesize);
499*7c478bd9Sstevel@tonic-gate 		/* FALLTHROUGH */
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
502*7c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs, sp, nodesize));
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
505*7c478bd9Sstevel@tonic-gate 		if (sp != NULL) {
506*7c478bd9Sstevel@tonic-gate 			mem_free(sp, nodesize);
507*7c478bd9Sstevel@tonic-gate 			*cpp = NULL;
508*7c478bd9Sstevel@tonic-gate 		}
509*7c478bd9Sstevel@tonic-gate 		return (TRUE);
510*7c478bd9Sstevel@tonic-gate 	}
511*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
512*7c478bd9Sstevel@tonic-gate 	printf("xdr_bytes: bad op FAILED\n");
513*7c478bd9Sstevel@tonic-gate #endif
514*7c478bd9Sstevel@tonic-gate 	return (FALSE);
515*7c478bd9Sstevel@tonic-gate }
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate /*
518*7c478bd9Sstevel@tonic-gate  * Implemented here due to commonality of the object.
519*7c478bd9Sstevel@tonic-gate  */
520*7c478bd9Sstevel@tonic-gate bool_t
521*7c478bd9Sstevel@tonic-gate xdr_netobj(XDR *xdrs, struct netobj *np)
522*7c478bd9Sstevel@tonic-gate {
523*7c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
524*7c478bd9Sstevel@tonic-gate }
525*7c478bd9Sstevel@tonic-gate 
526*7c478bd9Sstevel@tonic-gate /*
527*7c478bd9Sstevel@tonic-gate  * XDR a descriminated union
528*7c478bd9Sstevel@tonic-gate  * Support routine for discriminated unions.
529*7c478bd9Sstevel@tonic-gate  * You create an array of xdrdiscrim structures, terminated with
530*7c478bd9Sstevel@tonic-gate  * an entry with a null procedure pointer.  The routine gets
531*7c478bd9Sstevel@tonic-gate  * the discriminant value and then searches the array of xdrdiscrims
532*7c478bd9Sstevel@tonic-gate  * looking for that value.  It calls the procedure given in the xdrdiscrim
533*7c478bd9Sstevel@tonic-gate  * to handle the discriminant.  If there is no specific routine a default
534*7c478bd9Sstevel@tonic-gate  * routine may be called.
535*7c478bd9Sstevel@tonic-gate  * If there is no specific or default routine an error is returned.
536*7c478bd9Sstevel@tonic-gate  */
537*7c478bd9Sstevel@tonic-gate bool_t
538*7c478bd9Sstevel@tonic-gate xdr_union(XDR *xdrs, enum_t *dscmp, char *unp,
539*7c478bd9Sstevel@tonic-gate 	const struct xdr_discrim *choices, const xdrproc_t dfault)
540*7c478bd9Sstevel@tonic-gate {
541*7c478bd9Sstevel@tonic-gate 	enum_t dscm;
542*7c478bd9Sstevel@tonic-gate 
543*7c478bd9Sstevel@tonic-gate 	/*
544*7c478bd9Sstevel@tonic-gate 	 * we deal with the discriminator;  it's an enum
545*7c478bd9Sstevel@tonic-gate 	 */
546*7c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, dscmp)) {
547*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
548*7c478bd9Sstevel@tonic-gate 		printf("xdr_enum: dscmp FAILED\n");
549*7c478bd9Sstevel@tonic-gate #endif
550*7c478bd9Sstevel@tonic-gate 		return (FALSE);
551*7c478bd9Sstevel@tonic-gate 	}
552*7c478bd9Sstevel@tonic-gate 	dscm = *dscmp;
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate 	/*
555*7c478bd9Sstevel@tonic-gate 	 * search choices for a value that matches the discriminator.
556*7c478bd9Sstevel@tonic-gate 	 * if we find one, execute the xdr routine for that value.
557*7c478bd9Sstevel@tonic-gate 	 */
558*7c478bd9Sstevel@tonic-gate 	for (; choices->proc != NULL_xdrproc_t; choices++) {
559*7c478bd9Sstevel@tonic-gate 		if (choices->value == dscm)
560*7c478bd9Sstevel@tonic-gate 			return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
561*7c478bd9Sstevel@tonic-gate 	}
562*7c478bd9Sstevel@tonic-gate 
563*7c478bd9Sstevel@tonic-gate 	/*
564*7c478bd9Sstevel@tonic-gate 	 * no match - execute the default xdr routine if there is one
565*7c478bd9Sstevel@tonic-gate 	 */
566*7c478bd9Sstevel@tonic-gate 	return ((dfault == NULL_xdrproc_t) ? FALSE :
567*7c478bd9Sstevel@tonic-gate 	    (*dfault)(xdrs, unp, LASTUNSIGNED));
568*7c478bd9Sstevel@tonic-gate }
569*7c478bd9Sstevel@tonic-gate 
570*7c478bd9Sstevel@tonic-gate 
571*7c478bd9Sstevel@tonic-gate /*
572*7c478bd9Sstevel@tonic-gate  * Non-portable xdr primitives.
573*7c478bd9Sstevel@tonic-gate  * Care should be taken when moving these routines to new architectures.
574*7c478bd9Sstevel@tonic-gate  */
575*7c478bd9Sstevel@tonic-gate 
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate /*
578*7c478bd9Sstevel@tonic-gate  * XDR null terminated ASCII strings
579*7c478bd9Sstevel@tonic-gate  * xdr_string deals with "C strings" - arrays of bytes that are
580*7c478bd9Sstevel@tonic-gate  * terminated by a NULL character.  The parameter cpp references a
581*7c478bd9Sstevel@tonic-gate  * pointer to storage; If the pointer is null, then the necessary
582*7c478bd9Sstevel@tonic-gate  * storage is allocated.  The last parameter is the max allowed length
583*7c478bd9Sstevel@tonic-gate  * of the string as specified by a protocol.
584*7c478bd9Sstevel@tonic-gate  */
585*7c478bd9Sstevel@tonic-gate bool_t
586*7c478bd9Sstevel@tonic-gate xdr_string(XDR *xdrs, char **cpp, const uint_t maxsize)
587*7c478bd9Sstevel@tonic-gate {
588*7c478bd9Sstevel@tonic-gate 	char *sp = *cpp;  /* sp is the actual string pointer */
589*7c478bd9Sstevel@tonic-gate 	uint_t size;
590*7c478bd9Sstevel@tonic-gate 	uint_t nodesize;
591*7c478bd9Sstevel@tonic-gate 
592*7c478bd9Sstevel@tonic-gate 	/*
593*7c478bd9Sstevel@tonic-gate 	 * first deal with the length since xdr strings are counted-strings
594*7c478bd9Sstevel@tonic-gate 	 */
595*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
596*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
597*7c478bd9Sstevel@tonic-gate 		if (sp == NULL)
598*7c478bd9Sstevel@tonic-gate 			return (TRUE);	/* already free */
599*7c478bd9Sstevel@tonic-gate 		/* FALLTHROUGH */
600*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
601*7c478bd9Sstevel@tonic-gate 		size = (sp != NULL) ? (uint_t)strlen(sp) : 0;
602*7c478bd9Sstevel@tonic-gate 		break;
603*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
604*7c478bd9Sstevel@tonic-gate 		break;
605*7c478bd9Sstevel@tonic-gate 	}
606*7c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &size)) {
607*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
608*7c478bd9Sstevel@tonic-gate 		printf("xdr_string: size FAILED\n");
609*7c478bd9Sstevel@tonic-gate #endif
610*7c478bd9Sstevel@tonic-gate 		return (FALSE);
611*7c478bd9Sstevel@tonic-gate 	}
612*7c478bd9Sstevel@tonic-gate 	if (size > maxsize) {
613*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
614*7c478bd9Sstevel@tonic-gate 		printf("xdr_string: bad size FAILED\n");
615*7c478bd9Sstevel@tonic-gate #endif
616*7c478bd9Sstevel@tonic-gate 		return (FALSE);
617*7c478bd9Sstevel@tonic-gate 	}
618*7c478bd9Sstevel@tonic-gate 	nodesize = size + 1;
619*7c478bd9Sstevel@tonic-gate 
620*7c478bd9Sstevel@tonic-gate 	/*
621*7c478bd9Sstevel@tonic-gate 	 * now deal with the actual bytes
622*7c478bd9Sstevel@tonic-gate 	 */
623*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
624*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
625*7c478bd9Sstevel@tonic-gate 		if (nodesize == 0)
626*7c478bd9Sstevel@tonic-gate 			return (TRUE);
627*7c478bd9Sstevel@tonic-gate 		if (sp == NULL)
628*7c478bd9Sstevel@tonic-gate 			sp = (char *)mem_alloc(nodesize);
629*7c478bd9Sstevel@tonic-gate 		sp[size] = 0;
630*7c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, sp, size)) {
631*7c478bd9Sstevel@tonic-gate 			/*
632*7c478bd9Sstevel@tonic-gate 			 * free up memory if allocated here
633*7c478bd9Sstevel@tonic-gate 			 */
634*7c478bd9Sstevel@tonic-gate 			if (*cpp == NULL) {
635*7c478bd9Sstevel@tonic-gate 				mem_free(sp, nodesize);
636*7c478bd9Sstevel@tonic-gate 			}
637*7c478bd9Sstevel@tonic-gate 			return (FALSE);
638*7c478bd9Sstevel@tonic-gate 		}
639*7c478bd9Sstevel@tonic-gate 		if (strlen(sp) != size) {
640*7c478bd9Sstevel@tonic-gate 			if (*cpp == NULL) {
641*7c478bd9Sstevel@tonic-gate 				mem_free(sp, nodesize);
642*7c478bd9Sstevel@tonic-gate 			}
643*7c478bd9Sstevel@tonic-gate 			return (FALSE);
644*7c478bd9Sstevel@tonic-gate 		}
645*7c478bd9Sstevel@tonic-gate 		*cpp = sp;
646*7c478bd9Sstevel@tonic-gate 		return (TRUE);
647*7c478bd9Sstevel@tonic-gate 
648*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
649*7c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs, sp, size));
650*7c478bd9Sstevel@tonic-gate 
651*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
652*7c478bd9Sstevel@tonic-gate 		mem_free(sp, nodesize);
653*7c478bd9Sstevel@tonic-gate 		*cpp = NULL;
654*7c478bd9Sstevel@tonic-gate 		return (TRUE);
655*7c478bd9Sstevel@tonic-gate 	}
656*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
657*7c478bd9Sstevel@tonic-gate 	printf("xdr_string: bad op FAILED\n");
658*7c478bd9Sstevel@tonic-gate #endif
659*7c478bd9Sstevel@tonic-gate 	return (FALSE);
660*7c478bd9Sstevel@tonic-gate }
661*7c478bd9Sstevel@tonic-gate 
662*7c478bd9Sstevel@tonic-gate /*
663*7c478bd9Sstevel@tonic-gate  * Wrapper for xdr_string that can be called directly from
664*7c478bd9Sstevel@tonic-gate  * routines like clnt_call
665*7c478bd9Sstevel@tonic-gate  */
666*7c478bd9Sstevel@tonic-gate bool_t
667*7c478bd9Sstevel@tonic-gate xdr_wrapstring(XDR *xdrs, char **cpp)
668*7c478bd9Sstevel@tonic-gate {
669*7c478bd9Sstevel@tonic-gate 	if (xdr_string(xdrs, cpp, LASTUNSIGNED))
670*7c478bd9Sstevel@tonic-gate 		return (TRUE);
671*7c478bd9Sstevel@tonic-gate 	return (FALSE);
672*7c478bd9Sstevel@tonic-gate }
673