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

4.104.114.84.95
Last change on this file since df49c60 was df49c60, checked in by Joel Sherrill <joel.sherrill@…>, on Jun 12, 2000 at 3:00:15 PM

Merged from 4.5.0-beta3a

  • Property mode set to 100644
File size: 13.7 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/*
54 * constants specific to the xdr "protocol"
55 */
56#define XDR_FALSE       ((long) 0)
57#define XDR_TRUE        ((long) 1)
58#define LASTUNSIGNED    ((u_int) 0-1)
59
60/*
61 * for unit alignment
62 */
63static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
64
65/*
66 * Free a data structure using XDR
67 * Not a filter, but a convenient utility nonetheless
68 */
69void
70xdr_free(proc, objp)
71        xdrproc_t proc;
72        char *objp;
73{
74        XDR x;
75
76        x.x_op = XDR_FREE;
77        (*proc)(&x, objp);
78}
79
80/*
81 * XDR nothing
82 */
83bool_t
84xdr_void(/* xdrs, addr */)
85        /* XDR *xdrs; */
86        /* caddr_t addr; */
87{
88
89        return (TRUE);
90}
91
92
93/*
94 * XDR integers
95 */
96bool_t
97xdr_int(xdrs, ip)
98        XDR *xdrs;
99        int *ip;
100{
101        long l;
102
103        switch (xdrs->x_op) {
104
105        case XDR_ENCODE:
106                l = (long) *ip;
107                return (XDR_PUTLONG(xdrs, &l));
108
109        case XDR_DECODE:
110                if (!XDR_GETLONG(xdrs, &l)) {
111                        return (FALSE);
112                }
113                *ip = (int) l;
114                return (TRUE);
115
116        case XDR_FREE:
117                return (TRUE);
118        }
119        return (FALSE);
120}
121
122/*
123 * XDR unsigned integers
124 */
125bool_t
126xdr_u_int(xdrs, up)
127        XDR *xdrs;
128        u_int *up;
129{
130        u_long l;
131
132        switch (xdrs->x_op) {
133
134        case XDR_ENCODE:
135                l = (u_long) *up;
136                return (XDR_PUTLONG(xdrs, (long *)&l));
137
138        case XDR_DECODE:
139                if (!XDR_GETLONG(xdrs, (long *)&l)) {
140                        return (FALSE);
141                }
142                *up = (u_int) l;
143                return (TRUE);
144
145        case XDR_FREE:
146                return (TRUE);
147        }
148        return (FALSE);
149}
150
151
152/*
153 * XDR long integers
154 * same as xdr_u_long - open coded to save a proc call!
155 */
156bool_t
157xdr_long(xdrs, lp)
158        register XDR *xdrs;
159        long *lp;
160{
161        switch (xdrs->x_op) {
162        case XDR_ENCODE:
163                return (XDR_PUTLONG(xdrs, lp));
164        case XDR_DECODE:
165                return (XDR_GETLONG(xdrs, lp));
166        case XDR_FREE:
167                return (TRUE);
168        }
169
170        return (FALSE);
171}
172
173/*
174 * XDR unsigned long integers
175 * same as xdr_long - open coded to save a proc call!
176 */
177bool_t
178xdr_u_long(xdrs, ulp)
179        register XDR *xdrs;
180        u_long *ulp;
181{
182        switch (xdrs->x_op) {
183        case XDR_ENCODE:
184                return (XDR_PUTLONG(xdrs, (long *)ulp));
185        case XDR_DECODE:
186                return (XDR_GETLONG(xdrs, (long *)ulp));
187        case XDR_FREE:
188                return (TRUE);
189        }
190        return (FALSE);
191}
192
193
194/*
195 * XDR 32-bit integers
196 * same as xdr_u_int32_t - open coded to save a proc call!
197 */
198bool_t
199xdr_int32_t(xdrs, int32_p)
200        register XDR *xdrs;
201        int32_t *int32_p;
202{
203        long l;
204
205        switch (xdrs->x_op) {
206
207        case XDR_ENCODE:
208                l = (long) *int32_p;
209                return (XDR_PUTLONG(xdrs, &l));
210
211        case XDR_DECODE:
212                if (!XDR_GETLONG(xdrs, &l)) {
213                        return (FALSE);
214                }
215                *int32_p = (int32_t) l;
216                return (TRUE);
217
218        case XDR_FREE:
219                return (TRUE);
220        }
221        return (FALSE);
222}
223
224/*
225 * XDR unsigned 32-bit integers
226 * same as xdr_int32_t - open coded to save a proc call!
227 */
228bool_t
229xdr_u_int32_t(xdrs, u_int32_p)
230        register XDR *xdrs;
231        u_int32_t *u_int32_p;
232{
233        u_long l;
234
235        switch (xdrs->x_op) {
236
237        case XDR_ENCODE:
238                l = (u_long) *u_int32_p;
239                return (XDR_PUTLONG(xdrs, (long *)&l));
240
241        case XDR_DECODE:
242                if (!XDR_GETLONG(xdrs, (long *)&l)) {
243                        return (FALSE);
244                }
245                *u_int32_p = (u_int32_t) l;
246                return (TRUE);
247
248        case XDR_FREE:
249                return (TRUE);
250        }
251        return (FALSE);
252}
253
254/*
255 * XDR 64-bit integers
256 */
257bool_t
258xdr_int64_t(xdrs, int64_p)
259        register XDR *xdrs;
260        int64_t *int64_p;
261{
262        int64_t x;
263
264        switch (xdrs->x_op) {
265
266        case XDR_ENCODE:
267                return (xdr_opaque(xdrs, (caddr_t)int64_p, sizeof(int64_t)));
268
269        case XDR_DECODE:
270                if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
271                        return (FALSE);
272                }
273                *int64_p = x;
274                return (TRUE);
275
276        case XDR_FREE:
277                return (TRUE);
278        }
279        return (FALSE);
280}
281
282/*
283 * XDR unsigned 64-bit integers
284 */
285bool_t
286xdr_u_int64_t(xdrs, uint64_p)
287        register XDR *xdrs;
288        u_int64_t *uint64_p;
289{
290        u_int64_t x;
291
292        switch (xdrs->x_op) {
293
294        case XDR_ENCODE:
295                return (xdr_opaque(xdrs, (caddr_t)uint64_p, sizeof(u_int64_t)));
296
297        case XDR_DECODE:
298                if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
299                        return (FALSE);
300                }
301                *uint64_p = x;
302                return (TRUE);
303
304        case XDR_FREE:
305                return (TRUE);
306        }
307        return (FALSE);
308}
309
310
311/*
312 * XDR short integers
313 */
314bool_t
315xdr_short(xdrs, sp)
316        register XDR *xdrs;
317        short *sp;
318{
319        long l;
320
321        switch (xdrs->x_op) {
322
323        case XDR_ENCODE:
324                l = (long) *sp;
325                return (XDR_PUTLONG(xdrs, &l));
326
327        case XDR_DECODE:
328                if (!XDR_GETLONG(xdrs, &l)) {
329                        return (FALSE);
330                }
331                *sp = (short) l;
332                return (TRUE);
333
334        case XDR_FREE:
335                return (TRUE);
336        }
337        return (FALSE);
338}
339
340/*
341 * XDR unsigned short integers
342 */
343bool_t
344xdr_u_short(xdrs, usp)
345        register XDR *xdrs;
346        u_short *usp;
347{
348        u_long l;
349
350        switch (xdrs->x_op) {
351
352        case XDR_ENCODE:
353                l = (u_long) *usp;
354                return (XDR_PUTLONG(xdrs, (long *)&l));
355
356        case XDR_DECODE:
357                if (!XDR_GETLONG(xdrs, (long *)&l)) {
358                        return (FALSE);
359                }
360                *usp = (u_short) l;
361                return (TRUE);
362
363        case XDR_FREE:
364                return (TRUE);
365        }
366        return (FALSE);
367}
368
369
370/*
371 * XDR 16-bit integers
372 */
373bool_t
374xdr_int16_t(xdrs, int16_p)
375        register XDR *xdrs;
376        int16_t *int16_p;
377{
378        long l;
379
380        switch (xdrs->x_op) {
381
382        case XDR_ENCODE:
383                l = (long) *int16_p;
384                return (XDR_PUTLONG(xdrs, &l));
385
386        case XDR_DECODE:
387                if (!XDR_GETLONG(xdrs, &l)) {
388                        return (FALSE);
389                }
390                *int16_p = (int16_t) l;
391                return (TRUE);
392
393        case XDR_FREE:
394                return (TRUE);
395        }
396        return (FALSE);
397}
398
399/*
400 * XDR unsigned 16-bit integers
401 */
402bool_t
403xdr_u_int16_t(xdrs, u_int16_p)
404        register XDR *xdrs;
405        u_int16_t *u_int16_p;
406{
407        u_long l;
408
409        switch (xdrs->x_op) {
410
411        case XDR_ENCODE:
412                l = (u_long) *u_int16_p;
413                return (XDR_PUTLONG(xdrs, (long *)&l));
414
415        case XDR_DECODE:
416                if (!XDR_GETLONG(xdrs, (long *)&l)) {
417                        return (FALSE);
418                }
419                *u_int16_p = (u_int16_t) l;
420                return (TRUE);
421
422        case XDR_FREE:
423                return (TRUE);
424        }
425        return (FALSE);
426}
427
428
429/*
430 * XDR a char
431 */
432bool_t
433xdr_char(xdrs, cp)
434        XDR *xdrs;
435        char *cp;
436{
437        int i;
438
439        i = (*cp);
440        if (!xdr_int(xdrs, &i)) {
441                return (FALSE);
442        }
443        *cp = i;
444        return (TRUE);
445}
446
447/*
448 * XDR an unsigned char
449 */
450bool_t
451xdr_u_char(xdrs, cp)
452        XDR *xdrs;
453        u_char *cp;
454{
455        u_int u;
456
457        u = (*cp);
458        if (!xdr_u_int(xdrs, &u)) {
459                return (FALSE);
460        }
461        *cp = u;
462        return (TRUE);
463}
464
465/*
466 * XDR booleans
467 */
468bool_t
469xdr_bool(xdrs, bp)
470        register XDR *xdrs;
471        bool_t *bp;
472{
473        long lb;
474
475        switch (xdrs->x_op) {
476
477        case XDR_ENCODE:
478                lb = *bp ? XDR_TRUE : XDR_FALSE;
479                return (XDR_PUTLONG(xdrs, &lb));
480
481        case XDR_DECODE:
482                if (!XDR_GETLONG(xdrs, &lb)) {
483                        return (FALSE);
484                }
485                *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
486                return (TRUE);
487
488        case XDR_FREE:
489                return (TRUE);
490        }
491        return (FALSE);
492}
493
494/*
495 * XDR enumerations
496 */
497bool_t
498xdr_enum(xdrs, ep)
499        XDR *xdrs;
500        enum_t *ep;
501{
502#ifndef lint
503        enum sizecheck { SIZEVAL };     /* used to find the size of an enum */
504
505        /*
506         * enums are treated as ints
507         */
508        if (sizeof (enum sizecheck) == sizeof (long)) {
509                return (xdr_long(xdrs, (long *)ep));
510        } else if (sizeof (enum sizecheck) == sizeof (int)) {
511                return (xdr_int(xdrs, (int *)ep));
512        } else if (sizeof (enum sizecheck) == sizeof (short)) {
513                return (xdr_short(xdrs, (short *)ep));
514        } else {
515                return (FALSE);
516        }
517#else
518        (void) (xdr_short(xdrs, (short *)ep));
519        (void) (xdr_int(xdrs, (int *)ep));
520        return (xdr_long(xdrs, (long *)ep));
521#endif
522}
523
524/*
525 * XDR opaque data
526 * Allows the specification of a fixed size sequence of opaque bytes.
527 * cp points to the opaque object and cnt gives the byte length.
528 */
529bool_t
530xdr_opaque(xdrs, cp, cnt)
531        register XDR *xdrs;
532        caddr_t cp;
533        register u_int cnt;
534{
535        register u_int rndup;
536        static int crud[BYTES_PER_XDR_UNIT];
537
538        /*
539         * if no data we are done
540         */
541        if (cnt == 0)
542                return (TRUE);
543
544        /*
545         * round byte count to full xdr units
546         */
547        rndup = cnt % BYTES_PER_XDR_UNIT;
548        if (rndup > 0)
549                rndup = BYTES_PER_XDR_UNIT - rndup;
550
551        if (xdrs->x_op == XDR_DECODE) {
552                if (!XDR_GETBYTES(xdrs, cp, cnt)) {
553                        return (FALSE);
554                }
555                if (rndup == 0)
556                        return (TRUE);
557                return (XDR_GETBYTES(xdrs, (caddr_t)crud, rndup));
558        }
559
560        if (xdrs->x_op == XDR_ENCODE) {
561                if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
562                        return (FALSE);
563                }
564                if (rndup == 0)
565                        return (TRUE);
566                return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
567        }
568
569        if (xdrs->x_op == XDR_FREE) {
570                return (TRUE);
571        }
572
573        return (FALSE);
574}
575
576/*
577 * XDR counted bytes
578 * *cpp is a pointer to the bytes, *sizep is the count.
579 * If *cpp is NULL maxsize bytes are allocated
580 */
581bool_t
582xdr_bytes(xdrs, cpp, sizep, maxsize)
583        register XDR *xdrs;
584        char **cpp;
585        register u_int *sizep;
586        u_int maxsize;
587{
588        register char *sp = *cpp;  /* sp is the actual string pointer */
589        register u_int nodesize;
590
591        /*
592         * first deal with the length since xdr bytes are counted
593         */
594        if (! xdr_u_int(xdrs, sizep)) {
595                return (FALSE);
596        }
597        nodesize = *sizep;
598        if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
599                return (FALSE);
600        }
601
602        /*
603         * now deal with the actual bytes
604         */
605        switch (xdrs->x_op) {
606
607        case XDR_DECODE:
608                if (nodesize == 0) {
609                        return (TRUE);
610                }
611                if (sp == NULL) {
612                        *cpp = sp = (char *)mem_alloc(nodesize);
613                }
614                if (sp == NULL) {
615                        (void) fprintf(stderr, "xdr_bytes: out of memory\n");
616                        return (FALSE);
617                }
618                /* fall into ... */
619
620        case XDR_ENCODE:
621                return (xdr_opaque(xdrs, sp, nodesize));
622
623        case XDR_FREE:
624                if (sp != NULL) {
625                        mem_free(sp, nodesize);
626                        *cpp = NULL;
627                }
628                return (TRUE);
629        }
630        return (FALSE);
631}
632
633/*
634 * Implemented here due to commonality of the object.
635 */
636bool_t
637xdr_netobj(xdrs, np)
638        XDR *xdrs;
639        struct netobj *np;
640{
641
642        return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
643}
644
645/*
646 * XDR a descriminated union
647 * Support routine for discriminated unions.
648 * You create an array of xdrdiscrim structures, terminated with
649 * an entry with a null procedure pointer.  The routine gets
650 * the discriminant value and then searches the array of xdrdiscrims
651 * looking for that value.  It calls the procedure given in the xdrdiscrim
652 * to handle the discriminant.  If there is no specific routine a default
653 * routine may be called.
654 * If there is no specific or default routine an error is returned.
655 */
656bool_t
657xdr_union(xdrs, dscmp, unp, choices, dfault)
658        register XDR *xdrs;
659        enum_t *dscmp;          /* enum to decide which arm to work on */
660        char *unp;              /* the union itself */
661        struct xdr_discrim *choices;    /* [value, xdr proc] for each arm */
662        xdrproc_t dfault;       /* default xdr routine */
663{
664        register enum_t dscm;
665
666        /*
667         * we deal with the discriminator;  it's an enum
668         */
669        if (! xdr_enum(xdrs, dscmp)) {
670                return (FALSE);
671        }
672        dscm = *dscmp;
673
674        /*
675         * search choices for a value that matches the discriminator.
676         * if we find one, execute the xdr routine for that value.
677         */
678        for (; choices->proc != NULL_xdrproc_t; choices++) {
679                if (choices->value == dscm)
680                        return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
681        }
682
683        /*
684         * no match - execute the default xdr routine if there is one
685         */
686        return ((dfault == NULL_xdrproc_t) ? FALSE :
687            (*dfault)(xdrs, unp, LASTUNSIGNED));
688}
689
690
691/*
692 * Non-portable xdr primitives.
693 * Care should be taken when moving these routines to new architectures.
694 */
695
696
697/*
698 * XDR null terminated ASCII strings
699 * xdr_string deals with "C strings" - arrays of bytes that are
700 * terminated by a NULL character.  The parameter cpp references a
701 * pointer to storage; If the pointer is null, then the necessary
702 * storage is allocated.  The last parameter is the max allowed length
703 * of the string as specified by a protocol.
704 */
705bool_t
706xdr_string(xdrs, cpp, maxsize)
707        register XDR *xdrs;
708        char **cpp;
709        u_int maxsize;
710{
711        register char *sp = *cpp;  /* sp is the actual string pointer */
712        u_int size;
713        u_int nodesize;
714
715        /*
716         * first deal with the length since xdr strings are counted-strings
717         */
718        switch (xdrs->x_op) {
719        case XDR_FREE:
720                if (sp == NULL) {
721                        return(TRUE);   /* already free */
722                }
723                /* fall through... */
724        case XDR_ENCODE:
725                size = strlen(sp);
726                break;
727        case XDR_DECODE:  /* to avoid warning */
728                break;
729        }
730        if (! xdr_u_int(xdrs, &size)) {
731                return (FALSE);
732        }
733        if (size > maxsize) {
734                return (FALSE);
735        }
736        nodesize = size + 1;
737
738        /*
739         * now deal with the actual bytes
740         */
741        switch (xdrs->x_op) {
742
743        case XDR_DECODE:
744                if (nodesize == 0) {
745                        return (TRUE);
746                }
747                if (sp == NULL)
748                        *cpp = sp = (char *)mem_alloc(nodesize);
749                if (sp == NULL) {
750                        (void) fprintf(stderr, "xdr_string: out of memory\n");
751                        return (FALSE);
752                }
753                sp[size] = 0;
754                /* fall into ... */
755
756        case XDR_ENCODE:
757                return (xdr_opaque(xdrs, sp, size));
758
759        case XDR_FREE:
760                mem_free(sp, nodesize);
761                *cpp = NULL;
762                return (TRUE);
763        }
764        return (FALSE);
765}
766
767/*
768 * Wrapper for xdr_string that can be called directly from
769 * routines like clnt_call
770 */
771bool_t
772xdr_wrapstring(xdrs, cpp)
773        XDR *xdrs;
774        char **cpp;
775{
776        return xdr_string(xdrs, cpp, LASTUNSIGNED);
777}
Note: See TracBrowser for help on using the repository browser.