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           __PICOLIBC_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       __PICOLIBC_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       __PICOLIBC_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       __PICOLIBC_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