source: rtems/cpukit/librpc/src/xdr/xdr.c @ dab2d6eb

4.104.114.84.95
Last change on this file since dab2d6eb was dab2d6eb, checked in by Ralf Corsepius <ralf.corsepius@…>, on Jan 8, 2005 at 6:01:35 AM

2005-01-07 Ralf Corsepius <ralf.corsepius@…>

  • librpc/include/rpc/auth_des.h, librpc/include/rpc/xdr.h, librpc/src/rpc/auth_des.c, librpc/src/rpc/auth_unix.c, librpc/src/rpc/rpc_prot.c, librpc/src/xdr/xdr.c: Misc. ansi-fications, misc. updates from FreeBSD.
  • Property mode set to 100644
File size: 14.8 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#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49
50#include <rpc/types.h>
51#include <rpc/xdr.h>
52
53#if defined(__rtems__)
54#define warnx(msg) fprintf(stderr, msg "\n");
55#endif
56
57/*
58 * constants specific to the xdr "protocol"
59 */
60#define XDR_FALSE       ((long) 0)
61#define XDR_TRUE        ((long) 1)
62#define LASTUNSIGNED    ((u_int) 0-1)
63
64/*
65 * for unit alignment
66 */
67static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
68
69/*
70 * Free a data structure using XDR
71 * Not a filter, but a convenient utility nonetheless
72 */
73void
74xdr_free(proc, objp)
75        xdrproc_t proc;
76        char *objp;
77{
78        XDR x;
79
80        x.x_op = XDR_FREE;
81        (*proc)(&x, objp);
82}
83
84/*
85 * XDR nothing
86 */
87bool_t
88xdr_void(/* xdrs, addr */)
89        /* XDR *xdrs; */
90        /* caddr_t addr; */
91{
92
93        return (TRUE);
94}
95
96
97/*
98 * XDR integers
99 */
100bool_t
101xdr_int(xdrs, ip)
102        XDR *xdrs;
103        int *ip;
104{
105        long l;
106
107        switch (xdrs->x_op) {
108
109        case XDR_ENCODE:
110                l = (long) *ip;
111                return (XDR_PUTLONG(xdrs, &l));
112
113        case XDR_DECODE:
114                if (!XDR_GETLONG(xdrs, &l)) {
115                        return (FALSE);
116                }
117                *ip = (int) l;
118                return (TRUE);
119
120        case XDR_FREE:
121                return (TRUE);
122        }
123        /* NOTREACHED */
124        return (FALSE);
125}
126
127/*
128 * XDR unsigned integers
129 */
130bool_t
131xdr_u_int(xdrs, up)
132        XDR *xdrs;
133        u_int *up;
134{
135        u_long l;
136
137        switch (xdrs->x_op) {
138
139        case XDR_ENCODE:
140                l = (u_long) *up;
141                return (XDR_PUTLONG(xdrs, (long *)&l));
142
143        case XDR_DECODE:
144                if (!XDR_GETLONG(xdrs, (long *)&l)) {
145                        return (FALSE);
146                }
147                *up = (u_int) l;
148                return (TRUE);
149
150        case XDR_FREE:
151                return (TRUE);
152        }
153        /* NOTREACHED */
154        return (FALSE);
155}
156
157
158/*
159 * XDR long integers
160 * same as xdr_u_long - open coded to save a proc call!
161 */
162bool_t
163xdr_long(xdrs, lp)
164        XDR *xdrs;
165        long *lp;
166{
167        switch (xdrs->x_op) {
168        case XDR_ENCODE:
169                return (XDR_PUTLONG(xdrs, lp));
170        case XDR_DECODE:
171                return (XDR_GETLONG(xdrs, lp));
172        case XDR_FREE:
173                return (TRUE);
174        }
175        /* NOTREACHED */
176        return (FALSE);
177}
178
179/*
180 * XDR unsigned long integers
181 * same as xdr_long - open coded to save a proc call!
182 */
183bool_t
184xdr_u_long(xdrs, ulp)
185        XDR *xdrs;
186        u_long *ulp;
187{
188        switch (xdrs->x_op) {
189        case XDR_ENCODE:
190                return (XDR_PUTLONG(xdrs, (long *)ulp));
191        case XDR_DECODE:
192                return (XDR_GETLONG(xdrs, (long *)ulp));
193        case XDR_FREE:
194                return (TRUE);
195        }
196        /* NOTREACHED */
197        return (FALSE);
198}
199
200
201/*
202 * XDR 32-bit integers
203 * same as xdr_u_int32_t - open coded to save a proc call!
204 */
205bool_t
206xdr_int32_t(xdrs, int32_p)
207        XDR *xdrs;
208        int32_t *int32_p;
209{
210        long l;
211
212        switch (xdrs->x_op) {
213
214        case XDR_ENCODE:
215                l = (long) *int32_p;
216                return (XDR_PUTLONG(xdrs, &l));
217
218        case XDR_DECODE:
219                if (!XDR_GETLONG(xdrs, &l)) {
220                        return (FALSE);
221                }
222                *int32_p = (int32_t) l;
223                return (TRUE);
224
225        case XDR_FREE:
226                return (TRUE);
227        }
228        /* NOTREACHED */
229        return (FALSE);
230}
231
232/*
233 * XDR unsigned 32-bit integers
234 * same as xdr_int32_t - open coded to save a proc call!
235 */
236bool_t
237xdr_u_int32_t(xdrs, u_int32_p)
238        XDR *xdrs;
239        u_int32_t *u_int32_p;
240{
241        u_long l;
242
243        switch (xdrs->x_op) {
244
245        case XDR_ENCODE:
246                l = (u_long) *u_int32_p;
247                return (XDR_PUTLONG(xdrs, (long *)&l));
248
249        case XDR_DECODE:
250                if (!XDR_GETLONG(xdrs, (long *)&l)) {
251                        return (FALSE);
252                }
253                *u_int32_p = (u_int32_t) l;
254                return (TRUE);
255
256        case XDR_FREE:
257                return (TRUE);
258        }
259        return (FALSE);
260}
261
262/*
263 * XDR short integers
264 */
265bool_t
266xdr_short(xdrs, sp)
267        XDR *xdrs;
268        short *sp;
269{
270        long l;
271
272        switch (xdrs->x_op) {
273
274        case XDR_ENCODE:
275                l = (long) *sp;
276                return (XDR_PUTLONG(xdrs, &l));
277
278        case XDR_DECODE:
279                if (!XDR_GETLONG(xdrs, &l)) {
280                        return (FALSE);
281                }
282                *sp = (short) l;
283                return (TRUE);
284
285        case XDR_FREE:
286                return (TRUE);
287        }
288        /* NOTREACHED */
289        return (FALSE);
290}
291
292/*
293 * XDR unsigned short integers
294 */
295bool_t
296xdr_u_short(xdrs, usp)
297        XDR *xdrs;
298        u_short *usp;
299{
300        u_long l;
301
302        switch (xdrs->x_op) {
303
304        case XDR_ENCODE:
305                l = (u_long) *usp;
306                return (XDR_PUTLONG(xdrs, (long *)&l));
307
308        case XDR_DECODE:
309                if (!XDR_GETLONG(xdrs, (long *)&l)) {
310                        return (FALSE);
311                }
312                *usp = (u_short) l;
313                return (TRUE);
314
315        case XDR_FREE:
316                return (TRUE);
317        }
318        /* NOTREACHED */
319        return (FALSE);
320}
321
322
323/*
324 * XDR 16-bit integers
325 */
326bool_t
327xdr_int16_t(xdrs, int16_p)
328        XDR *xdrs;
329        int16_t *int16_p;
330{
331        long l;
332
333        switch (xdrs->x_op) {
334
335        case XDR_ENCODE:
336                l = (long) *int16_p;
337                return (XDR_PUTLONG(xdrs, &l));
338
339        case XDR_DECODE:
340                if (!XDR_GETLONG(xdrs, &l)) {
341                        return (FALSE);
342                }
343                *int16_p = (int16_t) l;
344                return (TRUE);
345
346        case XDR_FREE:
347                return (TRUE);
348        }
349        /* NOTREACHED */
350        return (FALSE);
351}
352
353/*
354 * XDR unsigned 16-bit integers
355 */
356bool_t
357xdr_u_int16_t(xdrs, u_int16_p)
358        XDR *xdrs;
359        u_int16_t *u_int16_p;
360{
361        u_long l;
362
363        switch (xdrs->x_op) {
364
365        case XDR_ENCODE:
366                l = (u_long) *u_int16_p;
367                return (XDR_PUTLONG(xdrs, (long *)&l));
368
369        case XDR_DECODE:
370                if (!XDR_GETLONG(xdrs, (long *)&l)) {
371                        return (FALSE);
372                }
373                *u_int16_p = (u_int16_t) l;
374                return (TRUE);
375
376        case XDR_FREE:
377                return (TRUE);
378        }
379        /* NOTREACHED */
380        return (FALSE);
381}
382
383
384/*
385 * XDR a char
386 */
387bool_t
388xdr_char(xdrs, cp)
389        XDR *xdrs;
390        char *cp;
391{
392        int i;
393
394        i = (*cp);
395        if (!xdr_int(xdrs, &i)) {
396                return (FALSE);
397        }
398        *cp = i;
399        return (TRUE);
400}
401
402/*
403 * XDR an unsigned char
404 */
405bool_t
406xdr_u_char(xdrs, cp)
407        XDR *xdrs;
408        u_char *cp;
409{
410        u_int u;
411
412        u = (*cp);
413        if (!xdr_u_int(xdrs, &u)) {
414                return (FALSE);
415        }
416        *cp = u;
417        return (TRUE);
418}
419
420/*
421 * XDR booleans
422 */
423bool_t
424xdr_bool(xdrs, bp)
425        XDR *xdrs;
426        bool_t *bp;
427{
428        long lb;
429
430        switch (xdrs->x_op) {
431
432        case XDR_ENCODE:
433                lb = *bp ? XDR_TRUE : XDR_FALSE;
434                return (XDR_PUTLONG(xdrs, &lb));
435
436        case XDR_DECODE:
437                if (!XDR_GETLONG(xdrs, &lb)) {
438                        return (FALSE);
439                }
440                *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
441                return (TRUE);
442
443        case XDR_FREE:
444                return (TRUE);
445        }
446        /* NOTREACHED */
447        return (FALSE);
448}
449
450/*
451 * XDR enumerations
452 */
453bool_t
454xdr_enum(xdrs, ep)
455        XDR *xdrs;
456        enum_t *ep;
457{
458#ifndef lint
459        enum sizecheck { SIZEVAL };     /* used to find the size of an enum */
460
461        /*
462         * enums are treated as ints
463         */
464        if (sizeof (enum sizecheck) == sizeof (long)) {
465                return (xdr_long(xdrs, (long *)ep));
466        } else if (sizeof (enum sizecheck) == sizeof (int)) {
467                return (xdr_int(xdrs, (int *)ep));
468        } else if (sizeof (enum sizecheck) == 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(xdrs, cp, cnt)
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(xdrs, cpp, sizep, maxsize)
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(xdrs, np)
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(xdrs, dscmp, unp, choices, dfault)
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(xdrs, cpp, maxsize)
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;
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(xdrs, cpp)
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(xdrs, int64_p)
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(xdrs, uint64_p)
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.