source: rtems-libbsd/services/librpc/src/xdr/xdr.c @ e599318

4.115-freebsd-12freebsd-9.3
Last change on this file since e599318 was e599318, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 9, 2013 at 8:52:54 PM

Update files to match FreeBSD layout

Add compatibility with Newlib header files. Some FreeBSD header files
are mapped by the translation script:

o rtems/bsd/sys/_types.h
o rtems/bsd/sys/errno.h
o rtems/bsd/sys/lock.h
o rtems/bsd/sys/param.h
o rtems/bsd/sys/resource.h
o rtems/bsd/sys/time.h
o rtems/bsd/sys/timespec.h
o rtems/bsd/sys/types.h
o rtems/bsd/sys/unistd.h

It is now possible to include <sys/socket.h> directly for example.

Generate one Makefile which builds everything including tests.

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