Reinitialize _create_xid state after fork.
[platform/upstream/glibc.git] / sunrpc / xdr.c
1 /*
2  * xdr.c, Generic XDR routines implementation.
3  *
4  * Copyright (C) 1986, Sun Microsystems, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  *       copyright notice, this list of conditions and the following
14  *       disclaimer in the documentation and/or other materials
15  *       provided with the distribution.
16  *     * Neither the name of Sun Microsystems, Inc. nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * These are the "generic" xdr routines used to serialize and de-serialize
34  * most common data items.  See xdr.h for more info on the interface to
35  * xdr.
36  */
37
38 #include <stdio.h>
39 #include <limits.h>
40 #include <string.h>
41 #include <libintl.h>
42
43 #include <rpc/types.h>
44 #include <rpc/xdr.h>
45
46 #ifdef USE_IN_LIBIO
47 # include <wchar.h>
48 #endif
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
67 xdr_free (xdrproc_t proc, char *objp)
68 {
69   XDR x;
70
71   x.x_op = XDR_FREE;
72   (*proc) (&x, objp);
73 }
74
75 /*
76  * XDR nothing
77  */
78 bool_t
79 xdr_void (void)
80 {
81   return TRUE;
82 }
83 INTDEF(xdr_void)
84
85 /*
86  * XDR integers
87  */
88 bool_t
89 xdr_int (XDR *xdrs, int *ip)
90 {
91
92 #if INT_MAX < LONG_MAX
93   long l;
94
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     case XDR_FREE:
108       return TRUE;
109     }
110   return FALSE;
111 #elif INT_MAX == LONG_MAX
112   return INTUSE(xdr_long) (xdrs, (long *) ip);
113 #elif INT_MAX == SHRT_MAX
114   return INTUSE(xdr_short) (xdrs, (short *) ip);
115 #else
116 #error unexpected integer sizes in_xdr_int()
117 #endif
118 }
119 INTDEF(xdr_int)
120
121 /*
122  * XDR unsigned integers
123  */
124 bool_t
125 xdr_u_int (XDR *xdrs, u_int *up)
126 {
127 #if UINT_MAX < ULONG_MAX
128   long l;
129
130   switch (xdrs->x_op)
131     {
132     case XDR_ENCODE:
133       l = (u_long) * up;
134       return XDR_PUTLONG (xdrs, &l);
135
136     case XDR_DECODE:
137       if (!XDR_GETLONG (xdrs, &l))
138         {
139           return FALSE;
140         }
141       *up = (u_int) (u_long) l;
142     case XDR_FREE:
143       return TRUE;
144     }
145   return FALSE;
146 #elif UINT_MAX == ULONG_MAX
147   return INTUSE(xdr_u_long) (xdrs, (u_long *) up);
148 #elif UINT_MAX == USHRT_MAX
149   return INTUSE(xdr_short) (xdrs, (short *) up);
150 #else
151 #error unexpected integer sizes in_xdr_u_int()
152 #endif
153 }
154 INTDEF(xdr_u_int)
155
156 /*
157  * XDR long integers
158  * The definition of xdr_long() is kept for backward
159  * compatibility. Instead xdr_int() should be used.
160  */
161 bool_t
162 xdr_long (XDR *xdrs, long *lp)
163 {
164
165   if (xdrs->x_op == XDR_ENCODE
166       && (sizeof (int32_t) == sizeof (long)
167           || (int32_t) *lp == *lp))
168     return XDR_PUTLONG (xdrs, lp);
169
170   if (xdrs->x_op == XDR_DECODE)
171     return XDR_GETLONG (xdrs, lp);
172
173   if (xdrs->x_op == XDR_FREE)
174     return TRUE;
175
176   return FALSE;
177 }
178 INTDEF(xdr_long)
179
180 /*
181  * XDR unsigned long integers
182  * The definition of xdr_u_long() is kept for backward
183  * compatibility. Instead xdr_u_int() should be used.
184  */
185 bool_t
186 xdr_u_long (XDR *xdrs, u_long *ulp)
187 {
188   switch (xdrs->x_op)
189     {
190     case XDR_DECODE:
191       {
192         long int tmp;
193
194         if (XDR_GETLONG (xdrs, &tmp) == FALSE)
195           return FALSE;
196
197         *ulp = (uint32_t) tmp;
198         return TRUE;
199       }
200
201     case XDR_ENCODE:
202       if (sizeof (uint32_t) != sizeof (u_long)
203           && (uint32_t) *ulp != *ulp)
204         return FALSE;
205
206       return XDR_PUTLONG (xdrs, (long *) ulp);
207
208     case XDR_FREE:
209       return TRUE;
210     }
211   return FALSE;
212 }
213 INTDEF(xdr_u_long)
214
215 /*
216  * XDR hyper integers
217  * same as xdr_u_hyper - open coded to save a proc call!
218  */
219 bool_t
220 xdr_hyper (XDR *xdrs, quad_t *llp)
221 {
222   long int t1, t2;
223
224   if (xdrs->x_op == XDR_ENCODE)
225     {
226       t1 = (long) ((*llp) >> 32);
227       t2 = (long) (*llp);
228       return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2));
229     }
230
231   if (xdrs->x_op == XDR_DECODE)
232     {
233       if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2))
234         return FALSE;
235       *llp = ((quad_t) t1) << 32;
236       *llp |= (uint32_t) t2;
237       return TRUE;
238     }
239
240   if (xdrs->x_op == XDR_FREE)
241     return TRUE;
242
243   return FALSE;
244 }
245 INTDEF(xdr_hyper)
246
247
248 /*
249  * XDR hyper integers
250  * same as xdr_hyper - open coded to save a proc call!
251  */
252 bool_t
253 xdr_u_hyper (XDR *xdrs, u_quad_t *ullp)
254 {
255   long int t1, t2;
256
257   if (xdrs->x_op == XDR_ENCODE)
258     {
259       t1 = (unsigned long) ((*ullp) >> 32);
260       t2 = (unsigned long) (*ullp);
261       return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2));
262     }
263
264   if (xdrs->x_op == XDR_DECODE)
265     {
266       if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2))
267         return FALSE;
268       *ullp = ((u_quad_t) t1) << 32;
269       *ullp |= (uint32_t) t2;
270       return TRUE;
271     }
272
273   if (xdrs->x_op == XDR_FREE)
274     return TRUE;
275
276   return FALSE;
277 }
278 INTDEF(xdr_u_hyper)
279
280 bool_t
281 xdr_longlong_t (XDR *xdrs, quad_t *llp)
282 {
283   return INTUSE(xdr_hyper) (xdrs, llp);
284 }
285
286 bool_t
287 xdr_u_longlong_t (XDR *xdrs, u_quad_t *ullp)
288 {
289   return INTUSE(xdr_u_hyper) (xdrs, ullp);
290 }
291
292 /*
293  * XDR short integers
294  */
295 bool_t
296 xdr_short (XDR *xdrs, short *sp)
297 {
298   long l;
299
300   switch (xdrs->x_op)
301     {
302     case XDR_ENCODE:
303       l = (long) *sp;
304       return XDR_PUTLONG (xdrs, &l);
305
306     case XDR_DECODE:
307       if (!XDR_GETLONG (xdrs, &l))
308         {
309           return FALSE;
310         }
311       *sp = (short) l;
312       return TRUE;
313
314     case XDR_FREE:
315       return TRUE;
316     }
317   return FALSE;
318 }
319 INTDEF(xdr_short)
320
321 /*
322  * XDR unsigned short integers
323  */
324 bool_t
325 xdr_u_short (XDR *xdrs, u_short *usp)
326 {
327   long l;
328
329   switch (xdrs->x_op)
330     {
331     case XDR_ENCODE:
332       l = (u_long) * usp;
333       return XDR_PUTLONG (xdrs, &l);
334
335     case XDR_DECODE:
336       if (!XDR_GETLONG (xdrs, &l))
337         {
338           return FALSE;
339         }
340       *usp = (u_short) (u_long) l;
341       return TRUE;
342
343     case XDR_FREE:
344       return TRUE;
345     }
346   return FALSE;
347 }
348 INTDEF(xdr_u_short)
349
350
351 /*
352  * XDR a char
353  */
354 bool_t
355 xdr_char (XDR *xdrs, char *cp)
356 {
357   int i;
358
359   i = (*cp);
360   if (!INTUSE(xdr_int) (xdrs, &i))
361     {
362       return FALSE;
363     }
364   *cp = i;
365   return TRUE;
366 }
367
368 /*
369  * XDR an unsigned char
370  */
371 bool_t
372 xdr_u_char (XDR *xdrs, u_char *cp)
373 {
374   u_int u;
375
376   u = (*cp);
377   if (!INTUSE(xdr_u_int) (xdrs, &u))
378     {
379       return FALSE;
380     }
381   *cp = u;
382   return TRUE;
383 }
384
385 /*
386  * XDR booleans
387  */
388 bool_t
389 xdr_bool (XDR *xdrs, bool_t *bp)
390 {
391   long lb;
392
393   switch (xdrs->x_op)
394     {
395     case XDR_ENCODE:
396       lb = *bp ? XDR_TRUE : XDR_FALSE;
397       return XDR_PUTLONG (xdrs, &lb);
398
399     case XDR_DECODE:
400       if (!XDR_GETLONG (xdrs, &lb))
401         {
402           return FALSE;
403         }
404       *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
405       return TRUE;
406
407     case XDR_FREE:
408       return TRUE;
409     }
410   return FALSE;
411 }
412 INTDEF(xdr_bool)
413
414 /*
415  * XDR enumerations
416  */
417 bool_t
418 xdr_enum (XDR *xdrs, enum_t *ep)
419 {
420   enum sizecheck
421     {
422       SIZEVAL
423     };                          /* used to find the size of an enum */
424
425   /*
426    * enums are treated as ints
427    */
428   if (sizeof (enum sizecheck) == 4)
429     {
430 #if INT_MAX < LONG_MAX
431       long l;
432
433       switch (xdrs->x_op)
434         {
435         case XDR_ENCODE:
436           l = *ep;
437           return XDR_PUTLONG (xdrs, &l);
438
439         case XDR_DECODE:
440           if (!XDR_GETLONG (xdrs, &l))
441             {
442               return FALSE;
443             }
444           *ep = l;
445         case XDR_FREE:
446           return TRUE;
447
448         }
449       return FALSE;
450 #else
451       return INTUSE(xdr_long) (xdrs, (long *) ep);
452 #endif
453     }
454   else if (sizeof (enum sizecheck) == sizeof (short))
455     {
456       return INTUSE(xdr_short) (xdrs, (short *) ep);
457     }
458   else
459     {
460       return FALSE;
461     }
462 }
463 INTDEF(xdr_enum)
464
465 /*
466  * XDR opaque data
467  * Allows the specification of a fixed size sequence of opaque bytes.
468  * cp points to the opaque object and cnt gives the byte length.
469  */
470 bool_t
471 xdr_opaque (XDR *xdrs, caddr_t cp, u_int cnt)
472 {
473   u_int rndup;
474   static char crud[BYTES_PER_XDR_UNIT];
475
476   /*
477    * if no data we are done
478    */
479   if (cnt == 0)
480     return TRUE;
481
482   /*
483    * round byte count to full xdr units
484    */
485   rndup = cnt % BYTES_PER_XDR_UNIT;
486   if (rndup > 0)
487     rndup = BYTES_PER_XDR_UNIT - rndup;
488
489   switch (xdrs->x_op)
490     {
491     case XDR_DECODE:
492       if (!XDR_GETBYTES (xdrs, cp, cnt))
493         {
494           return FALSE;
495         }
496       if (rndup == 0)
497         return TRUE;
498       return XDR_GETBYTES (xdrs, (caddr_t)crud, rndup);
499
500     case XDR_ENCODE:
501       if (!XDR_PUTBYTES (xdrs, cp, cnt))
502         {
503           return FALSE;
504         }
505       if (rndup == 0)
506         return TRUE;
507       return XDR_PUTBYTES (xdrs, xdr_zero, rndup);
508
509     case XDR_FREE:
510       return TRUE;
511     }
512   return FALSE;
513 }
514 INTDEF(xdr_opaque)
515
516 /*
517  * XDR counted bytes
518  * *cpp is a pointer to the bytes, *sizep is the count.
519  * If *cpp is NULL maxsize bytes are allocated
520  */
521 bool_t
522 xdr_bytes (xdrs, cpp, sizep, maxsize)
523      XDR *xdrs;
524      char **cpp;
525      u_int *sizep;
526      u_int maxsize;
527 {
528   char *sp = *cpp;      /* sp is the actual string pointer */
529   u_int nodesize;
530
531   /*
532    * first deal with the length since xdr bytes are counted
533    */
534   if (!INTUSE(xdr_u_int) (xdrs, sizep))
535     {
536       return FALSE;
537     }
538   nodesize = *sizep;
539   if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE))
540     {
541       return FALSE;
542     }
543
544   /*
545    * now deal with the actual bytes
546    */
547   switch (xdrs->x_op)
548     {
549     case XDR_DECODE:
550       if (nodesize == 0)
551         {
552           return TRUE;
553         }
554       if (sp == NULL)
555         {
556           *cpp = sp = (char *) mem_alloc (nodesize);
557         }
558       if (sp == NULL)
559         {
560           (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
561           return FALSE;
562         }
563       /* fall into ... */
564
565     case XDR_ENCODE:
566       return INTUSE(xdr_opaque) (xdrs, sp, nodesize);
567
568     case XDR_FREE:
569       if (sp != NULL)
570         {
571           mem_free (sp, nodesize);
572           *cpp = NULL;
573         }
574       return TRUE;
575     }
576   return FALSE;
577 }
578 INTDEF(xdr_bytes)
579
580 /*
581  * Implemented here due to commonality of the object.
582  */
583 bool_t
584 xdr_netobj (xdrs, np)
585      XDR *xdrs;
586      struct netobj *np;
587 {
588
589   return INTUSE(xdr_bytes) (xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ);
590 }
591 INTDEF(xdr_netobj)
592
593 /*
594  * XDR a discriminated union
595  * Support routine for discriminated unions.
596  * You create an array of xdrdiscrim structures, terminated with
597  * an entry with a null procedure pointer.  The routine gets
598  * the discriminant value and then searches the array of xdrdiscrims
599  * looking for that value.  It calls the procedure given in the xdrdiscrim
600  * to handle the discriminant.  If there is no specific routine a default
601  * routine may be called.
602  * If there is no specific or default routine an error is returned.
603  */
604 bool_t
605 xdr_union (xdrs, dscmp, unp, choices, dfault)
606      XDR *xdrs;
607      enum_t *dscmp;             /* enum to decide which arm to work on */
608      char *unp;                 /* the union itself */
609      const struct xdr_discrim *choices; /* [value, xdr proc] for each arm */
610      xdrproc_t dfault;          /* default xdr routine */
611 {
612   enum_t dscm;
613
614   /*
615    * we deal with the discriminator;  it's an enum
616    */
617   if (!INTUSE(xdr_enum) (xdrs, dscmp))
618     {
619       return FALSE;
620     }
621   dscm = *dscmp;
622
623   /*
624    * search choices for a value that matches the discriminator.
625    * if we find one, execute the xdr routine for that value.
626    */
627   for (; choices->proc != NULL_xdrproc_t; choices++)
628     {
629       if (choices->value == dscm)
630         return (*(choices->proc)) (xdrs, unp, LASTUNSIGNED);
631     }
632
633   /*
634    * no match - execute the default xdr routine if there is one
635    */
636   return ((dfault == NULL_xdrproc_t) ? FALSE :
637           (*dfault) (xdrs, unp, LASTUNSIGNED));
638 }
639 INTDEF(xdr_union)
640
641
642 /*
643  * Non-portable xdr primitives.
644  * Care should be taken when moving these routines to new architectures.
645  */
646
647
648 /*
649  * XDR null terminated ASCII strings
650  * xdr_string deals with "C strings" - arrays of bytes that are
651  * terminated by a NULL character.  The parameter cpp references a
652  * pointer to storage; If the pointer is null, then the necessary
653  * storage is allocated.  The last parameter is the max allowed length
654  * of the string as specified by a protocol.
655  */
656 bool_t
657 xdr_string (xdrs, cpp, maxsize)
658      XDR *xdrs;
659      char **cpp;
660      u_int maxsize;
661 {
662   char *sp = *cpp;      /* sp is the actual string pointer */
663   u_int size;
664   u_int nodesize;
665
666   /*
667    * first deal with the length since xdr strings are counted-strings
668    */
669   switch (xdrs->x_op)
670     {
671     case XDR_FREE:
672       if (sp == NULL)
673         {
674           return TRUE;          /* already free */
675         }
676       /* fall through... */
677     case XDR_ENCODE:
678       if (sp == NULL)
679         return FALSE;
680       size = strlen (sp);
681       break;
682     case XDR_DECODE:
683       break;
684     }
685   if (!INTUSE(xdr_u_int) (xdrs, &size))
686     {
687       return FALSE;
688     }
689   if (size > maxsize)
690     {
691       return FALSE;
692     }
693   nodesize = size + 1;
694   if (nodesize == 0)
695     {
696       /* This means an overflow.  It a bug in the caller which
697          provided a too large maxsize but nevertheless catch it
698          here.  */
699       return FALSE;
700     }
701
702   /*
703    * now deal with the actual bytes
704    */
705   switch (xdrs->x_op)
706     {
707     case XDR_DECODE:
708       if (sp == NULL)
709         *cpp = sp = (char *) mem_alloc (nodesize);
710       if (sp == NULL)
711         {
712           (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
713           return FALSE;
714         }
715       sp[size] = 0;
716       /* fall into ... */
717
718     case XDR_ENCODE:
719       return INTUSE(xdr_opaque) (xdrs, sp, size);
720
721     case XDR_FREE:
722       mem_free (sp, nodesize);
723       *cpp = NULL;
724       return TRUE;
725     }
726   return FALSE;
727 }
728 INTDEF(xdr_string)
729
730 /*
731  * Wrapper for xdr_string that can be called directly from
732  * routines like clnt_call
733  */
734 bool_t
735 xdr_wrapstring (xdrs, cpp)
736      XDR *xdrs;
737      char **cpp;
738 {
739   if (INTUSE(xdr_string) (xdrs, cpp, LASTUNSIGNED))
740     {
741       return TRUE;
742     }
743   return FALSE;
744 }