xref: /freebsd/lib/libc/xdr/xdr.c (revision eae561b30ec984ce171d99b1fd182575acc2c639)
1eae561b3SGarrett Wollman /*
2eae561b3SGarrett Wollman  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3eae561b3SGarrett Wollman  * unrestricted use provided that this legend is included on all tape
4eae561b3SGarrett Wollman  * media and as a part of the software program in whole or part.  Users
5eae561b3SGarrett Wollman  * may copy or modify Sun RPC without charge, but are not authorized
6eae561b3SGarrett Wollman  * to license or distribute it to anyone else except as part of a product or
7eae561b3SGarrett Wollman  * program developed by the user.
8eae561b3SGarrett Wollman  *
9eae561b3SGarrett Wollman  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10eae561b3SGarrett Wollman  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11eae561b3SGarrett Wollman  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12eae561b3SGarrett Wollman  *
13eae561b3SGarrett Wollman  * Sun RPC is provided with no support and without any obligation on the
14eae561b3SGarrett Wollman  * part of Sun Microsystems, Inc. to assist in its use, correction,
15eae561b3SGarrett Wollman  * modification or enhancement.
16eae561b3SGarrett Wollman  *
17eae561b3SGarrett Wollman  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18eae561b3SGarrett Wollman  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19eae561b3SGarrett Wollman  * OR ANY PART THEREOF.
20eae561b3SGarrett Wollman  *
21eae561b3SGarrett Wollman  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22eae561b3SGarrett Wollman  * or profits or other special, indirect and consequential damages, even if
23eae561b3SGarrett Wollman  * Sun has been advised of the possibility of such damages.
24eae561b3SGarrett Wollman  *
25eae561b3SGarrett Wollman  * Sun Microsystems, Inc.
26eae561b3SGarrett Wollman  * 2550 Garcia Avenue
27eae561b3SGarrett Wollman  * Mountain View, California  94043
28eae561b3SGarrett Wollman  */
29eae561b3SGarrett Wollman 
30eae561b3SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint)
31eae561b3SGarrett Wollman /*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/
32eae561b3SGarrett Wollman /*static char *sccsid = "from: @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";*/
33eae561b3SGarrett Wollman static char *rcsid = "$Id: xdr.c,v 1.1 1993/10/27 05:41:06 paul Exp $";
34eae561b3SGarrett Wollman #endif
35eae561b3SGarrett Wollman 
36eae561b3SGarrett Wollman /*
37eae561b3SGarrett Wollman  * xdr.c, Generic XDR routines implementation.
38eae561b3SGarrett Wollman  *
39eae561b3SGarrett Wollman  * Copyright (C) 1986, Sun Microsystems, Inc.
40eae561b3SGarrett Wollman  *
41eae561b3SGarrett Wollman  * These are the "generic" xdr routines used to serialize and de-serialize
42eae561b3SGarrett Wollman  * most common data items.  See xdr.h for more info on the interface to
43eae561b3SGarrett Wollman  * xdr.
44eae561b3SGarrett Wollman  */
45eae561b3SGarrett Wollman 
46eae561b3SGarrett Wollman #include <stdio.h>
47eae561b3SGarrett Wollman 
48eae561b3SGarrett Wollman #include <rpc/types.h>
49eae561b3SGarrett Wollman #include <rpc/xdr.h>
50eae561b3SGarrett Wollman 
51eae561b3SGarrett Wollman /*
52eae561b3SGarrett Wollman  * constants specific to the xdr "protocol"
53eae561b3SGarrett Wollman  */
54eae561b3SGarrett Wollman #define XDR_FALSE	((long) 0)
55eae561b3SGarrett Wollman #define XDR_TRUE	((long) 1)
56eae561b3SGarrett Wollman #define LASTUNSIGNED	((u_int) 0-1)
57eae561b3SGarrett Wollman 
58eae561b3SGarrett Wollman /*
59eae561b3SGarrett Wollman  * for unit alignment
60eae561b3SGarrett Wollman  */
61eae561b3SGarrett Wollman static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
62eae561b3SGarrett Wollman 
63eae561b3SGarrett Wollman /*
64eae561b3SGarrett Wollman  * Free a data structure using XDR
65eae561b3SGarrett Wollman  * Not a filter, but a convenient utility nonetheless
66eae561b3SGarrett Wollman  */
67eae561b3SGarrett Wollman void
68eae561b3SGarrett Wollman xdr_free(proc, objp)
69eae561b3SGarrett Wollman 	xdrproc_t proc;
70eae561b3SGarrett Wollman 	char *objp;
71eae561b3SGarrett Wollman {
72eae561b3SGarrett Wollman 	XDR x;
73eae561b3SGarrett Wollman 
74eae561b3SGarrett Wollman 	x.x_op = XDR_FREE;
75eae561b3SGarrett Wollman 	(*proc)(&x, objp);
76eae561b3SGarrett Wollman }
77eae561b3SGarrett Wollman 
78eae561b3SGarrett Wollman /*
79eae561b3SGarrett Wollman  * XDR nothing
80eae561b3SGarrett Wollman  */
81eae561b3SGarrett Wollman bool_t
82eae561b3SGarrett Wollman xdr_void(/* xdrs, addr */)
83eae561b3SGarrett Wollman 	/* XDR *xdrs; */
84eae561b3SGarrett Wollman 	/* caddr_t addr; */
85eae561b3SGarrett Wollman {
86eae561b3SGarrett Wollman 
87eae561b3SGarrett Wollman 	return (TRUE);
88eae561b3SGarrett Wollman }
89eae561b3SGarrett Wollman 
90eae561b3SGarrett Wollman /*
91eae561b3SGarrett Wollman  * XDR integers
92eae561b3SGarrett Wollman  */
93eae561b3SGarrett Wollman bool_t
94eae561b3SGarrett Wollman xdr_int(xdrs, ip)
95eae561b3SGarrett Wollman 	XDR *xdrs;
96eae561b3SGarrett Wollman 	int *ip;
97eae561b3SGarrett Wollman {
98eae561b3SGarrett Wollman 
99eae561b3SGarrett Wollman #ifdef lint
100eae561b3SGarrett Wollman 	(void) (xdr_short(xdrs, (short *)ip));
101eae561b3SGarrett Wollman 	return (xdr_long(xdrs, (long *)ip));
102eae561b3SGarrett Wollman #else
103eae561b3SGarrett Wollman 	if (sizeof (int) == sizeof (long)) {
104eae561b3SGarrett Wollman 		return (xdr_long(xdrs, (long *)ip));
105eae561b3SGarrett Wollman 	} else {
106eae561b3SGarrett Wollman 		return (xdr_short(xdrs, (short *)ip));
107eae561b3SGarrett Wollman 	}
108eae561b3SGarrett Wollman #endif
109eae561b3SGarrett Wollman }
110eae561b3SGarrett Wollman 
111eae561b3SGarrett Wollman /*
112eae561b3SGarrett Wollman  * XDR unsigned integers
113eae561b3SGarrett Wollman  */
114eae561b3SGarrett Wollman bool_t
115eae561b3SGarrett Wollman xdr_u_int(xdrs, up)
116eae561b3SGarrett Wollman 	XDR *xdrs;
117eae561b3SGarrett Wollman 	u_int *up;
118eae561b3SGarrett Wollman {
119eae561b3SGarrett Wollman 
120eae561b3SGarrett Wollman #ifdef lint
121eae561b3SGarrett Wollman 	(void) (xdr_short(xdrs, (short *)up));
122eae561b3SGarrett Wollman 	return (xdr_u_long(xdrs, (u_long *)up));
123eae561b3SGarrett Wollman #else
124eae561b3SGarrett Wollman 	if (sizeof (u_int) == sizeof (u_long)) {
125eae561b3SGarrett Wollman 		return (xdr_u_long(xdrs, (u_long *)up));
126eae561b3SGarrett Wollman 	} else {
127eae561b3SGarrett Wollman 		return (xdr_short(xdrs, (short *)up));
128eae561b3SGarrett Wollman 	}
129eae561b3SGarrett Wollman #endif
130eae561b3SGarrett Wollman }
131eae561b3SGarrett Wollman 
132eae561b3SGarrett Wollman /*
133eae561b3SGarrett Wollman  * XDR long integers
134eae561b3SGarrett Wollman  * same as xdr_u_long - open coded to save a proc call!
135eae561b3SGarrett Wollman  */
136eae561b3SGarrett Wollman bool_t
137eae561b3SGarrett Wollman xdr_long(xdrs, lp)
138eae561b3SGarrett Wollman 	register XDR *xdrs;
139eae561b3SGarrett Wollman 	long *lp;
140eae561b3SGarrett Wollman {
141eae561b3SGarrett Wollman 
142eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_ENCODE)
143eae561b3SGarrett Wollman 		return (XDR_PUTLONG(xdrs, lp));
144eae561b3SGarrett Wollman 
145eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_DECODE)
146eae561b3SGarrett Wollman 		return (XDR_GETLONG(xdrs, lp));
147eae561b3SGarrett Wollman 
148eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_FREE)
149eae561b3SGarrett Wollman 		return (TRUE);
150eae561b3SGarrett Wollman 
151eae561b3SGarrett Wollman 	return (FALSE);
152eae561b3SGarrett Wollman }
153eae561b3SGarrett Wollman 
154eae561b3SGarrett Wollman /*
155eae561b3SGarrett Wollman  * XDR unsigned long integers
156eae561b3SGarrett Wollman  * same as xdr_long - open coded to save a proc call!
157eae561b3SGarrett Wollman  */
158eae561b3SGarrett Wollman bool_t
159eae561b3SGarrett Wollman xdr_u_long(xdrs, ulp)
160eae561b3SGarrett Wollman 	register XDR *xdrs;
161eae561b3SGarrett Wollman 	u_long *ulp;
162eae561b3SGarrett Wollman {
163eae561b3SGarrett Wollman 
164eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_DECODE)
165eae561b3SGarrett Wollman 		return (XDR_GETLONG(xdrs, (long *)ulp));
166eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_ENCODE)
167eae561b3SGarrett Wollman 		return (XDR_PUTLONG(xdrs, (long *)ulp));
168eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_FREE)
169eae561b3SGarrett Wollman 		return (TRUE);
170eae561b3SGarrett Wollman 	return (FALSE);
171eae561b3SGarrett Wollman }
172eae561b3SGarrett Wollman 
173eae561b3SGarrett Wollman /*
174eae561b3SGarrett Wollman  * XDR short integers
175eae561b3SGarrett Wollman  */
176eae561b3SGarrett Wollman bool_t
177eae561b3SGarrett Wollman xdr_short(xdrs, sp)
178eae561b3SGarrett Wollman 	register XDR *xdrs;
179eae561b3SGarrett Wollman 	short *sp;
180eae561b3SGarrett Wollman {
181eae561b3SGarrett Wollman 	long l;
182eae561b3SGarrett Wollman 
183eae561b3SGarrett Wollman 	switch (xdrs->x_op) {
184eae561b3SGarrett Wollman 
185eae561b3SGarrett Wollman 	case XDR_ENCODE:
186eae561b3SGarrett Wollman 		l = (long) *sp;
187eae561b3SGarrett Wollman 		return (XDR_PUTLONG(xdrs, &l));
188eae561b3SGarrett Wollman 
189eae561b3SGarrett Wollman 	case XDR_DECODE:
190eae561b3SGarrett Wollman 		if (!XDR_GETLONG(xdrs, &l)) {
191eae561b3SGarrett Wollman 			return (FALSE);
192eae561b3SGarrett Wollman 		}
193eae561b3SGarrett Wollman 		*sp = (short) l;
194eae561b3SGarrett Wollman 		return (TRUE);
195eae561b3SGarrett Wollman 
196eae561b3SGarrett Wollman 	case XDR_FREE:
197eae561b3SGarrett Wollman 		return (TRUE);
198eae561b3SGarrett Wollman 	}
199eae561b3SGarrett Wollman 	return (FALSE);
200eae561b3SGarrett Wollman }
201eae561b3SGarrett Wollman 
202eae561b3SGarrett Wollman /*
203eae561b3SGarrett Wollman  * XDR unsigned short integers
204eae561b3SGarrett Wollman  */
205eae561b3SGarrett Wollman bool_t
206eae561b3SGarrett Wollman xdr_u_short(xdrs, usp)
207eae561b3SGarrett Wollman 	register XDR *xdrs;
208eae561b3SGarrett Wollman 	u_short *usp;
209eae561b3SGarrett Wollman {
210eae561b3SGarrett Wollman 	u_long l;
211eae561b3SGarrett Wollman 
212eae561b3SGarrett Wollman 	switch (xdrs->x_op) {
213eae561b3SGarrett Wollman 
214eae561b3SGarrett Wollman 	case XDR_ENCODE:
215eae561b3SGarrett Wollman 		l = (u_long) *usp;
216eae561b3SGarrett Wollman 		return (XDR_PUTLONG(xdrs, &l));
217eae561b3SGarrett Wollman 
218eae561b3SGarrett Wollman 	case XDR_DECODE:
219eae561b3SGarrett Wollman 		if (!XDR_GETLONG(xdrs, &l)) {
220eae561b3SGarrett Wollman 			return (FALSE);
221eae561b3SGarrett Wollman 		}
222eae561b3SGarrett Wollman 		*usp = (u_short) l;
223eae561b3SGarrett Wollman 		return (TRUE);
224eae561b3SGarrett Wollman 
225eae561b3SGarrett Wollman 	case XDR_FREE:
226eae561b3SGarrett Wollman 		return (TRUE);
227eae561b3SGarrett Wollman 	}
228eae561b3SGarrett Wollman 	return (FALSE);
229eae561b3SGarrett Wollman }
230eae561b3SGarrett Wollman 
231eae561b3SGarrett Wollman 
232eae561b3SGarrett Wollman /*
233eae561b3SGarrett Wollman  * XDR a char
234eae561b3SGarrett Wollman  */
235eae561b3SGarrett Wollman bool_t
236eae561b3SGarrett Wollman xdr_char(xdrs, cp)
237eae561b3SGarrett Wollman 	XDR *xdrs;
238eae561b3SGarrett Wollman 	char *cp;
239eae561b3SGarrett Wollman {
240eae561b3SGarrett Wollman 	int i;
241eae561b3SGarrett Wollman 
242eae561b3SGarrett Wollman 	i = (*cp);
243eae561b3SGarrett Wollman 	if (!xdr_int(xdrs, &i)) {
244eae561b3SGarrett Wollman 		return (FALSE);
245eae561b3SGarrett Wollman 	}
246eae561b3SGarrett Wollman 	*cp = i;
247eae561b3SGarrett Wollman 	return (TRUE);
248eae561b3SGarrett Wollman }
249eae561b3SGarrett Wollman 
250eae561b3SGarrett Wollman /*
251eae561b3SGarrett Wollman  * XDR an unsigned char
252eae561b3SGarrett Wollman  */
253eae561b3SGarrett Wollman bool_t
254eae561b3SGarrett Wollman xdr_u_char(xdrs, cp)
255eae561b3SGarrett Wollman 	XDR *xdrs;
256eae561b3SGarrett Wollman 	char *cp;
257eae561b3SGarrett Wollman {
258eae561b3SGarrett Wollman 	u_int u;
259eae561b3SGarrett Wollman 
260eae561b3SGarrett Wollman 	u = (*cp);
261eae561b3SGarrett Wollman 	if (!xdr_u_int(xdrs, &u)) {
262eae561b3SGarrett Wollman 		return (FALSE);
263eae561b3SGarrett Wollman 	}
264eae561b3SGarrett Wollman 	*cp = u;
265eae561b3SGarrett Wollman 	return (TRUE);
266eae561b3SGarrett Wollman }
267eae561b3SGarrett Wollman 
268eae561b3SGarrett Wollman /*
269eae561b3SGarrett Wollman  * XDR booleans
270eae561b3SGarrett Wollman  */
271eae561b3SGarrett Wollman bool_t
272eae561b3SGarrett Wollman xdr_bool(xdrs, bp)
273eae561b3SGarrett Wollman 	register XDR *xdrs;
274eae561b3SGarrett Wollman 	bool_t *bp;
275eae561b3SGarrett Wollman {
276eae561b3SGarrett Wollman 	long lb;
277eae561b3SGarrett Wollman 
278eae561b3SGarrett Wollman 	switch (xdrs->x_op) {
279eae561b3SGarrett Wollman 
280eae561b3SGarrett Wollman 	case XDR_ENCODE:
281eae561b3SGarrett Wollman 		lb = *bp ? XDR_TRUE : XDR_FALSE;
282eae561b3SGarrett Wollman 		return (XDR_PUTLONG(xdrs, &lb));
283eae561b3SGarrett Wollman 
284eae561b3SGarrett Wollman 	case XDR_DECODE:
285eae561b3SGarrett Wollman 		if (!XDR_GETLONG(xdrs, &lb)) {
286eae561b3SGarrett Wollman 			return (FALSE);
287eae561b3SGarrett Wollman 		}
288eae561b3SGarrett Wollman 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
289eae561b3SGarrett Wollman 		return (TRUE);
290eae561b3SGarrett Wollman 
291eae561b3SGarrett Wollman 	case XDR_FREE:
292eae561b3SGarrett Wollman 		return (TRUE);
293eae561b3SGarrett Wollman 	}
294eae561b3SGarrett Wollman 	return (FALSE);
295eae561b3SGarrett Wollman }
296eae561b3SGarrett Wollman 
297eae561b3SGarrett Wollman /*
298eae561b3SGarrett Wollman  * XDR enumerations
299eae561b3SGarrett Wollman  */
300eae561b3SGarrett Wollman bool_t
301eae561b3SGarrett Wollman xdr_enum(xdrs, ep)
302eae561b3SGarrett Wollman 	XDR *xdrs;
303eae561b3SGarrett Wollman 	enum_t *ep;
304eae561b3SGarrett Wollman {
305eae561b3SGarrett Wollman #ifndef lint
306eae561b3SGarrett Wollman 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
307eae561b3SGarrett Wollman 
308eae561b3SGarrett Wollman 	/*
309eae561b3SGarrett Wollman 	 * enums are treated as ints
310eae561b3SGarrett Wollman 	 */
311eae561b3SGarrett Wollman 	if (sizeof (enum sizecheck) == sizeof (long)) {
312eae561b3SGarrett Wollman 		return (xdr_long(xdrs, (long *)ep));
313eae561b3SGarrett Wollman 	} else if (sizeof (enum sizecheck) == sizeof (short)) {
314eae561b3SGarrett Wollman 		return (xdr_short(xdrs, (short *)ep));
315eae561b3SGarrett Wollman 	} else {
316eae561b3SGarrett Wollman 		return (FALSE);
317eae561b3SGarrett Wollman 	}
318eae561b3SGarrett Wollman #else
319eae561b3SGarrett Wollman 	(void) (xdr_short(xdrs, (short *)ep));
320eae561b3SGarrett Wollman 	return (xdr_long(xdrs, (long *)ep));
321eae561b3SGarrett Wollman #endif
322eae561b3SGarrett Wollman }
323eae561b3SGarrett Wollman 
324eae561b3SGarrett Wollman /*
325eae561b3SGarrett Wollman  * XDR opaque data
326eae561b3SGarrett Wollman  * Allows the specification of a fixed size sequence of opaque bytes.
327eae561b3SGarrett Wollman  * cp points to the opaque object and cnt gives the byte length.
328eae561b3SGarrett Wollman  */
329eae561b3SGarrett Wollman bool_t
330eae561b3SGarrett Wollman xdr_opaque(xdrs, cp, cnt)
331eae561b3SGarrett Wollman 	register XDR *xdrs;
332eae561b3SGarrett Wollman 	caddr_t cp;
333eae561b3SGarrett Wollman 	register u_int cnt;
334eae561b3SGarrett Wollman {
335eae561b3SGarrett Wollman 	register u_int rndup;
336eae561b3SGarrett Wollman 	static crud[BYTES_PER_XDR_UNIT];
337eae561b3SGarrett Wollman 
338eae561b3SGarrett Wollman 	/*
339eae561b3SGarrett Wollman 	 * if no data we are done
340eae561b3SGarrett Wollman 	 */
341eae561b3SGarrett Wollman 	if (cnt == 0)
342eae561b3SGarrett Wollman 		return (TRUE);
343eae561b3SGarrett Wollman 
344eae561b3SGarrett Wollman 	/*
345eae561b3SGarrett Wollman 	 * round byte count to full xdr units
346eae561b3SGarrett Wollman 	 */
347eae561b3SGarrett Wollman 	rndup = cnt % BYTES_PER_XDR_UNIT;
348eae561b3SGarrett Wollman 	if (rndup > 0)
349eae561b3SGarrett Wollman 		rndup = BYTES_PER_XDR_UNIT - rndup;
350eae561b3SGarrett Wollman 
351eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_DECODE) {
352eae561b3SGarrett Wollman 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
353eae561b3SGarrett Wollman 			return (FALSE);
354eae561b3SGarrett Wollman 		}
355eae561b3SGarrett Wollman 		if (rndup == 0)
356eae561b3SGarrett Wollman 			return (TRUE);
357eae561b3SGarrett Wollman 		return (XDR_GETBYTES(xdrs, crud, rndup));
358eae561b3SGarrett Wollman 	}
359eae561b3SGarrett Wollman 
360eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_ENCODE) {
361eae561b3SGarrett Wollman 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
362eae561b3SGarrett Wollman 			return (FALSE);
363eae561b3SGarrett Wollman 		}
364eae561b3SGarrett Wollman 		if (rndup == 0)
365eae561b3SGarrett Wollman 			return (TRUE);
366eae561b3SGarrett Wollman 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
367eae561b3SGarrett Wollman 	}
368eae561b3SGarrett Wollman 
369eae561b3SGarrett Wollman 	if (xdrs->x_op == XDR_FREE) {
370eae561b3SGarrett Wollman 		return (TRUE);
371eae561b3SGarrett Wollman 	}
372eae561b3SGarrett Wollman 
373eae561b3SGarrett Wollman 	return (FALSE);
374eae561b3SGarrett Wollman }
375eae561b3SGarrett Wollman 
376eae561b3SGarrett Wollman /*
377eae561b3SGarrett Wollman  * XDR counted bytes
378eae561b3SGarrett Wollman  * *cpp is a pointer to the bytes, *sizep is the count.
379eae561b3SGarrett Wollman  * If *cpp is NULL maxsize bytes are allocated
380eae561b3SGarrett Wollman  */
381eae561b3SGarrett Wollman bool_t
382eae561b3SGarrett Wollman xdr_bytes(xdrs, cpp, sizep, maxsize)
383eae561b3SGarrett Wollman 	register XDR *xdrs;
384eae561b3SGarrett Wollman 	char **cpp;
385eae561b3SGarrett Wollman 	register u_int *sizep;
386eae561b3SGarrett Wollman 	u_int maxsize;
387eae561b3SGarrett Wollman {
388eae561b3SGarrett Wollman 	register char *sp = *cpp;  /* sp is the actual string pointer */
389eae561b3SGarrett Wollman 	register u_int nodesize;
390eae561b3SGarrett Wollman 
391eae561b3SGarrett Wollman 	/*
392eae561b3SGarrett Wollman 	 * first deal with the length since xdr bytes are counted
393eae561b3SGarrett Wollman 	 */
394eae561b3SGarrett Wollman 	if (! xdr_u_int(xdrs, sizep)) {
395eae561b3SGarrett Wollman 		return (FALSE);
396eae561b3SGarrett Wollman 	}
397eae561b3SGarrett Wollman 	nodesize = *sizep;
398eae561b3SGarrett Wollman 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
399eae561b3SGarrett Wollman 		return (FALSE);
400eae561b3SGarrett Wollman 	}
401eae561b3SGarrett Wollman 
402eae561b3SGarrett Wollman 	/*
403eae561b3SGarrett Wollman 	 * now deal with the actual bytes
404eae561b3SGarrett Wollman 	 */
405eae561b3SGarrett Wollman 	switch (xdrs->x_op) {
406eae561b3SGarrett Wollman 
407eae561b3SGarrett Wollman 	case XDR_DECODE:
408eae561b3SGarrett Wollman 		if (nodesize == 0) {
409eae561b3SGarrett Wollman 			return (TRUE);
410eae561b3SGarrett Wollman 		}
411eae561b3SGarrett Wollman 		if (sp == NULL) {
412eae561b3SGarrett Wollman 			*cpp = sp = (char *)mem_alloc(nodesize);
413eae561b3SGarrett Wollman 		}
414eae561b3SGarrett Wollman 		if (sp == NULL) {
415eae561b3SGarrett Wollman 			(void) fprintf(stderr, "xdr_bytes: out of memory\n");
416eae561b3SGarrett Wollman 			return (FALSE);
417eae561b3SGarrett Wollman 		}
418eae561b3SGarrett Wollman 		/* fall into ... */
419eae561b3SGarrett Wollman 
420eae561b3SGarrett Wollman 	case XDR_ENCODE:
421eae561b3SGarrett Wollman 		return (xdr_opaque(xdrs, sp, nodesize));
422eae561b3SGarrett Wollman 
423eae561b3SGarrett Wollman 	case XDR_FREE:
424eae561b3SGarrett Wollman 		if (sp != NULL) {
425eae561b3SGarrett Wollman 			mem_free(sp, nodesize);
426eae561b3SGarrett Wollman 			*cpp = NULL;
427eae561b3SGarrett Wollman 		}
428eae561b3SGarrett Wollman 		return (TRUE);
429eae561b3SGarrett Wollman 	}
430eae561b3SGarrett Wollman 	return (FALSE);
431eae561b3SGarrett Wollman }
432eae561b3SGarrett Wollman 
433eae561b3SGarrett Wollman /*
434eae561b3SGarrett Wollman  * Implemented here due to commonality of the object.
435eae561b3SGarrett Wollman  */
436eae561b3SGarrett Wollman bool_t
437eae561b3SGarrett Wollman xdr_netobj(xdrs, np)
438eae561b3SGarrett Wollman 	XDR *xdrs;
439eae561b3SGarrett Wollman 	struct netobj *np;
440eae561b3SGarrett Wollman {
441eae561b3SGarrett Wollman 
442eae561b3SGarrett Wollman 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
443eae561b3SGarrett Wollman }
444eae561b3SGarrett Wollman 
445eae561b3SGarrett Wollman /*
446eae561b3SGarrett Wollman  * XDR a descriminated union
447eae561b3SGarrett Wollman  * Support routine for discriminated unions.
448eae561b3SGarrett Wollman  * You create an array of xdrdiscrim structures, terminated with
449eae561b3SGarrett Wollman  * an entry with a null procedure pointer.  The routine gets
450eae561b3SGarrett Wollman  * the discriminant value and then searches the array of xdrdiscrims
451eae561b3SGarrett Wollman  * looking for that value.  It calls the procedure given in the xdrdiscrim
452eae561b3SGarrett Wollman  * to handle the discriminant.  If there is no specific routine a default
453eae561b3SGarrett Wollman  * routine may be called.
454eae561b3SGarrett Wollman  * If there is no specific or default routine an error is returned.
455eae561b3SGarrett Wollman  */
456eae561b3SGarrett Wollman bool_t
457eae561b3SGarrett Wollman xdr_union(xdrs, dscmp, unp, choices, dfault)
458eae561b3SGarrett Wollman 	register XDR *xdrs;
459eae561b3SGarrett Wollman 	enum_t *dscmp;		/* enum to decide which arm to work on */
460eae561b3SGarrett Wollman 	char *unp;		/* the union itself */
461eae561b3SGarrett Wollman 	struct xdr_discrim *choices;	/* [value, xdr proc] for each arm */
462eae561b3SGarrett Wollman 	xdrproc_t dfault;	/* default xdr routine */
463eae561b3SGarrett Wollman {
464eae561b3SGarrett Wollman 	register enum_t dscm;
465eae561b3SGarrett Wollman 
466eae561b3SGarrett Wollman 	/*
467eae561b3SGarrett Wollman 	 * we deal with the discriminator;  it's an enum
468eae561b3SGarrett Wollman 	 */
469eae561b3SGarrett Wollman 	if (! xdr_enum(xdrs, dscmp)) {
470eae561b3SGarrett Wollman 		return (FALSE);
471eae561b3SGarrett Wollman 	}
472eae561b3SGarrett Wollman 	dscm = *dscmp;
473eae561b3SGarrett Wollman 
474eae561b3SGarrett Wollman 	/*
475eae561b3SGarrett Wollman 	 * search choices for a value that matches the discriminator.
476eae561b3SGarrett Wollman 	 * if we find one, execute the xdr routine for that value.
477eae561b3SGarrett Wollman 	 */
478eae561b3SGarrett Wollman 	for (; choices->proc != NULL_xdrproc_t; choices++) {
479eae561b3SGarrett Wollman 		if (choices->value == dscm)
480eae561b3SGarrett Wollman 			return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
481eae561b3SGarrett Wollman 	}
482eae561b3SGarrett Wollman 
483eae561b3SGarrett Wollman 	/*
484eae561b3SGarrett Wollman 	 * no match - execute the default xdr routine if there is one
485eae561b3SGarrett Wollman 	 */
486eae561b3SGarrett Wollman 	return ((dfault == NULL_xdrproc_t) ? FALSE :
487eae561b3SGarrett Wollman 	    (*dfault)(xdrs, unp, LASTUNSIGNED));
488eae561b3SGarrett Wollman }
489eae561b3SGarrett Wollman 
490eae561b3SGarrett Wollman 
491eae561b3SGarrett Wollman /*
492eae561b3SGarrett Wollman  * Non-portable xdr primitives.
493eae561b3SGarrett Wollman  * Care should be taken when moving these routines to new architectures.
494eae561b3SGarrett Wollman  */
495eae561b3SGarrett Wollman 
496eae561b3SGarrett Wollman 
497eae561b3SGarrett Wollman /*
498eae561b3SGarrett Wollman  * XDR null terminated ASCII strings
499eae561b3SGarrett Wollman  * xdr_string deals with "C strings" - arrays of bytes that are
500eae561b3SGarrett Wollman  * terminated by a NULL character.  The parameter cpp references a
501eae561b3SGarrett Wollman  * pointer to storage; If the pointer is null, then the necessary
502eae561b3SGarrett Wollman  * storage is allocated.  The last parameter is the max allowed length
503eae561b3SGarrett Wollman  * of the string as specified by a protocol.
504eae561b3SGarrett Wollman  */
505eae561b3SGarrett Wollman bool_t
506eae561b3SGarrett Wollman xdr_string(xdrs, cpp, maxsize)
507eae561b3SGarrett Wollman 	register XDR *xdrs;
508eae561b3SGarrett Wollman 	char **cpp;
509eae561b3SGarrett Wollman 	u_int maxsize;
510eae561b3SGarrett Wollman {
511eae561b3SGarrett Wollman 	register char *sp = *cpp;  /* sp is the actual string pointer */
512eae561b3SGarrett Wollman 	u_int size;
513eae561b3SGarrett Wollman 	u_int nodesize;
514eae561b3SGarrett Wollman 
515eae561b3SGarrett Wollman 	/*
516eae561b3SGarrett Wollman 	 * first deal with the length since xdr strings are counted-strings
517eae561b3SGarrett Wollman 	 */
518eae561b3SGarrett Wollman 	switch (xdrs->x_op) {
519eae561b3SGarrett Wollman 	case XDR_FREE:
520eae561b3SGarrett Wollman 		if (sp == NULL) {
521eae561b3SGarrett Wollman 			return(TRUE);	/* already free */
522eae561b3SGarrett Wollman 		}
523eae561b3SGarrett Wollman 		/* fall through... */
524eae561b3SGarrett Wollman 	case XDR_ENCODE:
525eae561b3SGarrett Wollman 		size = strlen(sp);
526eae561b3SGarrett Wollman 		break;
527eae561b3SGarrett Wollman 	}
528eae561b3SGarrett Wollman 	if (! xdr_u_int(xdrs, &size)) {
529eae561b3SGarrett Wollman 		return (FALSE);
530eae561b3SGarrett Wollman 	}
531eae561b3SGarrett Wollman 	if (size > maxsize) {
532eae561b3SGarrett Wollman 		return (FALSE);
533eae561b3SGarrett Wollman 	}
534eae561b3SGarrett Wollman 	nodesize = size + 1;
535eae561b3SGarrett Wollman 
536eae561b3SGarrett Wollman 	/*
537eae561b3SGarrett Wollman 	 * now deal with the actual bytes
538eae561b3SGarrett Wollman 	 */
539eae561b3SGarrett Wollman 	switch (xdrs->x_op) {
540eae561b3SGarrett Wollman 
541eae561b3SGarrett Wollman 	case XDR_DECODE:
542eae561b3SGarrett Wollman 		if (nodesize == 0) {
543eae561b3SGarrett Wollman 			return (TRUE);
544eae561b3SGarrett Wollman 		}
545eae561b3SGarrett Wollman 		if (sp == NULL)
546eae561b3SGarrett Wollman 			*cpp = sp = (char *)mem_alloc(nodesize);
547eae561b3SGarrett Wollman 		if (sp == NULL) {
548eae561b3SGarrett Wollman 			(void) fprintf(stderr, "xdr_string: out of memory\n");
549eae561b3SGarrett Wollman 			return (FALSE);
550eae561b3SGarrett Wollman 		}
551eae561b3SGarrett Wollman 		sp[size] = 0;
552eae561b3SGarrett Wollman 		/* fall into ... */
553eae561b3SGarrett Wollman 
554eae561b3SGarrett Wollman 	case XDR_ENCODE:
555eae561b3SGarrett Wollman 		return (xdr_opaque(xdrs, sp, size));
556eae561b3SGarrett Wollman 
557eae561b3SGarrett Wollman 	case XDR_FREE:
558eae561b3SGarrett Wollman 		mem_free(sp, nodesize);
559eae561b3SGarrett Wollman 		*cpp = NULL;
560eae561b3SGarrett Wollman 		return (TRUE);
561eae561b3SGarrett Wollman 	}
562eae561b3SGarrett Wollman 	return (FALSE);
563eae561b3SGarrett Wollman }
564eae561b3SGarrett Wollman 
565eae561b3SGarrett Wollman /*
566eae561b3SGarrett Wollman  * Wrapper for xdr_string that can be called directly from
567eae561b3SGarrett Wollman  * routines like clnt_call
568eae561b3SGarrett Wollman  */
569eae561b3SGarrett Wollman bool_t
570eae561b3SGarrett Wollman xdr_wrapstring(xdrs, cpp)
571eae561b3SGarrett Wollman 	XDR *xdrs;
572eae561b3SGarrett Wollman 	char **cpp;
573eae561b3SGarrett Wollman {
574eae561b3SGarrett Wollman 	if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
575eae561b3SGarrett Wollman 		return (TRUE);
576eae561b3SGarrett Wollman 	}
577eae561b3SGarrett Wollman 	return (FALSE);
578eae561b3SGarrett Wollman }
579