xref: /minix3/lib/libc/rpc/xdr.c (revision f14fb602092e015ff630df58e17c2a9cd57d29b3)
1 /*	$NetBSD: xdr.c,v 1.31 2012/06/25 22:32:45 abs Exp $	*/
2 
3 /*
4  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5  * unrestricted use provided that this legend is included on all tape
6  * media and as a part of the software program in whole or part.  Users
7  * may copy or modify Sun RPC without charge, but are not authorized
8  * to license or distribute it to anyone else except as part of a product or
9  * program developed by the user.
10  *
11  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14  *
15  * Sun RPC is provided with no support and without any obligation on the
16  * part of Sun Microsystems, Inc. to assist in its use, correction,
17  * modification or enhancement.
18  *
19  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21  * OR ANY PART THEREOF.
22  *
23  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24  * or profits or other special, indirect and consequential damages, even if
25  * Sun has been advised of the possibility of such damages.
26  *
27  * Sun Microsystems, Inc.
28  * 2550 Garcia Avenue
29  * Mountain View, California  94043
30  */
31 
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
34 #if 0
35 static char *sccsid = "@(#)xdr.c 1.35 87/08/12";
36 static char *sccsid = "@(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";
37 #else
38 __RCSID("$NetBSD: xdr.c,v 1.31 2012/06/25 22:32:45 abs Exp $");
39 #endif
40 #endif
41 
42 /*
43  * xdr.c, Generic XDR routines implementation.
44  *
45  * Copyright (C) 1986, Sun Microsystems, Inc.
46  *
47  * These are the "generic" xdr routines used to serialize and de-serialize
48  * most common data items.  See xdr.h for more info on the interface to
49  * xdr.
50  */
51 
52 #include "namespace.h"
53 
54 #include <assert.h>
55 #include <err.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 
60 #include <rpc/types.h>
61 #include <rpc/xdr.h>
62 
63 #ifdef __weak_alias
64 __weak_alias(xdr_bool,_xdr_bool)
65 __weak_alias(xdr_bytes,_xdr_bytes)
66 __weak_alias(xdr_char,_xdr_char)
67 __weak_alias(xdr_enum,_xdr_enum)
68 __weak_alias(xdr_free,_xdr_free)
69 __weak_alias(xdr_hyper,_xdr_hyper)
70 __weak_alias(xdr_int,_xdr_int)
71 __weak_alias(xdr_int16_t,_xdr_int16_t)
72 __weak_alias(xdr_int32_t,_xdr_int32_t)
73 __weak_alias(xdr_int64_t,_xdr_int64_t)
74 __weak_alias(xdr_long,_xdr_long)
75 __weak_alias(xdr_longlong_t,_xdr_longlong_t)
76 __weak_alias(xdr_netobj,_xdr_netobj)
77 __weak_alias(xdr_opaque,_xdr_opaque)
78 __weak_alias(xdr_short,_xdr_short)
79 __weak_alias(xdr_string,_xdr_string)
80 __weak_alias(xdr_u_char,_xdr_u_char)
81 __weak_alias(xdr_u_hyper,_xdr_u_hyper)
82 __weak_alias(xdr_u_int,_xdr_u_int)
83 __weak_alias(xdr_u_int16_t,_xdr_u_int16_t)
84 __weak_alias(xdr_u_int32_t,_xdr_u_int32_t)
85 __weak_alias(xdr_u_int64_t,_xdr_u_int64_t)
86 __weak_alias(xdr_u_long,_xdr_u_long)
87 __weak_alias(xdr_u_longlong_t,_xdr_u_longlong_t)
88 __weak_alias(xdr_u_short,_xdr_u_short)
89 __weak_alias(xdr_union,_xdr_union)
90 __weak_alias(xdr_void,_xdr_void)
91 __weak_alias(xdr_wrapstring,_xdr_wrapstring)
92 #endif
93 
94 /*
95  * constants specific to the xdr "protocol"
96  */
97 #define XDR_FALSE	((long) 0)
98 #define XDR_TRUE	((long) 1)
99 #define LASTUNSIGNED	((u_int) 0-1)
100 
101 /*
102  * for unit alignment
103  */
104 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
105 
106 /*
107  * Free a data structure using XDR
108  * Not a filter, but a convenient utility nonetheless
109  */
110 void
111 xdr_free(xdrproc_t proc, char *objp)
112 {
113 	XDR x;
114 
115 	x.x_op = XDR_FREE;
116 	(*proc)(&x, objp);
117 }
118 
119 /*
120  * XDR nothing
121  */
122 bool_t
123 xdr_void(void) {
124 
125 	return (TRUE);
126 }
127 
128 
129 /*
130  * XDR integers
131  */
132 bool_t
133 xdr_int(XDR *xdrs, int *ip)
134 {
135 	long l;
136 
137 	_DIAGASSERT(xdrs != NULL);
138 	_DIAGASSERT(ip != NULL);
139 
140 	switch (xdrs->x_op) {
141 
142 	case XDR_ENCODE:
143 		l = (long) *ip;
144 		return (XDR_PUTLONG(xdrs, &l));
145 
146 	case XDR_DECODE:
147 		if (!XDR_GETLONG(xdrs, &l)) {
148 			return (FALSE);
149 		}
150 		*ip = (int) l;
151 		return (TRUE);
152 
153 	case XDR_FREE:
154 		return (TRUE);
155 	}
156 	/* NOTREACHED */
157 	return (FALSE);
158 }
159 
160 /*
161  * XDR unsigned integers
162  */
163 bool_t
164 xdr_u_int(XDR *xdrs, u_int *up)
165 {
166 	u_long l;
167 
168 	_DIAGASSERT(xdrs != NULL);
169 	_DIAGASSERT(up != NULL);
170 
171 	switch (xdrs->x_op) {
172 
173 	case XDR_ENCODE:
174 		l = (u_long) *up;
175 		return (XDR_PUTLONG(xdrs, (long *)&l));
176 
177 	case XDR_DECODE:
178 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
179 			return (FALSE);
180 		}
181 		*up = (u_int) l;
182 		return (TRUE);
183 
184 	case XDR_FREE:
185 		return (TRUE);
186 	}
187 	/* NOTREACHED */
188 	return (FALSE);
189 }
190 
191 
192 /*
193  * XDR long integers
194  * same as xdr_u_long - open coded to save a proc call!
195  */
196 bool_t
197 xdr_long(XDR *xdrs, long *lp)
198 {
199 
200 	_DIAGASSERT(xdrs != NULL);
201 	_DIAGASSERT(lp != NULL);
202 
203 	switch (xdrs->x_op) {
204 	case XDR_ENCODE:
205 		return (XDR_PUTLONG(xdrs, lp));
206 	case XDR_DECODE:
207 		return (XDR_GETLONG(xdrs, lp));
208 	case XDR_FREE:
209 		return (TRUE);
210 	}
211 	/* NOTREACHED */
212 	return (FALSE);
213 }
214 
215 /*
216  * XDR unsigned long integers
217  * same as xdr_long - open coded to save a proc call!
218  */
219 bool_t
220 xdr_u_long(XDR *xdrs, u_long *ulp)
221 {
222 
223 	_DIAGASSERT(xdrs != NULL);
224 	_DIAGASSERT(ulp != NULL);
225 
226 	switch (xdrs->x_op) {
227 	case XDR_ENCODE:
228 		return (XDR_PUTLONG(xdrs, (long *)ulp));
229 	case XDR_DECODE:
230 		return (XDR_GETLONG(xdrs, (long *)ulp));
231 	case XDR_FREE:
232 		return (TRUE);
233 	}
234 	/* NOTREACHED */
235 	return (FALSE);
236 }
237 
238 
239 /*
240  * XDR 32-bit integers
241  * same as xdr_u_int32_t - open coded to save a proc call!
242  */
243 bool_t
244 xdr_int32_t(XDR *xdrs, int32_t *int32_p)
245 {
246 	long l;
247 
248 	_DIAGASSERT(xdrs != NULL);
249 	_DIAGASSERT(int32_p != NULL);
250 
251 	switch (xdrs->x_op) {
252 
253 	case XDR_ENCODE:
254 		l = (long) *int32_p;
255 		return (XDR_PUTLONG(xdrs, &l));
256 
257 	case XDR_DECODE:
258 		if (!XDR_GETLONG(xdrs, &l)) {
259 			return (FALSE);
260 		}
261 		*int32_p = (int32_t) l;
262 		return (TRUE);
263 
264 	case XDR_FREE:
265 		return (TRUE);
266 	}
267 	/* NOTREACHED */
268 	return (FALSE);
269 }
270 
271 /*
272  * XDR unsigned 32-bit integers
273  * same as xdr_int32_t - open coded to save a proc call!
274  */
275 bool_t
276 xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p)
277 {
278 	u_long l;
279 
280 	_DIAGASSERT(xdrs != NULL);
281 	_DIAGASSERT(u_int32_p != NULL);
282 
283 	switch (xdrs->x_op) {
284 
285 	case XDR_ENCODE:
286 		l = (u_long) *u_int32_p;
287 		return (XDR_PUTLONG(xdrs, (long *)&l));
288 
289 	case XDR_DECODE:
290 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
291 			return (FALSE);
292 		}
293 		*u_int32_p = (u_int32_t) l;
294 		return (TRUE);
295 
296 	case XDR_FREE:
297 		return (TRUE);
298 	}
299 	/* NOTREACHED */
300 	return (FALSE);
301 }
302 
303 
304 /*
305  * XDR short integers
306  */
307 bool_t
308 xdr_short(XDR *xdrs, short *sp)
309 {
310 	long l;
311 
312 	_DIAGASSERT(xdrs != NULL);
313 	_DIAGASSERT(sp != NULL);
314 
315 	switch (xdrs->x_op) {
316 
317 	case XDR_ENCODE:
318 		l = (long) *sp;
319 		return (XDR_PUTLONG(xdrs, &l));
320 
321 	case XDR_DECODE:
322 		if (!XDR_GETLONG(xdrs, &l)) {
323 			return (FALSE);
324 		}
325 		*sp = (short) l;
326 		return (TRUE);
327 
328 	case XDR_FREE:
329 		return (TRUE);
330 	}
331 	/* NOTREACHED */
332 	return (FALSE);
333 }
334 
335 /*
336  * XDR unsigned short integers
337  */
338 bool_t
339 xdr_u_short(XDR *xdrs, u_short *usp)
340 {
341 	u_long l;
342 
343 	_DIAGASSERT(xdrs != NULL);
344 	_DIAGASSERT(usp != NULL);
345 
346 	switch (xdrs->x_op) {
347 
348 	case XDR_ENCODE:
349 		l = (u_long) *usp;
350 		return (XDR_PUTLONG(xdrs, (long *)&l));
351 
352 	case XDR_DECODE:
353 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
354 			return (FALSE);
355 		}
356 		*usp = (u_short) l;
357 		return (TRUE);
358 
359 	case XDR_FREE:
360 		return (TRUE);
361 	}
362 	/* NOTREACHED */
363 	return (FALSE);
364 }
365 
366 
367 /*
368  * XDR 16-bit integers
369  */
370 bool_t
371 xdr_int16_t(XDR *xdrs, int16_t *int16_p)
372 {
373 	long l;
374 
375 	_DIAGASSERT(xdrs != NULL);
376 	_DIAGASSERT(int16_p != NULL);
377 
378 	switch (xdrs->x_op) {
379 
380 	case XDR_ENCODE:
381 		l = (long) *int16_p;
382 		return (XDR_PUTLONG(xdrs, &l));
383 
384 	case XDR_DECODE:
385 		if (!XDR_GETLONG(xdrs, &l)) {
386 			return (FALSE);
387 		}
388 		*int16_p = (int16_t) l;
389 		return (TRUE);
390 
391 	case XDR_FREE:
392 		return (TRUE);
393 	}
394 	/* NOTREACHED */
395 	return (FALSE);
396 }
397 
398 /*
399  * XDR unsigned 16-bit integers
400  */
401 bool_t
402 xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p)
403 {
404 	u_long l;
405 
406 	_DIAGASSERT(xdrs != NULL);
407 	_DIAGASSERT(u_int16_p != NULL);
408 
409 	switch (xdrs->x_op) {
410 
411 	case XDR_ENCODE:
412 		l = (u_long) *u_int16_p;
413 		return (XDR_PUTLONG(xdrs, (long *)&l));
414 
415 	case XDR_DECODE:
416 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
417 			return (FALSE);
418 		}
419 		*u_int16_p = (u_int16_t) l;
420 		return (TRUE);
421 
422 	case XDR_FREE:
423 		return (TRUE);
424 	}
425 	/* NOTREACHED */
426 	return (FALSE);
427 }
428 
429 
430 /*
431  * XDR a char
432  */
433 bool_t
434 xdr_char(XDR *xdrs, char *cp)
435 {
436 	int i;
437 
438 	_DIAGASSERT(xdrs != NULL);
439 	_DIAGASSERT(cp != NULL);
440 
441 	i = (*cp);
442 	if (!xdr_int(xdrs, &i)) {
443 		return (FALSE);
444 	}
445 	*cp = i;
446 	return (TRUE);
447 }
448 
449 /*
450  * XDR an unsigned char
451  */
452 bool_t
453 xdr_u_char(XDR *xdrs, u_char *cp)
454 {
455 	u_int u;
456 
457 	_DIAGASSERT(xdrs != NULL);
458 	_DIAGASSERT(cp != NULL);
459 
460 	u = (*cp);
461 	if (!xdr_u_int(xdrs, &u)) {
462 		return (FALSE);
463 	}
464 	*cp = u;
465 	return (TRUE);
466 }
467 
468 /*
469  * XDR booleans
470  */
471 bool_t
472 xdr_bool(XDR *xdrs, bool_t *bp)
473 {
474 	long lb;
475 
476 	_DIAGASSERT(xdrs != NULL);
477 	_DIAGASSERT(bp != NULL);
478 
479 	switch (xdrs->x_op) {
480 
481 	case XDR_ENCODE:
482 		lb = *bp ? XDR_TRUE : XDR_FALSE;
483 		return (XDR_PUTLONG(xdrs, &lb));
484 
485 	case XDR_DECODE:
486 		if (!XDR_GETLONG(xdrs, &lb)) {
487 			return (FALSE);
488 		}
489 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
490 		return (TRUE);
491 
492 	case XDR_FREE:
493 		return (TRUE);
494 	}
495 	/* NOTREACHED */
496 	return (FALSE);
497 }
498 
499 /*
500  * XDR enumerations
501  */
502 bool_t
503 xdr_enum(XDR *xdrs, enum_t *ep)
504 {
505 	long l;
506 
507 	_DIAGASSERT(xdrs != NULL);
508 	_DIAGASSERT(ep != NULL);
509 
510 	switch (xdrs->x_op) {
511 
512 	case XDR_ENCODE:
513 		l = (long) *ep;
514 		return (XDR_PUTLONG(xdrs, &l));
515 
516 	case XDR_DECODE:
517 		if (!XDR_GETLONG(xdrs, &l)) {
518 			return (FALSE);
519 		}
520 		*ep = (enum_t) l;
521 		return (TRUE);
522 
523 	case XDR_FREE:
524 		return (TRUE);
525 	}
526 	/* NOTREACHED */
527 	return (FALSE);
528 }
529 
530 /*
531  * XDR opaque data
532  * Allows the specification of a fixed size sequence of opaque bytes.
533  * cp points to the opaque object and cnt gives the byte length.
534  */
535 bool_t
536 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
537 {
538 	u_int rndup;
539 	static int crud[BYTES_PER_XDR_UNIT];
540 
541 	_DIAGASSERT(xdrs != NULL);
542 		/*
543 		 * if no data we are done
544 		 */
545 	if (cnt == 0)
546 		return (TRUE);
547 	_DIAGASSERT(cp != NULL);
548 
549 	/*
550 	 * round byte count to full xdr units
551 	 */
552 	rndup = cnt % BYTES_PER_XDR_UNIT;
553 	if (rndup > 0)
554 		rndup = BYTES_PER_XDR_UNIT - rndup;
555 
556 	if (xdrs->x_op == XDR_DECODE) {
557 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
558 			return (FALSE);
559 		}
560 		if (rndup == 0)
561 			return (TRUE);
562 		return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
563 	}
564 
565 	if (xdrs->x_op == XDR_ENCODE) {
566 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
567 			return (FALSE);
568 		}
569 		if (rndup == 0)
570 			return (TRUE);
571 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
572 	}
573 
574 	if (xdrs->x_op == XDR_FREE) {
575 		return (TRUE);
576 	}
577 
578 	return (FALSE);
579 }
580 
581 /*
582  * XDR counted bytes
583  * *cpp is a pointer to the bytes, *sizep is the count.
584  * If *cpp is NULL maxsize bytes are allocated
585  */
586 bool_t
587 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
588 {
589 	char *sp;  		/* sp is the actual string pointer */
590 	u_int nodesize;
591 
592 	_DIAGASSERT(xdrs != NULL);
593 	_DIAGASSERT(cpp != NULL);
594 	_DIAGASSERT(sizep != NULL);
595 
596 	sp = *cpp;
597 
598 	/*
599 	 * first deal with the length since xdr bytes are counted
600 	 */
601 	if (! xdr_u_int(xdrs, sizep)) {
602 		return (FALSE);
603 	}
604 	nodesize = *sizep;
605 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
606 		return (FALSE);
607 	}
608 
609 	/*
610 	 * now deal with the actual bytes
611 	 */
612 	switch (xdrs->x_op) {
613 
614 	case XDR_DECODE:
615 		if (nodesize == 0) {
616 			return (TRUE);
617 		}
618 		if (sp == NULL) {
619 			*cpp = sp = mem_alloc(nodesize);
620 		}
621 		if (sp == NULL) {
622 			warnx("xdr_bytes: out of memory");
623 			return (FALSE);
624 		}
625 		/* FALLTHROUGH */
626 
627 	case XDR_ENCODE:
628 		return (xdr_opaque(xdrs, sp, nodesize));
629 
630 	case XDR_FREE:
631 		if (sp != NULL) {
632 			mem_free(sp, nodesize);
633 			*cpp = NULL;
634 		}
635 		return (TRUE);
636 	}
637 	/* NOTREACHED */
638 	return (FALSE);
639 }
640 
641 /*
642  * Implemented here due to commonality of the object.
643  */
644 bool_t
645 xdr_netobj(XDR *xdrs, struct netobj *np)
646 {
647 
648 	_DIAGASSERT(xdrs != NULL);
649 	_DIAGASSERT(np != NULL);
650 
651 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
652 }
653 
654 /*
655  * XDR a descriminated union
656  * Support routine for discriminated unions.
657  * You create an array of xdrdiscrim structures, terminated with
658  * an entry with a null procedure pointer.  The routine gets
659  * the discriminant value and then searches the array of xdrdiscrims
660  * looking for that value.  It calls the procedure given in the xdrdiscrim
661  * to handle the discriminant.  If there is no specific routine a default
662  * routine may be called.
663  * If there is no specific or default routine an error is returned.
664  */
665 bool_t
666 xdr_union(
667 	XDR *xdrs,
668 	enum_t *dscmp,		/* enum to decide which arm to work on */
669 	char *unp,		/* the union itself */
670 	const struct xdr_discrim *choices, /* [value, xdr proc] for each arm */
671 	xdrproc_t dfault	/* default xdr routine */
672 )
673 {
674 	enum_t dscm;
675 
676 	_DIAGASSERT(xdrs != NULL);
677 	_DIAGASSERT(dscmp != NULL);
678 	_DIAGASSERT(unp != NULL);
679 	_DIAGASSERT(choices != NULL);
680 	/* dfault may be NULL */
681 
682 	/*
683 	 * we deal with the discriminator;  it's an enum
684 	 */
685 	if (! xdr_enum(xdrs, dscmp)) {
686 		return (FALSE);
687 	}
688 	dscm = *dscmp;
689 
690 	/*
691 	 * search choices for a value that matches the discriminator.
692 	 * if we find one, execute the xdr routine for that value.
693 	 */
694 	for (; choices->proc != NULL_xdrproc_t; choices++) {
695 		if (choices->value == dscm)
696 			return ((*(choices->proc))(xdrs, unp));
697 	}
698 
699 	/*
700 	 * no match - execute the default xdr routine if there is one
701 	 */
702 	return ((dfault == NULL_xdrproc_t) ? FALSE :
703 	    (*dfault)(xdrs, unp));
704 }
705 
706 
707 /*
708  * Non-portable xdr primitives.
709  * Care should be taken when moving these routines to new architectures.
710  */
711 
712 
713 /*
714  * XDR null terminated ASCII strings
715  * xdr_string deals with "C strings" - arrays of bytes that are
716  * terminated by a NULL character.  The parameter cpp references a
717  * pointer to storage; If the pointer is null, then the necessary
718  * storage is allocated.  The last parameter is the max allowed length
719  * of the string as specified by a protocol.
720  */
721 bool_t
722 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
723 {
724 	char *sp;  		/* sp is the actual string pointer */
725 	u_int size = 0;		/* XXX: GCC */
726 	u_int nodesize;
727 	size_t len;
728 
729 	_DIAGASSERT(xdrs != NULL);
730 	_DIAGASSERT(cpp != NULL);
731 
732 	sp = *cpp;
733 
734 	/*
735 	 * first deal with the length since xdr strings are counted-strings
736 	 */
737 	switch (xdrs->x_op) {
738 	case XDR_FREE:
739 		if (sp == NULL) {
740 			return(TRUE);	/* already free */
741 		}
742 		/* FALLTHROUGH */
743 	case XDR_ENCODE:
744 		len = strlen(sp);
745 		_DIAGASSERT(__type_fit(u_int, len));
746 		size = (u_int)len;
747 		break;
748 	case XDR_DECODE:
749 		break;
750 	}
751 	if (! xdr_u_int(xdrs, &size)) {
752 		return (FALSE);
753 	}
754 	if (size > maxsize) {
755 		return (FALSE);
756 	}
757 	nodesize = size + 1;
758 
759 	/*
760 	 * now deal with the actual bytes
761 	 */
762 	switch (xdrs->x_op) {
763 
764 	case XDR_DECODE:
765 		if (nodesize == 0) {
766 			return (TRUE);
767 		}
768 		if (sp == NULL)
769 			*cpp = sp = mem_alloc(nodesize);
770 		if (sp == NULL) {
771 			warnx("xdr_string: out of memory");
772 			return (FALSE);
773 		}
774 		sp[size] = 0;
775 		/* FALLTHROUGH */
776 
777 	case XDR_ENCODE:
778 		return (xdr_opaque(xdrs, sp, size));
779 
780 	case XDR_FREE:
781 		mem_free(sp, nodesize);
782 		*cpp = NULL;
783 		return (TRUE);
784 	}
785 	/* NOTREACHED */
786 	return (FALSE);
787 }
788 
789 /*
790  * Wrapper for xdr_string that can be called directly from
791  * routines like clnt_call
792  */
793 bool_t
794 xdr_wrapstring(XDR *xdrs, char **cpp)
795 {
796 
797 	_DIAGASSERT(xdrs != NULL);
798 	_DIAGASSERT(cpp != NULL);
799 
800 	return xdr_string(xdrs, cpp, LASTUNSIGNED);
801 }
802 
803 /*
804  * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
805  * are in the "non-portable" section because they require that a `long long'
806  * be a 64-bit type.
807  *
808  *	--thorpej@NetBSD.org, November 30, 1999
809  */
810 
811 /*
812  * XDR 64-bit integers
813  */
814 bool_t
815 xdr_int64_t(XDR *xdrs, int64_t *llp)
816 {
817 	u_long ul[2];
818 
819 	_DIAGASSERT(xdrs != NULL);
820 	_DIAGASSERT(llp != NULL);
821 
822 	switch (xdrs->x_op) {
823 	case XDR_ENCODE:
824 		ul[0] = (u_long)(((uint64_t)*llp >> 32) &
825 		    (uint64_t)0xffffffffULL);
826 		ul[1] = (u_long)(((uint64_t)*llp) &
827 		    (uint64_t)0xffffffffULL);
828 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
829 			return (FALSE);
830 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
831 	case XDR_DECODE:
832 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
833 			return (FALSE);
834 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
835 			return (FALSE);
836 		*llp = (int64_t)
837 		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
838 		return (TRUE);
839 	case XDR_FREE:
840 		return (TRUE);
841 	}
842 	/* NOTREACHED */
843 	return (FALSE);
844 }
845 
846 
847 /*
848  * XDR unsigned 64-bit integers
849  */
850 bool_t
851 xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp)
852 {
853 	u_long ul[2];
854 
855 	_DIAGASSERT(xdrs != NULL);
856 	_DIAGASSERT(ullp != NULL);
857 
858 	switch (xdrs->x_op) {
859 	case XDR_ENCODE:
860 		ul[0] = (u_long)(*ullp >> 32) & 0xffffffffUL;
861 		ul[1] = (u_long)(*ullp) & 0xffffffffUL;
862 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
863 			return (FALSE);
864 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
865 	case XDR_DECODE:
866 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
867 			return (FALSE);
868 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
869 			return (FALSE);
870 		*ullp = (u_int64_t)
871 		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
872 		return (TRUE);
873 	case XDR_FREE:
874 		return (TRUE);
875 	}
876 	/* NOTREACHED */
877 	return (FALSE);
878 }
879 
880 
881 /*
882  * XDR hypers
883  */
884 bool_t
885 xdr_hyper(XDR *xdrs, longlong_t *llp)
886 {
887 
888 	_DIAGASSERT(xdrs != NULL);
889 	_DIAGASSERT(llp != NULL);
890 
891 	/*
892 	 * Don't bother open-coding this; it's a fair amount of code.  Just
893 	 * call xdr_int64_t().
894 	 */
895 	return (xdr_int64_t(xdrs, (int64_t *)llp));
896 }
897 
898 
899 /*
900  * XDR unsigned hypers
901  */
902 bool_t
903 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp)
904 {
905 
906 	_DIAGASSERT(xdrs != NULL);
907 	_DIAGASSERT(ullp != NULL);
908 
909 	/*
910 	 * Don't bother open-coding this; it's a fair amount of code.  Just
911 	 * call xdr_u_int64_t().
912 	 */
913 	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
914 }
915 
916 
917 /*
918  * XDR longlong_t's
919  */
920 bool_t
921 xdr_longlong_t(XDR *xdrs, longlong_t *llp)
922 {
923 
924 	_DIAGASSERT(xdrs != NULL);
925 	_DIAGASSERT(llp != NULL);
926 
927 	/*
928 	 * Don't bother open-coding this; it's a fair amount of code.  Just
929 	 * call xdr_int64_t().
930 	 */
931 	return (xdr_int64_t(xdrs, (int64_t *)llp));
932 }
933 
934 
935 /*
936  * XDR u_longlong_t's
937  */
938 bool_t
939 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
940 {
941 
942 	_DIAGASSERT(xdrs != NULL);
943 	_DIAGASSERT(ullp != NULL);
944 
945 	/*
946 	 * Don't bother open-coding this; it's a fair amount of code.  Just
947 	 * call xdr_u_int64_t().
948 	 */
949 	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
950 }
951