xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/nfs/rpc/xdr.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero  *
4*10465441SEvalZero  * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero  *
6*10465441SEvalZero  * Change Logs:
7*10465441SEvalZero  * Date           Author       Notes
8*10465441SEvalZero  */
9*10465441SEvalZero /* @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC */
10*10465441SEvalZero /*
11*10465441SEvalZero  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
12*10465441SEvalZero  * unrestricted use provided that this legend is included on all tape
13*10465441SEvalZero  * media and as a part of the software program in whole or part.  Users
14*10465441SEvalZero  * may copy or modify Sun RPC without charge, but are not authorized
15*10465441SEvalZero  * to license or distribute it to anyone else except as part of a product or
16*10465441SEvalZero  * program developed by the user.
17*10465441SEvalZero  *
18*10465441SEvalZero  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
19*10465441SEvalZero  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
20*10465441SEvalZero  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
21*10465441SEvalZero  *
22*10465441SEvalZero  * Sun RPC is provided with no support and without any obligation on the
23*10465441SEvalZero  * part of Sun Microsystems, Inc. to assist in its use, correction,
24*10465441SEvalZero  * modification or enhancement.
25*10465441SEvalZero  *
26*10465441SEvalZero  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
27*10465441SEvalZero  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
28*10465441SEvalZero  * OR ANY PART THEREOF.
29*10465441SEvalZero  *
30*10465441SEvalZero  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
31*10465441SEvalZero  * or profits or other special, indirect and consequential damages, even if
32*10465441SEvalZero  * Sun has been advised of the possibility of such damages.
33*10465441SEvalZero  *
34*10465441SEvalZero  * Sun Microsystems, Inc.
35*10465441SEvalZero  * 2550 Garcia Avenue
36*10465441SEvalZero  * Mountain View, California  94043
37*10465441SEvalZero  */
38*10465441SEvalZero #if !defined(lint) && defined(SCCSIDS)
39*10465441SEvalZero static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
40*10465441SEvalZero #endif
41*10465441SEvalZero 
42*10465441SEvalZero /*
43*10465441SEvalZero  * xdr.c, Generic XDR routines implementation.
44*10465441SEvalZero  *
45*10465441SEvalZero  * Copyright (C) 1986, Sun Microsystems, Inc.
46*10465441SEvalZero  *
47*10465441SEvalZero  * These are the "generic" xdr routines used to serialize and de-serialize
48*10465441SEvalZero  * most common data items.  See xdr.h for more info on the interface to
49*10465441SEvalZero  * xdr.
50*10465441SEvalZero  */
51*10465441SEvalZero 
52*10465441SEvalZero #include <stdio.h>
53*10465441SEvalZero #include <stdlib.h>
54*10465441SEvalZero #include <rpc/types.h>
55*10465441SEvalZero #include <rpc/xdr.h>
56*10465441SEvalZero #include <string.h>
57*10465441SEvalZero 
58*10465441SEvalZero /*
59*10465441SEvalZero  * constants specific to the xdr "protocol"
60*10465441SEvalZero  */
61*10465441SEvalZero #define XDR_FALSE		((long) 0)
62*10465441SEvalZero #define XDR_TRUE		((long) 1)
63*10465441SEvalZero #define LASTUNSIGNED	((unsigned int) 0-1)
64*10465441SEvalZero 
65*10465441SEvalZero /*
66*10465441SEvalZero  * for unit alignment
67*10465441SEvalZero  */
68*10465441SEvalZero static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
69*10465441SEvalZero 
70*10465441SEvalZero /*
71*10465441SEvalZero  * Free a data structure using XDR
72*10465441SEvalZero  * Not a filter, but a convenient utility nonetheless
73*10465441SEvalZero  */
xdr_free(xdrproc_t proc,char * objp)74*10465441SEvalZero void xdr_free(xdrproc_t proc, char* objp)
75*10465441SEvalZero {
76*10465441SEvalZero 	XDR x;
77*10465441SEvalZero 
78*10465441SEvalZero 	x.x_op = XDR_FREE;
79*10465441SEvalZero 	(*proc) (&x, objp);
80*10465441SEvalZero }
81*10465441SEvalZero 
82*10465441SEvalZero /*
83*10465441SEvalZero  * XDR nothing
84*10465441SEvalZero  */
xdr_void()85*10465441SEvalZero bool_t xdr_void( /* xdrs, addr */ )
86*10465441SEvalZero 	/* XDR *xdrs; */
87*10465441SEvalZero 	/* char* addr; */
88*10465441SEvalZero {
89*10465441SEvalZero 
90*10465441SEvalZero 	return (TRUE);
91*10465441SEvalZero }
92*10465441SEvalZero 
93*10465441SEvalZero /*
94*10465441SEvalZero  * XDR integers
95*10465441SEvalZero  */
xdr_int(XDR * xdrs,int * ip)96*10465441SEvalZero bool_t xdr_int(XDR* xdrs, int* ip)
97*10465441SEvalZero {
98*10465441SEvalZero 	if (sizeof(int) == sizeof(long)) {
99*10465441SEvalZero 		return (xdr_long(xdrs, (long *) ip));
100*10465441SEvalZero 	} else if (sizeof(int) < sizeof(long)) {
101*10465441SEvalZero 	  long l;
102*10465441SEvalZero 	  switch (xdrs->x_op) {
103*10465441SEvalZero 	  case XDR_ENCODE:
104*10465441SEvalZero 		l = (long) *ip;
105*10465441SEvalZero 		return XDR_PUTLONG(xdrs, &l);
106*10465441SEvalZero 	  case XDR_DECODE:
107*10465441SEvalZero 		if (!XDR_GETLONG(xdrs, &l))
108*10465441SEvalZero 		  return FALSE;
109*10465441SEvalZero 		*ip = (int) l;
110*10465441SEvalZero 	  case XDR_FREE:
111*10465441SEvalZero 		return TRUE;
112*10465441SEvalZero 	  }
113*10465441SEvalZero 	  return FALSE;
114*10465441SEvalZero 	} else {
115*10465441SEvalZero 		return (xdr_short(xdrs, (short *) ip));
116*10465441SEvalZero 	}
117*10465441SEvalZero }
118*10465441SEvalZero 
119*10465441SEvalZero /*
120*10465441SEvalZero  * XDR unsigned integers
121*10465441SEvalZero  */
xdr_u_int(XDR * xdrs,unsigned int * up)122*10465441SEvalZero bool_t xdr_u_int(XDR* xdrs, unsigned int* up)
123*10465441SEvalZero {
124*10465441SEvalZero 	if (sizeof(unsigned int) == sizeof(unsigned long)) {
125*10465441SEvalZero 		return (xdr_u_long(xdrs, (unsigned long *) up));
126*10465441SEvalZero 	} else if (sizeof(unsigned int) < sizeof(unsigned long)) {
127*10465441SEvalZero 	  unsigned long l;
128*10465441SEvalZero 	  switch (xdrs->x_op) {
129*10465441SEvalZero 	  case XDR_ENCODE:
130*10465441SEvalZero 		l = (unsigned long) *up;
131*10465441SEvalZero 		return XDR_PUTLONG(xdrs, (long*)&l);
132*10465441SEvalZero 	  case XDR_DECODE:
133*10465441SEvalZero 		if (!XDR_GETLONG(xdrs, (long*)&l))
134*10465441SEvalZero 		  return FALSE;
135*10465441SEvalZero 		*up = (unsigned int) l;
136*10465441SEvalZero 	  case XDR_FREE:
137*10465441SEvalZero 		return TRUE;
138*10465441SEvalZero 	  }
139*10465441SEvalZero 	  return FALSE;
140*10465441SEvalZero 	} else {
141*10465441SEvalZero 		return (xdr_short(xdrs, (short *) up));
142*10465441SEvalZero 	}
143*10465441SEvalZero }
144*10465441SEvalZero 
145*10465441SEvalZero /*
146*10465441SEvalZero  * XDR long integers
147*10465441SEvalZero  * same as xdr_u_long - open coded to save a proc call!
148*10465441SEvalZero  */
xdr_long(XDR * xdrs,long * lp)149*10465441SEvalZero bool_t xdr_long(XDR* xdrs, long* lp)
150*10465441SEvalZero {
151*10465441SEvalZero 
152*10465441SEvalZero 	if (xdrs->x_op == XDR_ENCODE
153*10465441SEvalZero 		&& (sizeof(int32_t) == sizeof(long)
154*10465441SEvalZero 			|| (int32_t) *lp == *lp))
155*10465441SEvalZero 		return (XDR_PUTLONG(xdrs, lp));
156*10465441SEvalZero 
157*10465441SEvalZero 	if (xdrs->x_op == XDR_DECODE)
158*10465441SEvalZero 		return (XDR_GETLONG(xdrs, lp));
159*10465441SEvalZero 
160*10465441SEvalZero 	if (xdrs->x_op == XDR_FREE)
161*10465441SEvalZero 		return (TRUE);
162*10465441SEvalZero 
163*10465441SEvalZero 	return (FALSE);
164*10465441SEvalZero }
165*10465441SEvalZero 
166*10465441SEvalZero /*
167*10465441SEvalZero  * XDR unsigned long integers
168*10465441SEvalZero  * same as xdr_long - open coded to save a proc call!
169*10465441SEvalZero  */
xdr_u_long(XDR * xdrs,unsigned long * ulp)170*10465441SEvalZero bool_t xdr_u_long(XDR* xdrs, unsigned long* ulp)
171*10465441SEvalZero {
172*10465441SEvalZero 
173*10465441SEvalZero   if (xdrs->x_op == XDR_DECODE) {
174*10465441SEvalZero 	long l;
175*10465441SEvalZero 	if (XDR_GETLONG(xdrs, &l) == FALSE)
176*10465441SEvalZero 	  return FALSE;
177*10465441SEvalZero 	*ulp = (uint32_t) l;
178*10465441SEvalZero 	return TRUE;
179*10465441SEvalZero   }
180*10465441SEvalZero 
181*10465441SEvalZero   if (xdrs->x_op == XDR_ENCODE) {
182*10465441SEvalZero 	if (sizeof(uint32_t) != sizeof(unsigned long)
183*10465441SEvalZero 		&& (uint32_t) *ulp != *ulp)
184*10465441SEvalZero 	  return FALSE;
185*10465441SEvalZero 
186*10465441SEvalZero 		return (XDR_PUTLONG(xdrs, (long *) ulp));
187*10465441SEvalZero   }
188*10465441SEvalZero 
189*10465441SEvalZero 	if (xdrs->x_op == XDR_FREE)
190*10465441SEvalZero 		return (TRUE);
191*10465441SEvalZero 
192*10465441SEvalZero 	return (FALSE);
193*10465441SEvalZero }
194*10465441SEvalZero 
195*10465441SEvalZero 
196*10465441SEvalZero /*
197*10465441SEvalZero  * XDR long long integers
198*10465441SEvalZero  */
xdr_longlong_t(XDR * xdrs,long long * llp)199*10465441SEvalZero bool_t xdr_longlong_t (XDR * xdrs, long long* llp)
200*10465441SEvalZero {
201*10465441SEvalZero   int32_t t1, t2;
202*10465441SEvalZero 
203*10465441SEvalZero   switch (xdrs->x_op)
204*10465441SEvalZero     {
205*10465441SEvalZero     case XDR_ENCODE:
206*10465441SEvalZero       t1 = (int32_t) ((*llp) >> 32);
207*10465441SEvalZero       t2 = (int32_t) (*llp);
208*10465441SEvalZero       return (XDR_PUTLONG (xdrs, &t1) && XDR_PUTLONG (xdrs, &t2));
209*10465441SEvalZero 
210*10465441SEvalZero     case XDR_DECODE:
211*10465441SEvalZero       if (!XDR_GETLONG (xdrs, &t1) || !XDR_GETLONG (xdrs, &t2))
212*10465441SEvalZero         return FALSE;
213*10465441SEvalZero       *llp = ((int64_t) t1) << 32;
214*10465441SEvalZero       *llp |= (uint32_t) t2;
215*10465441SEvalZero       return TRUE;
216*10465441SEvalZero 
217*10465441SEvalZero     case XDR_FREE:
218*10465441SEvalZero       return TRUE;
219*10465441SEvalZero     }
220*10465441SEvalZero   return FALSE;
221*10465441SEvalZero }
222*10465441SEvalZero 
223*10465441SEvalZero /*
224*10465441SEvalZero  * XDR unsigned long long integers
225*10465441SEvalZero  */
xdr_u_longlong_t(XDR * xdrs,unsigned long long * ullp)226*10465441SEvalZero bool_t xdr_u_longlong_t (XDR * xdrs, unsigned long long* ullp)
227*10465441SEvalZero {
228*10465441SEvalZero   uint32_t t1, t2;
229*10465441SEvalZero 
230*10465441SEvalZero   switch (xdrs->x_op)
231*10465441SEvalZero     {
232*10465441SEvalZero     case XDR_ENCODE:
233*10465441SEvalZero       t1 = (uint32_t) ((*ullp) >> 32);
234*10465441SEvalZero       t2 = (uint32_t) (*ullp);
235*10465441SEvalZero       return (XDR_PUTLONG (xdrs, (int32_t *)&t1) &&
236*10465441SEvalZero               XDR_PUTLONG (xdrs, (int32_t *)&t2));
237*10465441SEvalZero 
238*10465441SEvalZero     case XDR_DECODE:
239*10465441SEvalZero       if (!XDR_GETLONG (xdrs, (int32_t *)&t1) ||
240*10465441SEvalZero           !XDR_GETLONG (xdrs, (int32_t *)&t2))
241*10465441SEvalZero         return FALSE;
242*10465441SEvalZero       *ullp = ((uint64_t) t1) << 32;
243*10465441SEvalZero       *ullp |= t2;
244*10465441SEvalZero       return TRUE;
245*10465441SEvalZero 
246*10465441SEvalZero     case XDR_FREE:
247*10465441SEvalZero       return TRUE;
248*10465441SEvalZero     }
249*10465441SEvalZero   return FALSE;
250*10465441SEvalZero }
251*10465441SEvalZero 
252*10465441SEvalZero /*
253*10465441SEvalZero  * XDR short integers
254*10465441SEvalZero  */
xdr_short(XDR * xdrs,short * sp)255*10465441SEvalZero bool_t xdr_short(XDR* xdrs, short* sp)
256*10465441SEvalZero {
257*10465441SEvalZero 	long l;
258*10465441SEvalZero 
259*10465441SEvalZero 	switch (xdrs->x_op) {
260*10465441SEvalZero 
261*10465441SEvalZero 	case XDR_ENCODE:
262*10465441SEvalZero 		l = (long) *sp;
263*10465441SEvalZero 		return (XDR_PUTLONG(xdrs, &l));
264*10465441SEvalZero 
265*10465441SEvalZero 	case XDR_DECODE:
266*10465441SEvalZero 		if (!XDR_GETLONG(xdrs, &l)) {
267*10465441SEvalZero 			return (FALSE);
268*10465441SEvalZero 		}
269*10465441SEvalZero 		*sp = (short) l;
270*10465441SEvalZero 		return (TRUE);
271*10465441SEvalZero 
272*10465441SEvalZero 	case XDR_FREE:
273*10465441SEvalZero 		return (TRUE);
274*10465441SEvalZero 	}
275*10465441SEvalZero 	return (FALSE);
276*10465441SEvalZero }
277*10465441SEvalZero 
278*10465441SEvalZero /*
279*10465441SEvalZero  * XDR unsigned short integers
280*10465441SEvalZero  */
xdr_u_short(XDR * xdrs,unsigned short * usp)281*10465441SEvalZero bool_t xdr_u_short(XDR* xdrs, unsigned short* usp)
282*10465441SEvalZero {
283*10465441SEvalZero 	unsigned long l;
284*10465441SEvalZero 
285*10465441SEvalZero 	switch (xdrs->x_op) {
286*10465441SEvalZero 
287*10465441SEvalZero 	case XDR_ENCODE:
288*10465441SEvalZero 		l = (unsigned long) * usp;
289*10465441SEvalZero 		return (XDR_PUTLONG(xdrs, (long*)&l));
290*10465441SEvalZero 
291*10465441SEvalZero 	case XDR_DECODE:
292*10465441SEvalZero 		if (!XDR_GETLONG(xdrs, (long*)&l)) {
293*10465441SEvalZero 			return (FALSE);
294*10465441SEvalZero 		}
295*10465441SEvalZero 		*usp = (unsigned short) l;
296*10465441SEvalZero 		return (TRUE);
297*10465441SEvalZero 
298*10465441SEvalZero 	case XDR_FREE:
299*10465441SEvalZero 		return (TRUE);
300*10465441SEvalZero 	}
301*10465441SEvalZero 	return (FALSE);
302*10465441SEvalZero }
303*10465441SEvalZero 
304*10465441SEvalZero 
305*10465441SEvalZero /*
306*10465441SEvalZero  * XDR a char
307*10465441SEvalZero  */
xdr_char(XDR * xdrs,char * cp)308*10465441SEvalZero bool_t xdr_char(XDR* xdrs, char* cp)
309*10465441SEvalZero {
310*10465441SEvalZero 	int i;
311*10465441SEvalZero 
312*10465441SEvalZero 	i = (*cp);
313*10465441SEvalZero 	if (!xdr_int(xdrs, &i)) {
314*10465441SEvalZero 		return (FALSE);
315*10465441SEvalZero 	}
316*10465441SEvalZero 	*cp = i;
317*10465441SEvalZero 	return (TRUE);
318*10465441SEvalZero }
319*10465441SEvalZero 
320*10465441SEvalZero /*
321*10465441SEvalZero  * XDR an unsigned char
322*10465441SEvalZero  */
xdr_u_char(XDR * xdrs,unsigned char * cp)323*10465441SEvalZero bool_t xdr_u_char(XDR* xdrs, unsigned char* cp)
324*10465441SEvalZero {
325*10465441SEvalZero 	unsigned int u;
326*10465441SEvalZero 
327*10465441SEvalZero 	u = (*cp);
328*10465441SEvalZero 	if (!xdr_u_int(xdrs, &u)) {
329*10465441SEvalZero 		return (FALSE);
330*10465441SEvalZero 	}
331*10465441SEvalZero 	*cp = u;
332*10465441SEvalZero 	return (TRUE);
333*10465441SEvalZero }
334*10465441SEvalZero 
335*10465441SEvalZero /*
336*10465441SEvalZero  * XDR booleans
337*10465441SEvalZero  */
xdr_bool(XDR * xdrs,bool_t * bp)338*10465441SEvalZero bool_t xdr_bool(XDR *xdrs, bool_t *bp)
339*10465441SEvalZero {
340*10465441SEvalZero 	long lb;
341*10465441SEvalZero 
342*10465441SEvalZero 	switch (xdrs->x_op) {
343*10465441SEvalZero 
344*10465441SEvalZero 	case XDR_ENCODE:
345*10465441SEvalZero 		lb = *bp ? XDR_TRUE : XDR_FALSE;
346*10465441SEvalZero 		return (XDR_PUTLONG(xdrs, &lb));
347*10465441SEvalZero 
348*10465441SEvalZero 	case XDR_DECODE:
349*10465441SEvalZero 		if (!XDR_GETLONG(xdrs, &lb)) {
350*10465441SEvalZero 			return (FALSE);
351*10465441SEvalZero 		}
352*10465441SEvalZero 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
353*10465441SEvalZero 		return (TRUE);
354*10465441SEvalZero 
355*10465441SEvalZero 	case XDR_FREE:
356*10465441SEvalZero 		return (TRUE);
357*10465441SEvalZero 	}
358*10465441SEvalZero 	return (FALSE);
359*10465441SEvalZero }
360*10465441SEvalZero 
361*10465441SEvalZero /*
362*10465441SEvalZero  * XDR enumerations
363*10465441SEvalZero  */
xdr_enum(XDR * xdrs,enum_t * ep)364*10465441SEvalZero bool_t xdr_enum(XDR *xdrs, enum_t *ep)
365*10465441SEvalZero {
366*10465441SEvalZero 	/*
367*10465441SEvalZero 	 * enums are treated as ints
368*10465441SEvalZero 	 */
369*10465441SEvalZero 	return (xdr_long(xdrs, (long *) ep));
370*10465441SEvalZero }
371*10465441SEvalZero 
372*10465441SEvalZero /*
373*10465441SEvalZero  * XDR opaque data
374*10465441SEvalZero  * Allows the specification of a fixed size sequence of opaque bytes.
375*10465441SEvalZero  * cp points to the opaque object and cnt gives the byte length.
376*10465441SEvalZero  */
xdr_opaque(XDR * xdrs,char * cp,unsigned int cnt)377*10465441SEvalZero bool_t xdr_opaque(XDR *xdrs, char* cp, unsigned int cnt)
378*10465441SEvalZero {
379*10465441SEvalZero 	register unsigned int rndup;
380*10465441SEvalZero 	static char crud[BYTES_PER_XDR_UNIT];
381*10465441SEvalZero 
382*10465441SEvalZero 	/*
383*10465441SEvalZero 	 * if no data we are done
384*10465441SEvalZero 	 */
385*10465441SEvalZero 	if (cnt == 0)
386*10465441SEvalZero 		return (TRUE);
387*10465441SEvalZero 
388*10465441SEvalZero 	/*
389*10465441SEvalZero 	 * round byte count to full xdr units
390*10465441SEvalZero 	 */
391*10465441SEvalZero 	rndup = cnt % BYTES_PER_XDR_UNIT;
392*10465441SEvalZero 	if (rndup > 0)
393*10465441SEvalZero 		rndup = BYTES_PER_XDR_UNIT - rndup;
394*10465441SEvalZero 
395*10465441SEvalZero 	if (xdrs->x_op == XDR_DECODE) {
396*10465441SEvalZero 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
397*10465441SEvalZero 			return (FALSE);
398*10465441SEvalZero 		}
399*10465441SEvalZero 		if (rndup == 0)
400*10465441SEvalZero 			return (TRUE);
401*10465441SEvalZero 		return (XDR_GETBYTES(xdrs, crud, rndup));
402*10465441SEvalZero 	}
403*10465441SEvalZero 
404*10465441SEvalZero 	if (xdrs->x_op == XDR_ENCODE) {
405*10465441SEvalZero 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
406*10465441SEvalZero 			return (FALSE);
407*10465441SEvalZero 		}
408*10465441SEvalZero 		if (rndup == 0)
409*10465441SEvalZero 			return (TRUE);
410*10465441SEvalZero 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
411*10465441SEvalZero 	}
412*10465441SEvalZero 
413*10465441SEvalZero 	if (xdrs->x_op == XDR_FREE) {
414*10465441SEvalZero 		return (TRUE);
415*10465441SEvalZero 	}
416*10465441SEvalZero 
417*10465441SEvalZero 	return (FALSE);
418*10465441SEvalZero }
419*10465441SEvalZero 
420*10465441SEvalZero /*
421*10465441SEvalZero  * XDR counted bytes
422*10465441SEvalZero  * *cpp is a pointer to the bytes, *sizep is the count.
423*10465441SEvalZero  * If *cpp is NULL maxsize bytes are allocated
424*10465441SEvalZero  */
xdr_bytes(XDR * xdrs,char ** cpp,unsigned int * sizep,unsigned int maxsize)425*10465441SEvalZero bool_t xdr_bytes(XDR *xdrs, char** cpp, unsigned int *sizep, unsigned int maxsize)
426*10465441SEvalZero {
427*10465441SEvalZero 	register char *sp = *cpp;	/* sp is the actual string pointer */
428*10465441SEvalZero 	register unsigned int nodesize;
429*10465441SEvalZero 
430*10465441SEvalZero 	/*
431*10465441SEvalZero 	 * first deal with the length since xdr bytes are counted
432*10465441SEvalZero 	 */
433*10465441SEvalZero 	if (!xdr_u_int(xdrs, sizep)) {
434*10465441SEvalZero 		return (FALSE);
435*10465441SEvalZero 	}
436*10465441SEvalZero 	nodesize = *sizep;
437*10465441SEvalZero 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
438*10465441SEvalZero 		return (FALSE);
439*10465441SEvalZero 	}
440*10465441SEvalZero 
441*10465441SEvalZero 	/*
442*10465441SEvalZero 	 * now deal with the actual bytes
443*10465441SEvalZero 	 */
444*10465441SEvalZero 	switch (xdrs->x_op) {
445*10465441SEvalZero 
446*10465441SEvalZero 	case XDR_DECODE:
447*10465441SEvalZero 		if (nodesize == 0) {
448*10465441SEvalZero 			return (TRUE);
449*10465441SEvalZero 		}
450*10465441SEvalZero 		if (sp == NULL) {
451*10465441SEvalZero 			*cpp = sp = (char *) rt_malloc(nodesize);
452*10465441SEvalZero 		}
453*10465441SEvalZero 		if (sp == NULL) {
454*10465441SEvalZero 			rt_kprintf("xdr_bytes: out of memory\n");
455*10465441SEvalZero 			return (FALSE);
456*10465441SEvalZero 		}
457*10465441SEvalZero 		/* fall into ... */
458*10465441SEvalZero 
459*10465441SEvalZero 	case XDR_ENCODE:
460*10465441SEvalZero 		return (xdr_opaque(xdrs, sp, nodesize));
461*10465441SEvalZero 
462*10465441SEvalZero 	case XDR_FREE:
463*10465441SEvalZero 		if (sp != NULL) {
464*10465441SEvalZero 			rt_free(sp);
465*10465441SEvalZero 			*cpp = NULL;
466*10465441SEvalZero 		}
467*10465441SEvalZero 		return (TRUE);
468*10465441SEvalZero 	}
469*10465441SEvalZero 	return (FALSE);
470*10465441SEvalZero }
471*10465441SEvalZero 
472*10465441SEvalZero /*
473*10465441SEvalZero  * Implemented here due to commonality of the object.
474*10465441SEvalZero  */
xdr_netobj(XDR * xdrs,struct netobj * np)475*10465441SEvalZero bool_t xdr_netobj(XDR *xdrs, struct netobj *np)
476*10465441SEvalZero {
477*10465441SEvalZero 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
478*10465441SEvalZero }
479*10465441SEvalZero 
480*10465441SEvalZero /*
481*10465441SEvalZero  * XDR a descriminated union
482*10465441SEvalZero  * Support routine for discriminated unions.
483*10465441SEvalZero  * You create an array of xdrdiscrim structures, terminated with
484*10465441SEvalZero  * an entry with a null procedure pointer.  The routine gets
485*10465441SEvalZero  * the discriminant value and then searches the array of xdrdiscrims
486*10465441SEvalZero  * looking for that value.  It calls the procedure given in the xdrdiscrim
487*10465441SEvalZero  * to handle the discriminant.  If there is no specific routine a default
488*10465441SEvalZero  * routine may be called.
489*10465441SEvalZero  * If there is no specific or default routine an error is returned.
490*10465441SEvalZero  */
xdr_union(XDR * xdrs,enum_t * dscmp,char * unp,const struct xdr_discrim * choices,xdrproc_t dfault)491*10465441SEvalZero bool_t xdr_union(XDR* xdrs, enum_t* dscmp, char* unp, const struct xdr_discrim* choices, xdrproc_t dfault)
492*10465441SEvalZero {
493*10465441SEvalZero 	register enum_t dscm;
494*10465441SEvalZero 
495*10465441SEvalZero 	/*
496*10465441SEvalZero 	 * we deal with the discriminator;  it's an enum
497*10465441SEvalZero 	 */
498*10465441SEvalZero 	if (!xdr_enum(xdrs, dscmp)) {
499*10465441SEvalZero 		return (FALSE);
500*10465441SEvalZero 	}
501*10465441SEvalZero 	dscm = *dscmp;
502*10465441SEvalZero 
503*10465441SEvalZero 	/*
504*10465441SEvalZero 	 * search choices for a value that matches the discriminator.
505*10465441SEvalZero 	 * if we find one, execute the xdr routine for that value.
506*10465441SEvalZero 	 */
507*10465441SEvalZero 	for (; choices->proc != NULL_xdrproc_t; choices++) {
508*10465441SEvalZero 		if (choices->value == dscm)
509*10465441SEvalZero 			return ((*(choices->proc)) (xdrs, unp, LASTUNSIGNED));
510*10465441SEvalZero 	}
511*10465441SEvalZero 
512*10465441SEvalZero 	/*
513*10465441SEvalZero 	 * no match - execute the default xdr routine if there is one
514*10465441SEvalZero 	 */
515*10465441SEvalZero 	return ((dfault == NULL_xdrproc_t) ? FALSE :
516*10465441SEvalZero 			(*dfault) (xdrs, unp, LASTUNSIGNED));
517*10465441SEvalZero }
518*10465441SEvalZero 
519*10465441SEvalZero 
520*10465441SEvalZero /*
521*10465441SEvalZero  * Non-portable xdr primitives.
522*10465441SEvalZero  * Care should be taken when moving these routines to new architectures.
523*10465441SEvalZero  */
524*10465441SEvalZero 
525*10465441SEvalZero 
526*10465441SEvalZero /*
527*10465441SEvalZero  * XDR null terminated ASCII strings
528*10465441SEvalZero  * xdr_string deals with "C strings" - arrays of bytes that are
529*10465441SEvalZero  * terminated by a NULL character.  The parameter cpp references a
530*10465441SEvalZero  * pointer to storage; If the pointer is null, then the necessary
531*10465441SEvalZero  * storage is allocated.  The last parameter is the max allowed length
532*10465441SEvalZero  * of the string as specified by a protocol.
533*10465441SEvalZero  */
xdr_string(XDR * xdrs,char ** cpp,unsigned int maxsize)534*10465441SEvalZero bool_t xdr_string(XDR *xdrs, char **cpp, unsigned int maxsize)
535*10465441SEvalZero {
536*10465441SEvalZero 	register char *sp = *cpp;	/* sp is the actual string pointer */
537*10465441SEvalZero 	unsigned int size;
538*10465441SEvalZero 	unsigned int nodesize;
539*10465441SEvalZero 
540*10465441SEvalZero 	/*
541*10465441SEvalZero 	 * first deal with the length since xdr strings are counted-strings
542*10465441SEvalZero 	 */
543*10465441SEvalZero 	switch (xdrs->x_op) {
544*10465441SEvalZero 	case XDR_FREE:
545*10465441SEvalZero 		if (sp == NULL) {
546*10465441SEvalZero 			return (TRUE);		/* already free */
547*10465441SEvalZero 		}
548*10465441SEvalZero 		/* fall through... */
549*10465441SEvalZero 	case XDR_ENCODE:
550*10465441SEvalZero 		size = strlen(sp);
551*10465441SEvalZero 		break;
552*10465441SEvalZero 	}
553*10465441SEvalZero 	if (!xdr_u_int(xdrs, &size)) {
554*10465441SEvalZero 		return (FALSE);
555*10465441SEvalZero 	}
556*10465441SEvalZero 	if (size > maxsize) {
557*10465441SEvalZero 		return (FALSE);
558*10465441SEvalZero 	}
559*10465441SEvalZero 	nodesize = size + 1;
560*10465441SEvalZero 
561*10465441SEvalZero 	/*
562*10465441SEvalZero 	 * now deal with the actual bytes
563*10465441SEvalZero 	 */
564*10465441SEvalZero 	switch (xdrs->x_op) {
565*10465441SEvalZero 
566*10465441SEvalZero 	case XDR_DECODE:
567*10465441SEvalZero 		if (nodesize == 0) {
568*10465441SEvalZero 			return (TRUE);
569*10465441SEvalZero 		}
570*10465441SEvalZero 		if (sp == NULL)
571*10465441SEvalZero 			*cpp = sp = (char *) rt_malloc(nodesize);
572*10465441SEvalZero 		if (sp == NULL) {
573*10465441SEvalZero 			rt_kprintf("xdr_string: out of memory\n");
574*10465441SEvalZero 			return (FALSE);
575*10465441SEvalZero 		}
576*10465441SEvalZero 		sp[size] = 0;
577*10465441SEvalZero 		/* fall into ... */
578*10465441SEvalZero 
579*10465441SEvalZero 	case XDR_ENCODE:
580*10465441SEvalZero 		return (xdr_opaque(xdrs, sp, size));
581*10465441SEvalZero 
582*10465441SEvalZero 	case XDR_FREE:
583*10465441SEvalZero 		rt_free(sp);
584*10465441SEvalZero 		*cpp = NULL;
585*10465441SEvalZero 		return (TRUE);
586*10465441SEvalZero 	}
587*10465441SEvalZero 	return (FALSE);
588*10465441SEvalZero }
589*10465441SEvalZero 
590*10465441SEvalZero /*
591*10465441SEvalZero  * Wrapper for xdr_string that can be called directly from
592*10465441SEvalZero  * routines like clnt_call
593*10465441SEvalZero  */
xdr_wrapstring(XDR * xdrs,char ** cpp)594*10465441SEvalZero bool_t xdr_wrapstring(XDR *xdrs, char **cpp)
595*10465441SEvalZero {
596*10465441SEvalZero 	if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
597*10465441SEvalZero 		return (TRUE);
598*10465441SEvalZero 	}
599*10465441SEvalZero 	return (FALSE);
600*10465441SEvalZero }
601*10465441SEvalZero 
602*10465441SEvalZero /*
603*10465441SEvalZero  * XDR an array of arbitrary elements
604*10465441SEvalZero  * *addrp is a pointer to the array, *sizep is the number of elements.
605*10465441SEvalZero  * If addrp is NULL (*sizep * elsize) bytes are allocated.
606*10465441SEvalZero  * elsize is the size (in bytes) of each element, and elproc is the
607*10465441SEvalZero  * xdr procedure to call to handle each element of the array.
608*10465441SEvalZero  */
xdr_array(XDR * xdrs,char ** addrp,unsigned int * sizep,unsigned int maxsize,unsigned int elsize,xdrproc_t elproc)609*10465441SEvalZero bool_t xdr_array(XDR *xdrs, char **addrp, unsigned int *sizep, unsigned int maxsize, unsigned int elsize, xdrproc_t elproc)
610*10465441SEvalZero {
611*10465441SEvalZero 	register unsigned int i;
612*10465441SEvalZero 	register char* target = *addrp;
613*10465441SEvalZero 	register unsigned int c;			/* the actual element count */
614*10465441SEvalZero 	register bool_t stat = TRUE;
615*10465441SEvalZero 	register unsigned int nodesize;
616*10465441SEvalZero 
617*10465441SEvalZero 	/* like strings, arrays are really counted arrays */
618*10465441SEvalZero 	if (!xdr_u_int(xdrs, sizep)) {
619*10465441SEvalZero 		return (FALSE);
620*10465441SEvalZero 	}
621*10465441SEvalZero 	c = *sizep;
622*10465441SEvalZero 	if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
623*10465441SEvalZero 		return (FALSE);
624*10465441SEvalZero 	}
625*10465441SEvalZero 	/* duh, look for integer overflow (fefe) */
626*10465441SEvalZero 	{
627*10465441SEvalZero 	  unsigned int i;
628*10465441SEvalZero 	  nodesize = 0;
629*10465441SEvalZero 	  for (i=c; i; --i) {
630*10465441SEvalZero 	    unsigned int tmp=nodesize+elsize;
631*10465441SEvalZero 	    if (tmp<nodesize)	/* overflow */
632*10465441SEvalZero 	      return FALSE;
633*10465441SEvalZero 	    nodesize=tmp;
634*10465441SEvalZero 	  }
635*10465441SEvalZero 	}
636*10465441SEvalZero 
637*10465441SEvalZero 	/*
638*10465441SEvalZero 	 * if we are deserializing, we may need to allocate an array.
639*10465441SEvalZero 	 * We also save time by checking for a null array if we are freeing.
640*10465441SEvalZero 	 */
641*10465441SEvalZero 	if (target == NULL)
642*10465441SEvalZero 		switch (xdrs->x_op) {
643*10465441SEvalZero 		case XDR_DECODE:
644*10465441SEvalZero 			if (c == 0)
645*10465441SEvalZero 				return (TRUE);
646*10465441SEvalZero 			*addrp = target = rt_malloc(nodesize);
647*10465441SEvalZero 			if (target == NULL) {
648*10465441SEvalZero 				rt_kprintf("xdr_array: out of memory\n");
649*10465441SEvalZero 				return (FALSE);
650*10465441SEvalZero 			}
651*10465441SEvalZero 			memset(target, 0, nodesize);
652*10465441SEvalZero 			break;
653*10465441SEvalZero 
654*10465441SEvalZero 		case XDR_FREE:
655*10465441SEvalZero 			return (TRUE);
656*10465441SEvalZero 		}
657*10465441SEvalZero 
658*10465441SEvalZero 	/*
659*10465441SEvalZero 	 * now we xdr each element of array
660*10465441SEvalZero 	 */
661*10465441SEvalZero 	for (i = 0; (i < c) && stat; i++) {
662*10465441SEvalZero 		stat = (*elproc) (xdrs, target, LASTUNSIGNED);
663*10465441SEvalZero 		target += elsize;
664*10465441SEvalZero 	}
665*10465441SEvalZero 
666*10465441SEvalZero 	/*
667*10465441SEvalZero 	 * the array may need freeing
668*10465441SEvalZero 	 */
669*10465441SEvalZero 	if (xdrs->x_op == XDR_FREE) {
670*10465441SEvalZero 		rt_free(*addrp);
671*10465441SEvalZero 		*addrp = NULL;
672*10465441SEvalZero 	}
673*10465441SEvalZero 	return (stat);
674*10465441SEvalZero }
675*10465441SEvalZero 
676*10465441SEvalZero /*
677*10465441SEvalZero  * xdr_vector():
678*10465441SEvalZero  *
679*10465441SEvalZero  * XDR a fixed length array. Unlike variable-length arrays,
680*10465441SEvalZero  * the storage of fixed length arrays is static and unfreeable.
681*10465441SEvalZero  * > basep: base of the array
682*10465441SEvalZero  * > size: size of the array
683*10465441SEvalZero  * > elemsize: size of each element
684*10465441SEvalZero  * > xdr_elem: routine to XDR each element
685*10465441SEvalZero  */
xdr_vector(XDR * xdrs,char * basep,unsigned int nelem,unsigned int elemsize,xdrproc_t xdr_elem)686*10465441SEvalZero bool_t xdr_vector(XDR *xdrs, char *basep, unsigned int nelem, unsigned int elemsize, xdrproc_t xdr_elem)
687*10465441SEvalZero {
688*10465441SEvalZero 	register unsigned int i;
689*10465441SEvalZero 	register char *elptr;
690*10465441SEvalZero 
691*10465441SEvalZero 	elptr = basep;
692*10465441SEvalZero 	for (i = 0; i < nelem; i++) {
693*10465441SEvalZero 		if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED)) {
694*10465441SEvalZero 			return (FALSE);
695*10465441SEvalZero 		}
696*10465441SEvalZero 		elptr += elemsize;
697*10465441SEvalZero 	}
698*10465441SEvalZero 	return (TRUE);
699*10465441SEvalZero }
700*10465441SEvalZero 
701*10465441SEvalZero 
702*10465441SEvalZero /*
703*10465441SEvalZero  * XDR an indirect pointer
704*10465441SEvalZero  * xdr_reference is for recursively translating a structure that is
705*10465441SEvalZero  * referenced by a pointer inside the structure that is currently being
706*10465441SEvalZero  * translated.  pp references a pointer to storage. If *pp is null
707*10465441SEvalZero  * the  necessary storage is allocated.
708*10465441SEvalZero  * size is the sizeof the referneced structure.
709*10465441SEvalZero  * proc is the routine to handle the referenced structure.
710*10465441SEvalZero  */
xdr_reference(XDR * xdrs,char ** pp,unsigned int size,xdrproc_t proc)711*10465441SEvalZero bool_t xdr_reference(XDR *xdrs, char **pp, unsigned int size, xdrproc_t proc)
712*10465441SEvalZero {
713*10465441SEvalZero 	register char* loc = *pp;
714*10465441SEvalZero 	register bool_t stat;
715*10465441SEvalZero 
716*10465441SEvalZero 	if (loc == NULL)
717*10465441SEvalZero 		switch (xdrs->x_op) {
718*10465441SEvalZero 		case XDR_FREE:
719*10465441SEvalZero 			return (TRUE);
720*10465441SEvalZero 
721*10465441SEvalZero 		case XDR_DECODE:
722*10465441SEvalZero 			*pp = loc = (char*) rt_malloc(size);
723*10465441SEvalZero 			if (loc == NULL) {
724*10465441SEvalZero 				rt_kprintf("xdr_reference: out of memory\n");
725*10465441SEvalZero 				return (FALSE);
726*10465441SEvalZero 			}
727*10465441SEvalZero 			memset(loc, 0, (int) size);
728*10465441SEvalZero 			break;
729*10465441SEvalZero 		}
730*10465441SEvalZero 
731*10465441SEvalZero 	stat = (*proc) (xdrs, loc, LASTUNSIGNED);
732*10465441SEvalZero 
733*10465441SEvalZero 	if (xdrs->x_op == XDR_FREE) {
734*10465441SEvalZero 		rt_free(loc);
735*10465441SEvalZero 		*pp = NULL;
736*10465441SEvalZero 	}
737*10465441SEvalZero 	return (stat);
738*10465441SEvalZero }
739*10465441SEvalZero 
740*10465441SEvalZero 
741*10465441SEvalZero /*
742*10465441SEvalZero  * xdr_pointer():
743*10465441SEvalZero  *
744*10465441SEvalZero  * XDR a pointer to a possibly recursive data structure. This
745*10465441SEvalZero  * differs with xdr_reference in that it can serialize/deserialiaze
746*10465441SEvalZero  * trees correctly.
747*10465441SEvalZero  *
748*10465441SEvalZero  *  What's sent is actually a union:
749*10465441SEvalZero  *
750*10465441SEvalZero  *  union object_pointer switch (boolean b) {
751*10465441SEvalZero  *  case TRUE: object_data data;
752*10465441SEvalZero  *  case FALSE: void nothing;
753*10465441SEvalZero  *  }
754*10465441SEvalZero  *
755*10465441SEvalZero  * > objpp: Pointer to the pointer to the object.
756*10465441SEvalZero  * > obj_size: size of the object.
757*10465441SEvalZero  * > xdr_obj: routine to XDR an object.
758*10465441SEvalZero  *
759*10465441SEvalZero  */
xdr_pointer(XDR * xdrs,char ** objpp,unsigned int obj_size,xdrproc_t xdr_obj)760*10465441SEvalZero bool_t xdr_pointer(XDR *xdrs, char **objpp, unsigned int obj_size, xdrproc_t xdr_obj)
761*10465441SEvalZero {
762*10465441SEvalZero 
763*10465441SEvalZero 	bool_t more_data;
764*10465441SEvalZero 
765*10465441SEvalZero 	more_data = (*objpp != NULL);
766*10465441SEvalZero 	if (!xdr_bool(xdrs, &more_data)) {
767*10465441SEvalZero 		return (FALSE);
768*10465441SEvalZero 	}
769*10465441SEvalZero 	if (!more_data) {
770*10465441SEvalZero 		*objpp = NULL;
771*10465441SEvalZero 		return (TRUE);
772*10465441SEvalZero 	}
773*10465441SEvalZero 	return (xdr_reference(xdrs, objpp, obj_size, xdr_obj));
774*10465441SEvalZero }
775