1 /*
2 * Copyright (c) 2009, Sun Microsystems, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * xdr.c, Generic XDR routines implementation.
31 *
32 * Copyright (C) 1986, Sun Microsystems, Inc.
33 *
34 * These are the "generic" xdr routines used to serialize and de-serialize
35 * most common data items. See xdr.h for more info on the interface to
36 * xdr.
37 */
38
39 #define _DEFAULT_SOURCE
40 #include <stdlib.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <limits.h>
44
45 #include <rpc/types.h>
46 #include <rpc/xdr.h>
47
48 #include "xdr_private.h"
49
50 /*
51 * constants specific to the xdr "protocol"
52 */
53 #define XDR_FALSE ((long) 0)
54 #define XDR_TRUE ((long) 1)
55 #define LASTUNSIGNED ((u_int) 0-1)
56
57 /*
58 * for unit alignment
59 */
60 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
61
62 /*
63 * Free a data structure using XDR
64 * Not a filter, but a convenient utility nonetheless
65 */
66 void
xdr_free(xdrproc_t proc,void * objp)67 xdr_free (xdrproc_t proc,
68 void * objp)
69 {
70 XDR x;
71
72 x.x_op = XDR_FREE;
73 (*proc) (&x, objp);
74 }
75
76 /*
77 * XDR nothing
78 */
79 bool_t
xdr_void(void)80 xdr_void (void)
81 {
82 return TRUE;
83 }
84
85
86 /*
87 * XDR integers
88 */
89 bool_t
xdr_int(XDR * xdrs,int * ip)90 xdr_int (XDR * xdrs,
91 int * ip)
92 {
93 #if INT_MAX < LONG_MAX
94 long l;
95 switch (xdrs->x_op)
96 {
97 case XDR_ENCODE:
98 l = (long) *ip;
99 return (XDR_PUTLONG (xdrs, &l));
100
101 case XDR_DECODE:
102 if (!XDR_GETLONG (xdrs, &l))
103 {
104 return FALSE;
105 }
106 *ip = (int) l;
107 return TRUE;
108
109 case XDR_FREE:
110 return TRUE;
111 }
112 return FALSE;
113 #elif INT_MAX == LONG_MAX
114 return xdr_long (xdrs, (long *) ip);
115 #else
116 # error Unexpected integer sizes in xdr_int()
117 #endif
118 }
119
120 /*
121 * XDR unsigned integers
122 */
123 bool_t
xdr_u_int(XDR * xdrs,u_int * up)124 xdr_u_int (XDR * xdrs,
125 u_int * up)
126 {
127 #if UINT_MAX < ULONG_MAX
128 u_long l;
129 switch (xdrs->x_op)
130 {
131 case XDR_ENCODE:
132 l = (u_long) * up;
133 return (XDR_PUTLONG (xdrs, (long *) &l));
134
135 case XDR_DECODE:
136 if (!XDR_GETLONG (xdrs, (long *) &l))
137 {
138 return FALSE;
139 }
140 *up = (u_int) (u_long) l;
141 return TRUE;
142
143 case XDR_FREE:
144 return TRUE;
145 }
146 return FALSE;
147 #elif UINT_MAX == ULONG_MAX
148 return xdr_u_long (xdrs, (u_long *) up);
149 #else
150 # error Unexpected integer sizes in xdr_int()
151 #endif
152 }
153
154 /*
155 * XDR long integers
156 */
157 bool_t
xdr_long(XDR * xdrs,long * lp)158 xdr_long (XDR * xdrs,
159 long * lp)
160 {
161 if ((xdrs->x_op == XDR_ENCODE)
162 && ((sizeof (int32_t) == sizeof (long)) || ((int32_t) *lp == *lp)))
163 return XDR_PUTLONG (xdrs, lp);
164
165 if (xdrs->x_op == XDR_DECODE)
166 return XDR_GETLONG (xdrs, lp);
167
168 if (xdrs->x_op == XDR_FREE)
169 return TRUE;
170
171 return FALSE;
172 }
173
174 /*
175 * XDR unsigned long integers
176 */
177 bool_t
xdr_u_long(XDR * xdrs,u_long * ulp)178 xdr_u_long (XDR * xdrs,
179 u_long * ulp)
180 {
181 switch (xdrs->x_op)
182 {
183 case XDR_ENCODE:
184 if ((sizeof (uint32_t) != sizeof (u_long)) && ((uint32_t) *ulp != *ulp))
185 return FALSE;
186 return (XDR_PUTLONG (xdrs, (long *) ulp));
187
188 case XDR_DECODE:
189 {
190 long int tmp;
191 if (XDR_GETLONG (xdrs, &tmp) == FALSE)
192 return FALSE;
193 *ulp = (u_long) (uint32_t) tmp;
194 return TRUE;
195 }
196
197 case XDR_FREE:
198 return TRUE;
199 }
200 return FALSE;
201 }
202
203
204 /*
205 * XDR 32-bit integers
206 */
207 bool_t
xdr_int32_t(XDR * xdrs,int32_t * int32_p)208 xdr_int32_t (XDR * xdrs,
209 int32_t * int32_p)
210 {
211 switch (xdrs->x_op)
212 {
213 case XDR_ENCODE:
214 return XDR_PUTINT32 (xdrs, int32_p);
215
216 case XDR_DECODE:
217 return XDR_GETINT32(xdrs, int32_p);
218
219 case XDR_FREE:
220 return TRUE;
221 }
222 return FALSE;
223 }
224
225 /*
226 * XDR unsigned 32-bit integers
227 */
228 bool_t
xdr_u_int32_t(XDR * xdrs,u_int32_t * u_int32_p)229 xdr_u_int32_t (XDR * xdrs,
230 u_int32_t * u_int32_p)
231 {
232 switch (xdrs->x_op)
233 {
234 case XDR_ENCODE:
235 return XDR_PUTINT32 (xdrs, (int32_t *)u_int32_p);
236
237 case XDR_DECODE:
238 return XDR_GETINT32 (xdrs, (int32_t *)u_int32_p);
239
240 case XDR_FREE:
241 return TRUE;
242 }
243 return FALSE;
244 }
245
246 /*
247 * XDR unsigned 32-bit integers
248 */
249 bool_t
xdr_uint32_t(XDR * xdrs,uint32_t * uint32_p)250 xdr_uint32_t (XDR * xdrs,
251 uint32_t * uint32_p)
252 {
253 switch (xdrs->x_op)
254 {
255 case XDR_ENCODE:
256 return XDR_PUTINT32 (xdrs, (int32_t *)uint32_p);
257
258 case XDR_DECODE:
259 return XDR_GETINT32 (xdrs, (int32_t *)uint32_p);
260
261 case XDR_FREE:
262 return TRUE;
263 }
264 return FALSE;
265 }
266
267 /*
268 * XDR short integers
269 */
270 bool_t
xdr_short(XDR * xdrs,short * sp)271 xdr_short (XDR * xdrs,
272 short * sp)
273 {
274 long l;
275
276 switch (xdrs->x_op)
277 {
278 case XDR_ENCODE:
279 l = (long) *sp;
280 return (XDR_PUTLONG (xdrs, &l));
281
282 case XDR_DECODE:
283 if (!XDR_GETLONG (xdrs, &l))
284 return FALSE;
285 *sp = (short) l;
286 return TRUE;
287
288 case XDR_FREE:
289 return TRUE;
290 }
291 return FALSE;
292 }
293
294 /*
295 * XDR unsigned short integers
296 */
297 bool_t
xdr_u_short(XDR * xdrs,u_short * usp)298 xdr_u_short (XDR * xdrs,
299 u_short * usp)
300 {
301 long l;
302
303 switch (xdrs->x_op)
304 {
305 case XDR_ENCODE:
306 l = (u_long) * usp;
307 return XDR_PUTLONG (xdrs, &l);
308
309 case XDR_DECODE:
310 if (!XDR_GETLONG (xdrs, &l))
311 return FALSE;
312 *usp = (u_short) (u_long) l;
313 return TRUE;
314
315 case XDR_FREE:
316 return TRUE;
317 }
318 return FALSE;
319 }
320
321
322 /*
323 * XDR 16-bit integers
324 */
325 bool_t
xdr_int16_t(XDR * xdrs,int16_t * int16_p)326 xdr_int16_t (XDR * xdrs,
327 int16_t * int16_p)
328 {
329 int32_t t;
330
331 switch (xdrs->x_op)
332 {
333 case XDR_ENCODE:
334 t = (int32_t) *int16_p;
335 return XDR_PUTINT32 (xdrs, &t);
336
337 case XDR_DECODE:
338 if (!XDR_GETINT32 (xdrs, &t))
339 return FALSE;
340 *int16_p = (int16_t) t;
341 return TRUE;
342
343 case XDR_FREE:
344 return TRUE;
345 }
346 return FALSE;
347 }
348
349 /*
350 * XDR unsigned 16-bit integers
351 */
352 bool_t
xdr_u_int16_t(XDR * xdrs,u_int16_t * u_int16_p)353 xdr_u_int16_t (XDR * xdrs,
354 u_int16_t * u_int16_p)
355 {
356 uint32_t ut;
357
358 switch (xdrs->x_op)
359 {
360 case XDR_ENCODE:
361 ut = (uint32_t) *u_int16_p;
362 return XDR_PUTINT32 (xdrs, (int32_t *)&ut);
363
364 case XDR_DECODE:
365 if (!XDR_GETINT32 (xdrs, (int32_t *)&ut))
366 return FALSE;
367 *u_int16_p = (u_int16_t) ut;
368 return TRUE;
369
370 case XDR_FREE:
371 return TRUE;
372 }
373 return FALSE;
374 }
375
376 /*
377 * XDR unsigned 16-bit integers
378 */
379 bool_t
xdr_uint16_t(XDR * xdrs,uint16_t * uint16_p)380 xdr_uint16_t (XDR * xdrs,
381 uint16_t * uint16_p)
382 {
383 uint32_t ut;
384
385 switch (xdrs->x_op)
386 {
387 case XDR_ENCODE:
388 ut = (uint32_t) *uint16_p;
389 return XDR_PUTINT32 (xdrs, (int32_t *)&ut);
390
391 case XDR_DECODE:
392 if (!XDR_GETINT32 (xdrs, (int32_t *)&ut))
393 return FALSE;
394 *uint16_p = (uint16_t) ut;
395 return TRUE;
396
397 case XDR_FREE:
398 return TRUE;
399 }
400 return FALSE;
401 }
402
403 /*
404 * XDR 8-bit integers
405 */
406 bool_t
xdr_int8_t(XDR * xdrs,int8_t * int8_p)407 xdr_int8_t (XDR * xdrs,
408 int8_t * int8_p)
409 {
410 int32_t t;
411
412 switch (xdrs->x_op)
413 {
414 case XDR_ENCODE:
415 t = (int32_t) *int8_p;
416 return XDR_PUTINT32 (xdrs, &t);
417
418 case XDR_DECODE:
419 if (!XDR_GETINT32 (xdrs, &t))
420 return FALSE;
421 *int8_p = (int8_t) t;
422 return TRUE;
423
424 case XDR_FREE:
425 return TRUE;
426 }
427 return FALSE;
428 }
429
430 /*
431 * XDR unsigned 8-bit integers
432 */
433 bool_t
xdr_u_int8_t(XDR * xdrs,u_int8_t * u_int8_p)434 xdr_u_int8_t (XDR * xdrs,
435 u_int8_t * u_int8_p)
436 {
437 uint32_t ut;
438
439 switch (xdrs->x_op)
440 {
441 case XDR_ENCODE:
442 ut = (uint32_t) *u_int8_p;
443 return XDR_PUTINT32 (xdrs, (int32_t *)&ut);
444
445 case XDR_DECODE:
446 if (!XDR_GETINT32 (xdrs, (int32_t *)&ut))
447 return FALSE;
448 *u_int8_p = (u_int8_t) ut;
449 return TRUE;
450
451 case XDR_FREE:
452 return TRUE;
453 }
454 return FALSE;
455 }
456
457 /*
458 * XDR unsigned 8-bit integers
459 */
460 bool_t
xdr_uint8_t(XDR * xdrs,uint8_t * uint8_p)461 xdr_uint8_t (XDR * xdrs,
462 uint8_t * uint8_p)
463 {
464 uint32_t ut;
465
466 switch (xdrs->x_op)
467 {
468 case XDR_ENCODE:
469 ut = (uint32_t) *uint8_p;
470 return XDR_PUTINT32 (xdrs, (int32_t *)&ut);
471
472 case XDR_DECODE:
473 if (!XDR_GETINT32 (xdrs, (int32_t *)&ut))
474 return FALSE;
475 *uint8_p = (uint8_t) ut;
476 return TRUE;
477
478 case XDR_FREE:
479 return TRUE;
480 }
481 return FALSE;
482
483 }
484
485
486 /*
487 * XDR a char
488 */
489 bool_t
xdr_char(XDR * xdrs,char * cp)490 xdr_char (XDR * xdrs,
491 char * cp)
492 {
493 int i;
494
495 i = (*cp);
496 if (!xdr_int (xdrs, &i))
497 return FALSE;
498 *cp = (char) i;
499 return TRUE;
500 }
501
502 /*
503 * XDR an unsigned char
504 */
505 bool_t
xdr_u_char(XDR * xdrs,u_char * ucp)506 xdr_u_char (XDR * xdrs,
507 u_char * ucp)
508 {
509 u_int u;
510
511 u = (*ucp);
512 if (!xdr_u_int (xdrs, &u))
513 return FALSE;
514 *ucp = (u_char) u;
515 return TRUE;
516 }
517
518 /*
519 * XDR booleans
520 */
521 bool_t
xdr_bool(XDR * xdrs,bool_t * bp)522 xdr_bool (XDR * xdrs,
523 bool_t * bp)
524 {
525 long lb;
526
527 switch (xdrs->x_op)
528 {
529 case XDR_ENCODE:
530 lb = *bp ? XDR_TRUE : XDR_FALSE;
531 return XDR_PUTLONG (xdrs, &lb);
532
533 case XDR_DECODE:
534 if (!XDR_GETLONG (xdrs, &lb))
535 return FALSE;
536 *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
537 return TRUE;
538
539 case XDR_FREE:
540 return TRUE;
541 }
542 return FALSE;
543 }
544
545 /*
546 * XDR enumerations
547 */
548 bool_t
xdr_enum(XDR * xdrs,enum_t * ep)549 xdr_enum (XDR * xdrs,
550 enum_t * ep)
551 {
552 enum sizecheck
553 { SIZEVAL }; /* used to find the size of an enum */
554
555 /*
556 * enums are treated as ints
557 */
558 /* LINTED */ if (sizeof (enum sizecheck) == 4)
559 {
560 #if INT_MAX < LONG_MAX
561 long l;
562 switch (xdrs->x_op)
563 {
564 case XDR_ENCODE:
565 l = (long) *ep;
566 return XDR_PUTLONG (xdrs, &l);
567
568 case XDR_DECODE:
569 if (!XDR_GETLONG (xdrs, &l))
570 return FALSE;
571 *ep = l;
572 FALLTHROUGH;
573 case XDR_FREE:
574 return TRUE;
575 }
576 #else
577 return xdr_long (xdrs, (long *) (void *) ep);
578 #endif
579 }
580 else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short))
581 {
582 return (xdr_short (xdrs, (short *) (void *) ep));
583 }
584 return FALSE;
585 }
586
587 /*
588 * XDR opaque data
589 * Allows the specification of a fixed size sequence of opaque bytes.
590 * cp points to the opaque object and cnt gives the byte length.
591 */
592 bool_t
xdr_opaque(XDR * xdrs,caddr_t cp,u_int cnt)593 xdr_opaque (XDR * xdrs,
594 caddr_t cp,
595 u_int cnt)
596 {
597 u_int rndup;
598 static char crud[BYTES_PER_XDR_UNIT];
599
600 /*
601 * if no data we are done
602 */
603 if (cnt == 0)
604 return TRUE;
605
606 /*
607 * round byte count to full xdr units
608 */
609 rndup = cnt % BYTES_PER_XDR_UNIT;
610 if (rndup > 0)
611 rndup = BYTES_PER_XDR_UNIT - rndup;
612
613 switch (xdrs->x_op)
614 {
615 case XDR_DECODE:
616 if (!XDR_GETBYTES (xdrs, cp, cnt))
617 return FALSE;
618 if (rndup == 0)
619 return TRUE;
620 return XDR_GETBYTES (xdrs, (caddr_t) crud, rndup);
621
622 case XDR_ENCODE:
623 if (!XDR_PUTBYTES (xdrs, cp, cnt))
624 return FALSE;
625 if (rndup == 0)
626 return TRUE;
627 return (XDR_PUTBYTES (xdrs, xdr_zero, rndup));
628
629 case XDR_FREE:
630 return TRUE;
631 }
632 return FALSE;
633 }
634
635 /*
636 * XDR counted bytes
637 * *cpp is a pointer to the bytes, *sizep is the count.
638 * If *cpp is NULL maxsize bytes are allocated
639 */
640 bool_t
xdr_bytes(XDR * xdrs,char ** cpp,u_int * sizep,u_int maxsize)641 xdr_bytes (XDR * xdrs,
642 char ** cpp,
643 u_int * sizep,
644 u_int maxsize)
645 {
646 char *sp = *cpp; /* sp is the actual string pointer */
647 u_int nodesize;
648
649 /*
650 * first deal with the length since xdr bytes are counted
651 */
652 if (!xdr_u_int (xdrs, sizep))
653 return FALSE;
654
655 nodesize = *sizep;
656 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE))
657 return FALSE;
658
659 /*
660 * now deal with the actual bytes
661 */
662 switch (xdrs->x_op)
663 {
664 case XDR_DECODE:
665 if (nodesize == 0)
666 return TRUE;
667 if (sp == NULL)
668 *cpp = sp = mem_alloc (nodesize);
669 if (sp == NULL)
670 {
671 xdr_warnx ("xdr_bytes: out of memory");
672 errno = ENOMEM;
673 return FALSE;
674 }
675 FALLTHROUGH;
676
677 case XDR_ENCODE:
678 return xdr_opaque (xdrs, sp, nodesize);
679
680 case XDR_FREE:
681 if (sp != NULL)
682 {
683 mem_free (sp, nodesize);
684 *cpp = NULL;
685 }
686 return TRUE;
687 }
688 return FALSE;
689 }
690
691 /*
692 * Implemented here due to commonality of the object.
693 */
694 bool_t
xdr_netobj(XDR * xdrs,struct netobj * np)695 xdr_netobj (XDR * xdrs,
696 struct netobj * np)
697 {
698 return (xdr_bytes (xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
699 }
700
701 /*
702 * XDR a descriminated union
703 * Support routine for discriminated unions.
704 * You create an array of xdrdiscrim structures, terminated with
705 * an entry with a null procedure pointer. The routine gets
706 * the discriminant value and then searches the array of xdrdiscrims
707 * looking for that value. It calls the procedure given in the xdrdiscrim
708 * to handle the discriminant. If there is no specific routine a default
709 * routine may be called.
710 * If there is no specific or default routine an error is returned.
711 * dscmp: enum to decide which arm to work on
712 * unp: ptr to the union itself
713 * choices: ptr to array of [value, xdr proc] for each arm
714 * dfault: default xdr routine
715 */
716 bool_t
xdr_union(XDR * xdrs,enum_t * dscmp,char * unp,const struct xdr_discrim * choices,xdrproc_t dfault)717 xdr_union (XDR * xdrs,
718 enum_t * dscmp,
719 char * unp,
720 const struct xdr_discrim * choices,
721 xdrproc_t dfault)
722 {
723 enum_t dscm;
724
725 /*
726 * we deal with the discriminator; it's an enum
727 */
728 if (!xdr_enum (xdrs, dscmp))
729 return FALSE;
730
731 dscm = *dscmp;
732
733 /*
734 * search choices for a value that matches the discriminator.
735 * if we find one, execute the xdr routine for that value.
736 */
737 for (; choices->proc != NULL_xdrproc_t; choices++)
738 {
739 if (choices->value == dscm)
740 return ((*(choices->proc)) (xdrs, unp, LASTUNSIGNED));
741 }
742
743 /*
744 * no match - execute the default xdr routine if there is one
745 */
746 return ((dfault == NULL_xdrproc_t) ? FALSE : (*dfault) (xdrs, unp, LASTUNSIGNED));
747 }
748
749
750 /*
751 * Non-portable xdr primitives.
752 * Care should be taken when moving these routines to new architectures.
753 */
754
755
756 /*
757 * XDR null terminated ASCII strings
758 * xdr_string deals with "C strings" - arrays of bytes that are
759 * terminated by a NULL character. The parameter cpp references a
760 * pointer to storage; If the pointer is null, then the necessary
761 * storage is allocated. The last parameter is the max allowed length
762 * of the string as specified by a protocol.
763 */
764 bool_t
xdr_string(XDR * xdrs,char ** cpp,u_int maxsize)765 xdr_string (XDR * xdrs,
766 char ** cpp,
767 u_int maxsize)
768 {
769 char *sp = *cpp; /* sp is the actual string pointer */
770 u_int size = 0;
771 u_int nodesize;
772
773 /*
774 * first deal with the length since xdr strings are counted-strings
775 */
776 switch (xdrs->x_op)
777 {
778 case XDR_FREE:
779 if (sp == NULL)
780 return TRUE; /* already free */
781
782 FALLTHROUGH;
783 case XDR_ENCODE:
784 if (sp == NULL)
785 return FALSE;
786
787 size = strlen (sp);
788 break;
789 case XDR_DECODE:
790 break;
791 }
792 if (!xdr_u_int (xdrs, &size))
793 return FALSE;
794
795 if (size > maxsize)
796 return FALSE;
797
798 nodesize = size + 1;
799 if (nodesize == 0)
800 {
801 /* This means an overflow. It a bug in the caller which
802 * provided a too large maxsize but nevertheless catch it
803 * here.
804 */
805 return FALSE;
806 }
807
808 /*
809 * now deal with the actual bytes
810 */
811 switch (xdrs->x_op)
812 {
813
814 case XDR_DECODE:
815 if (sp == NULL)
816 *cpp = sp = mem_alloc (nodesize);
817 if (sp == NULL)
818 {
819 xdr_warnx ("xdr_string: out of memory");
820 errno = ENOMEM;
821 return FALSE;
822 }
823 sp[size] = 0;
824 FALLTHROUGH;
825
826 case XDR_ENCODE:
827 return xdr_opaque (xdrs, sp, size);
828
829 case XDR_FREE:
830 mem_free (sp, nodesize);
831 *cpp = NULL;
832 return TRUE;
833 }
834 return FALSE;
835 }
836
837 /*
838 * Wrapper for xdr_string that can be called directly from
839 * routines like clnt_call
840 */
841 bool_t
xdr_wrapstring(XDR * xdrs,char ** cpp)842 xdr_wrapstring (XDR * xdrs,
843 char ** cpp)
844 {
845 return xdr_string (xdrs, cpp, LASTUNSIGNED);
846 }
847
848
849 #if defined(___int64_t_defined)
850 /*
851 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
852 * are in the "non-portable" section because they require that a `long long'
853 * be a 64-bit type.
854 *
855 * --thorpej@netbsd.org, November 30, 1999
856 */
857
858 /*
859 * XDR 64-bit integers
860 */
861 bool_t
xdr_int64_t(XDR * xdrs,int64_t * llp)862 xdr_int64_t (XDR * xdrs,
863 int64_t * llp)
864 {
865 int32_t t1, t2;
866
867 switch (xdrs->x_op)
868 {
869 case XDR_ENCODE:
870 t1 = (int32_t) ((*llp) >> 32);
871 t2 = (int32_t) (*llp);
872 return (XDR_PUTINT32 (xdrs, &t1) && XDR_PUTINT32 (xdrs, &t2));
873
874 case XDR_DECODE:
875 if (!XDR_GETINT32 (xdrs, &t1) || !XDR_GETINT32 (xdrs, &t2))
876 return FALSE;
877 *llp = ((int64_t) t1) << 32;
878 *llp |= (uint32_t) t2;
879 return TRUE;
880
881 case XDR_FREE:
882 return TRUE;
883 }
884 return FALSE;
885 }
886
887
888 /*
889 * XDR unsigned 64-bit integers
890 */
891 bool_t
xdr_u_int64_t(XDR * xdrs,u_int64_t * ullp)892 xdr_u_int64_t (XDR * xdrs,
893 u_int64_t * ullp)
894 {
895 uint32_t t1, t2;
896
897 switch (xdrs->x_op)
898 {
899 case XDR_ENCODE:
900 t1 = (uint32_t) ((*ullp) >> 32);
901 t2 = (uint32_t) (*ullp);
902 return (XDR_PUTINT32 (xdrs, (int32_t *)&t1) &&
903 XDR_PUTINT32 (xdrs, (int32_t *)&t2));
904
905 case XDR_DECODE:
906 if (!XDR_GETINT32 (xdrs, (int32_t *)&t1) ||
907 !XDR_GETINT32 (xdrs, (int32_t *)&t2))
908 return FALSE;
909 *ullp = ((u_int64_t) t1) << 32;
910 *ullp |= t2;
911 return TRUE;
912
913 case XDR_FREE:
914 return TRUE;
915 }
916 return FALSE;
917 }
918
919 /*
920 * XDR unsigned 64-bit integers
921 */
922 bool_t
xdr_uint64_t(XDR * xdrs,uint64_t * ullp)923 xdr_uint64_t (XDR * xdrs,
924 uint64_t * ullp)
925 {
926 uint32_t t1, t2;
927
928 switch (xdrs->x_op)
929 {
930 case XDR_ENCODE:
931 t1 = (uint32_t) ((*ullp) >> 32);
932 t2 = (uint32_t) (*ullp);
933 return (XDR_PUTINT32 (xdrs, (int32_t *)&t1) &&
934 XDR_PUTINT32 (xdrs, (int32_t *)&t2));
935
936 case XDR_DECODE:
937 if (!XDR_GETINT32 (xdrs, (int32_t *)&t1) ||
938 !XDR_GETINT32 (xdrs, (int32_t *)&t2))
939 return FALSE;
940 *ullp = ((uint64_t) t1) << 32;
941 *ullp |= t2;
942 return TRUE;
943
944 case XDR_FREE:
945 return TRUE;
946 }
947 return FALSE;
948 }
949
950
951 /*
952 * XDR hypers
953 */
954 bool_t
xdr_hyper(XDR * xdrs,quad_t * llp)955 xdr_hyper (XDR * xdrs,
956 quad_t * llp)
957 {
958 /*
959 * Don't bother open-coding this; it's a fair amount of code. Just
960 * call xdr_int64_t().
961 */
962 return (xdr_int64_t (xdrs, (int64_t *) llp));
963 }
964
965
966 /*
967 * XDR unsigned hypers
968 */
969 bool_t
xdr_u_hyper(XDR * xdrs,u_quad_t * ullp)970 xdr_u_hyper (XDR * xdrs,
971 u_quad_t * ullp)
972 {
973 /*
974 * Don't bother open-coding this; it's a fair amount of code. Just
975 * call xdr_uint64_t().
976 */
977 return (xdr_uint64_t (xdrs, (uint64_t *) ullp));
978 }
979
980
981 /*
982 * XDR longlong_t's
983 */
984 bool_t
xdr_longlong_t(XDR * xdrs,quad_t * llp)985 xdr_longlong_t (XDR * xdrs,
986 quad_t * llp)
987 {
988 /*
989 * Don't bother open-coding this; it's a fair amount of code. Just
990 * call xdr_int64_t().
991 */
992 return (xdr_int64_t (xdrs, (int64_t *) llp));
993 }
994
995
996 /*
997 * XDR u_longlong_t's
998 */
999 bool_t
xdr_u_longlong_t(XDR * xdrs,u_quad_t * ullp)1000 xdr_u_longlong_t (XDR * xdrs,
1001 u_quad_t *ullp)
1002 {
1003 /*
1004 * Don't bother open-coding this; it's a fair amount of code. Just
1005 * call xdr_u_int64_t().
1006 */
1007 return (xdr_uint64_t (xdrs, (uint64_t *) ullp));
1008 }
1009
1010 #endif /* ___int64_t_defined */
1011
1012