acpi: Narrow workaround for broken interrupt settings
[dragonfly.git] / lib / libc / xdr / xdr.c
blob56223da1ff14c965efd80db11ec5732a56bc5019
1 /* $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $ */
3 /*-
4 * SPDX-License-Identifier: BSD-3-Clause
6 * Copyright (c) 2010, Oracle America, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials
17 * provided with the distribution.
18 * * Neither the name of the "Oracle America, Inc." nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 * @(#)xdr.c 1.35 87/08/12
36 * @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC
37 * $FreeBSD: head/lib/libc/xdr/xdr.c 326025 2017-11-20 19:49:47Z pfg $
41 * xdr.c, Generic XDR routines implementation.
43 * These are the "generic" xdr routines used to serialize and de-serialize
44 * most common data items. See xdr.h for more info on the interface to
45 * xdr.
48 #include "namespace.h"
49 #include <err.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
54 #include <rpc/rpc.h>
55 #include <rpc/rpc_com.h>
56 #include <rpc/types.h>
57 #include <rpc/xdr.h>
58 #include "un-namespace.h"
60 typedef quad_t longlong_t; /* ANSI long long type */
61 typedef u_quad_t u_longlong_t; /* ANSI unsigned long long type */
64 * constants specific to the xdr "protocol"
66 #define XDR_FALSE ((long) 0)
67 #define XDR_TRUE ((long) 1)
70 * for unit alignment
72 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
75 * Free a data structure using XDR
76 * Not a filter, but a convenient utility nonetheless
78 void
79 xdr_free(xdrproc_t proc, void *objp)
81 XDR x;
83 x.x_op = XDR_FREE;
84 (*proc)(&x, objp);
88 * XDR nothing
90 bool_t
91 xdr_void(void)
94 return (TRUE);
99 * XDR integers
101 bool_t
102 xdr_int(XDR *xdrs, int *ip)
104 long l;
106 switch (xdrs->x_op) {
108 case XDR_ENCODE:
109 l = (long) *ip;
110 return (XDR_PUTLONG(xdrs, &l));
112 case XDR_DECODE:
113 if (!XDR_GETLONG(xdrs, &l)) {
114 return (FALSE);
116 *ip = (int) l;
117 return (TRUE);
119 case XDR_FREE:
120 return (TRUE);
122 /* NOTREACHED */
123 return (FALSE);
127 * XDR unsigned integers
129 bool_t
130 xdr_u_int(XDR *xdrs, u_int *up)
132 u_long l;
134 switch (xdrs->x_op) {
136 case XDR_ENCODE:
137 l = (u_long) *up;
138 return (XDR_PUTLONG(xdrs, (long *)&l));
140 case XDR_DECODE:
141 if (!XDR_GETLONG(xdrs, (long *)&l)) {
142 return (FALSE);
144 *up = (u_int) l;
145 return (TRUE);
147 case XDR_FREE:
148 return (TRUE);
150 /* NOTREACHED */
151 return (FALSE);
156 * XDR long integers
157 * same as xdr_u_long - open coded to save a proc call!
159 bool_t
160 xdr_long(XDR *xdrs, long *lp)
162 switch (xdrs->x_op) {
163 case XDR_ENCODE:
164 return (XDR_PUTLONG(xdrs, lp));
165 case XDR_DECODE:
166 return (XDR_GETLONG(xdrs, lp));
167 case XDR_FREE:
168 return (TRUE);
170 /* NOTREACHED */
171 return (FALSE);
175 * XDR unsigned long integers
176 * same as xdr_long - open coded to save a proc call!
178 bool_t
179 xdr_u_long(XDR *xdrs, u_long *ulp)
181 switch (xdrs->x_op) {
182 case XDR_ENCODE:
183 return (XDR_PUTLONG(xdrs, (long *)ulp));
184 case XDR_DECODE:
185 return (XDR_GETLONG(xdrs, (long *)ulp));
186 case XDR_FREE:
187 return (TRUE);
189 /* NOTREACHED */
190 return (FALSE);
195 * XDR 32-bit integers
196 * same as xdr_u_int32_t - open coded to save a proc call!
198 bool_t
199 xdr_int32_t(XDR *xdrs, int32_t *int32_p)
201 long l;
203 switch (xdrs->x_op) {
205 case XDR_ENCODE:
206 l = (long) *int32_p;
207 return (XDR_PUTLONG(xdrs, &l));
209 case XDR_DECODE:
210 if (!XDR_GETLONG(xdrs, &l)) {
211 return (FALSE);
213 *int32_p = (int32_t) l;
214 return (TRUE);
216 case XDR_FREE:
217 return (TRUE);
219 /* NOTREACHED */
220 return (FALSE);
224 * XDR unsigned 32-bit integers
225 * same as xdr_int32_t - open coded to save a proc call!
227 bool_t
228 xdr_u_int32_t(XDR *xdrs, uint32_t *uint32_p)
230 u_long l;
232 switch (xdrs->x_op) {
234 case XDR_ENCODE:
235 l = (u_long) *uint32_p;
236 return (XDR_PUTLONG(xdrs, (long *)&l));
238 case XDR_DECODE:
239 if (!XDR_GETLONG(xdrs, (long *)&l)) {
240 return (FALSE);
242 *uint32_p = (uint32_t) l;
243 return (TRUE);
245 case XDR_FREE:
246 return (TRUE);
248 /* NOTREACHED */
249 return (FALSE);
253 * XDR unsigned 32-bit integers
254 * same as xdr_int32_t - open coded to save a proc call!
256 bool_t
257 xdr_uint32_t(XDR *xdrs, uint32_t *uint32_p)
259 u_long l;
261 switch (xdrs->x_op) {
263 case XDR_ENCODE:
264 l = (u_long) *uint32_p;
265 return (XDR_PUTLONG(xdrs, (long *)&l));
267 case XDR_DECODE:
268 if (!XDR_GETLONG(xdrs, (long *)&l)) {
269 return (FALSE);
271 *uint32_p = (uint32_t) l;
272 return (TRUE);
274 case XDR_FREE:
275 return (TRUE);
277 /* NOTREACHED */
278 return (FALSE);
282 * XDR short integers
284 bool_t
285 xdr_short(XDR *xdrs, short *sp)
287 long l;
289 switch (xdrs->x_op) {
291 case XDR_ENCODE:
292 l = (long) *sp;
293 return (XDR_PUTLONG(xdrs, &l));
295 case XDR_DECODE:
296 if (!XDR_GETLONG(xdrs, &l)) {
297 return (FALSE);
299 *sp = (short) l;
300 return (TRUE);
302 case XDR_FREE:
303 return (TRUE);
305 /* NOTREACHED */
306 return (FALSE);
310 * XDR unsigned short integers
312 bool_t
313 xdr_u_short(XDR *xdrs, u_short *usp)
315 u_long l;
317 switch (xdrs->x_op) {
319 case XDR_ENCODE:
320 l = (u_long) *usp;
321 return (XDR_PUTLONG(xdrs, (long *)&l));
323 case XDR_DECODE:
324 if (!XDR_GETLONG(xdrs, (long *)&l)) {
325 return (FALSE);
327 *usp = (u_short) l;
328 return (TRUE);
330 case XDR_FREE:
331 return (TRUE);
333 /* NOTREACHED */
334 return (FALSE);
339 * XDR 16-bit integers
341 bool_t
342 xdr_int16_t(XDR *xdrs, int16_t *int16_p)
344 long l;
346 switch (xdrs->x_op) {
348 case XDR_ENCODE:
349 l = (long) *int16_p;
350 return (XDR_PUTLONG(xdrs, &l));
352 case XDR_DECODE:
353 if (!XDR_GETLONG(xdrs, &l)) {
354 return (FALSE);
356 *int16_p = (int16_t) l;
357 return (TRUE);
359 case XDR_FREE:
360 return (TRUE);
362 /* NOTREACHED */
363 return (FALSE);
367 * XDR unsigned 16-bit integers
369 bool_t
370 xdr_u_int16_t(XDR *xdrs, uint16_t *uint16_p)
372 u_long l;
374 switch (xdrs->x_op) {
376 case XDR_ENCODE:
377 l = (u_long) *uint16_p;
378 return (XDR_PUTLONG(xdrs, (long *)&l));
380 case XDR_DECODE:
381 if (!XDR_GETLONG(xdrs, (long *)&l)) {
382 return (FALSE);
384 *uint16_p = (uint16_t) l;
385 return (TRUE);
387 case XDR_FREE:
388 return (TRUE);
390 /* NOTREACHED */
391 return (FALSE);
395 * XDR unsigned 16-bit integers
397 bool_t
398 xdr_uint16_t(XDR *xdrs, uint16_t *uint16_p)
400 u_long l;
402 switch (xdrs->x_op) {
404 case XDR_ENCODE:
405 l = (u_long) *uint16_p;
406 return (XDR_PUTLONG(xdrs, (long *)&l));
408 case XDR_DECODE:
409 if (!XDR_GETLONG(xdrs, (long *)&l)) {
410 return (FALSE);
412 *uint16_p = (uint16_t) l;
413 return (TRUE);
415 case XDR_FREE:
416 return (TRUE);
418 /* NOTREACHED */
419 return (FALSE);
424 * XDR a char
426 bool_t
427 xdr_char(XDR *xdrs, char *cp)
429 int i;
431 i = (*cp);
432 if (!xdr_int(xdrs, &i)) {
433 return (FALSE);
435 *cp = i;
436 return (TRUE);
440 * XDR an unsigned char
442 bool_t
443 xdr_u_char(XDR *xdrs, u_char *cp)
445 u_int u;
447 u = (*cp);
448 if (!xdr_u_int(xdrs, &u)) {
449 return (FALSE);
451 *cp = u;
452 return (TRUE);
456 * XDR booleans
458 bool_t
459 xdr_bool(XDR *xdrs, bool_t *bp)
461 long lb;
463 switch (xdrs->x_op) {
465 case XDR_ENCODE:
466 lb = *bp ? XDR_TRUE : XDR_FALSE;
467 return (XDR_PUTLONG(xdrs, &lb));
469 case XDR_DECODE:
470 if (!XDR_GETLONG(xdrs, &lb)) {
471 return (FALSE);
473 *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
474 return (TRUE);
476 case XDR_FREE:
477 return (TRUE);
479 /* NOTREACHED */
480 return (FALSE);
484 * XDR enumerations
486 bool_t
487 xdr_enum(XDR *xdrs, enum_t *ep)
489 enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
492 * enums are treated as ints
494 /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
495 return (xdr_long(xdrs, (long *)(void *)ep));
496 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
497 return (xdr_int(xdrs, (int *)(void *)ep));
498 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
499 return (xdr_short(xdrs, (short *)(void *)ep));
500 } else {
501 return (FALSE);
506 * XDR opaque data
507 * Allows the specification of a fixed size sequence of opaque bytes.
508 * cp points to the opaque object and cnt gives the byte length.
510 bool_t
511 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
513 u_int rndup;
514 static int crud[BYTES_PER_XDR_UNIT];
517 * if no data we are done
519 if (cnt == 0)
520 return (TRUE);
523 * round byte count to full xdr units
525 rndup = cnt % BYTES_PER_XDR_UNIT;
526 if (rndup > 0)
527 rndup = BYTES_PER_XDR_UNIT - rndup;
529 if (xdrs->x_op == XDR_DECODE) {
530 if (!XDR_GETBYTES(xdrs, cp, cnt)) {
531 return (FALSE);
533 if (rndup == 0)
534 return (TRUE);
535 return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
538 if (xdrs->x_op == XDR_ENCODE) {
539 if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
540 return (FALSE);
542 if (rndup == 0)
543 return (TRUE);
544 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
547 if (xdrs->x_op == XDR_FREE) {
548 return (TRUE);
551 return (FALSE);
555 * XDR counted bytes
556 * *cpp is a pointer to the bytes, *sizep is the count.
557 * If *cpp is NULL maxsize bytes are allocated
559 bool_t
560 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
562 char *sp = *cpp; /* sp is the actual string pointer */
563 u_int nodesize;
564 bool_t ret, allocated = FALSE;
567 * first deal with the length since xdr bytes are counted
569 if (! xdr_u_int(xdrs, sizep)) {
570 return (FALSE);
572 nodesize = *sizep;
573 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
574 return (FALSE);
578 * now deal with the actual bytes
580 switch (xdrs->x_op) {
582 case XDR_DECODE:
583 if (nodesize == 0) {
584 return (TRUE);
586 if (sp == NULL) {
587 *cpp = sp = mem_alloc(nodesize);
588 allocated = TRUE;
590 if (sp == NULL) {
591 warnx("xdr_bytes: out of memory");
592 return (FALSE);
594 /* FALLTHROUGH */
596 case XDR_ENCODE:
597 ret = xdr_opaque(xdrs, sp, nodesize);
598 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
599 if (allocated == TRUE) {
600 free(sp);
601 *cpp = NULL;
604 return (ret);
606 case XDR_FREE:
607 if (sp != NULL) {
608 mem_free(sp, nodesize);
609 *cpp = NULL;
611 return (TRUE);
613 /* NOTREACHED */
614 return (FALSE);
618 * Implemented here due to commonality of the object.
620 bool_t
621 xdr_netobj(XDR *xdrs, struct netobj *np)
623 return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
627 * XDR a descriminated union
628 * Support routine for discriminated unions.
629 * You create an array of xdrdiscrim structures, terminated with
630 * an entry with a null procedure pointer. The routine gets
631 * the discriminant value and then searches the array of xdrdiscrims
632 * looking for that value. It calls the procedure given in the xdrdiscrim
633 * to handle the discriminant. If there is no specific routine a default
634 * routine may be called.
635 * If there is no specific or default routine an error is returned.
637 * Parameters:
638 * dscmp: enum to decide which ar to work on
639 * unp: the union itself
640 * choices: [value, xdr proc] for each arm
641 * dfault: default xdr routine
643 bool_t
644 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp,
645 const struct xdr_discrim *choices, xdrproc_t dfault)
647 enum_t dscm;
650 * we deal with the discriminator; it's an enum
652 if (! xdr_enum(xdrs, dscmp)) {
653 return (FALSE);
655 dscm = *dscmp;
658 * search choices for a value that matches the discriminator.
659 * if we find one, execute the xdr routine for that value.
661 for (; choices->proc != NULL_xdrproc_t; choices++) {
662 if (choices->value == dscm)
663 return ((*(choices->proc))(xdrs, unp));
667 * no match - execute the default xdr routine if there is one
669 return ((dfault == NULL_xdrproc_t) ? FALSE :
670 (*dfault)(xdrs, unp));
675 * Non-portable xdr primitives.
676 * Care should be taken when moving these routines to new architectures.
681 * XDR null terminated ASCII strings
682 * xdr_string deals with "C strings" - arrays of bytes that are
683 * terminated by a NULL character. The parameter cpp references a
684 * pointer to storage; If the pointer is null, then the necessary
685 * storage is allocated. The last parameter is the max allowed length
686 * of the string as specified by a protocol.
688 bool_t
689 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
691 char *sp = *cpp; /* sp is the actual string pointer */
692 u_int size;
693 u_int nodesize;
694 bool_t ret, allocated = FALSE;
697 * first deal with the length since xdr strings are counted-strings
699 switch (xdrs->x_op) {
700 case XDR_FREE:
701 if (sp == NULL) {
702 return(TRUE); /* already free */
704 /* FALLTHROUGH */
705 case XDR_ENCODE:
706 size = strlen(sp);
707 break;
708 case XDR_DECODE:
709 break;
711 if (! xdr_u_int(xdrs, &size)) {
712 return (FALSE);
714 if (size > maxsize) {
715 return (FALSE);
717 nodesize = size + 1;
720 * now deal with the actual bytes
722 switch (xdrs->x_op) {
724 case XDR_DECODE:
725 if (nodesize == 0) {
726 return (TRUE);
728 if (sp == NULL) {
729 *cpp = sp = mem_alloc(nodesize);
730 allocated = TRUE;
732 if (sp == NULL) {
733 warnx("xdr_string: out of memory");
734 return (FALSE);
736 sp[size] = 0;
737 /* FALLTHROUGH */
739 case XDR_ENCODE:
740 ret = xdr_opaque(xdrs, sp, size);
741 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
742 if (allocated == TRUE) {
743 free(sp);
744 *cpp = NULL;
747 return (ret);
749 case XDR_FREE:
750 mem_free(sp, nodesize);
751 *cpp = NULL;
752 return (TRUE);
754 /* NOTREACHED */
755 return (FALSE);
759 * Wrapper for xdr_string that can be called directly from
760 * routines like clnt_call
762 bool_t
763 xdr_wrapstring(XDR *xdrs, char **cpp)
765 return xdr_string(xdrs, cpp, RPC_MAXDATASIZE);
769 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
770 * are in the "non-portable" section because they require that a `long long'
771 * be a 64-bit type.
773 * --thorpej@netbsd.org, November 30, 1999
777 * XDR 64-bit integers
779 bool_t
780 xdr_int64_t(XDR *xdrs, int64_t *llp)
782 u_long ul[2];
784 switch (xdrs->x_op) {
785 case XDR_ENCODE:
786 ul[0] = (u_long)((uint64_t)*llp >> 32) & 0xffffffff;
787 ul[1] = (u_long)((uint64_t)*llp) & 0xffffffff;
788 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
789 return (FALSE);
790 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
791 case XDR_DECODE:
792 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
793 return (FALSE);
794 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
795 return (FALSE);
796 *llp = (int64_t)
797 (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1]));
798 return (TRUE);
799 case XDR_FREE:
800 return (TRUE);
802 /* NOTREACHED */
803 return (FALSE);
808 * XDR unsigned 64-bit integers
810 bool_t
811 xdr_u_int64_t(XDR *xdrs, uint64_t *ullp)
813 u_long ul[2];
815 switch (xdrs->x_op) {
816 case XDR_ENCODE:
817 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
818 ul[1] = (u_long)(*ullp) & 0xffffffff;
819 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
820 return (FALSE);
821 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
822 case XDR_DECODE:
823 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
824 return (FALSE);
825 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
826 return (FALSE);
827 *ullp = (uint64_t)
828 (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1]));
829 return (TRUE);
830 case XDR_FREE:
831 return (TRUE);
833 /* NOTREACHED */
834 return (FALSE);
838 * XDR unsigned 64-bit integers
840 bool_t
841 xdr_uint64_t(XDR *xdrs, uint64_t *ullp)
843 u_long ul[2];
845 switch (xdrs->x_op) {
846 case XDR_ENCODE:
847 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
848 ul[1] = (u_long)(*ullp) & 0xffffffff;
849 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
850 return (FALSE);
851 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
852 case XDR_DECODE:
853 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
854 return (FALSE);
855 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
856 return (FALSE);
857 *ullp = (uint64_t)
858 (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1]));
859 return (TRUE);
860 case XDR_FREE:
861 return (TRUE);
863 /* NOTREACHED */
864 return (FALSE);
869 * XDR hypers
871 bool_t
872 xdr_hyper(XDR *xdrs, longlong_t *llp)
876 * Don't bother open-coding this; it's a fair amount of code. Just
877 * call xdr_int64_t().
879 return (xdr_int64_t(xdrs, (int64_t *)llp));
884 * XDR unsigned hypers
886 bool_t
887 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp)
891 * Don't bother open-coding this; it's a fair amount of code. Just
892 * call xdr_u_int64_t().
894 return (xdr_u_int64_t(xdrs, (uint64_t *)ullp));
899 * XDR longlong_t's
901 bool_t
902 xdr_longlong_t(XDR *xdrs, longlong_t *llp)
906 * Don't bother open-coding this; it's a fair amount of code. Just
907 * call xdr_int64_t().
909 return (xdr_int64_t(xdrs, (int64_t *)llp));
914 * XDR u_longlong_t's
916 bool_t
917 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
921 * Don't bother open-coding this; it's a fair amount of code. Just
922 * call xdr_u_int64_t().
924 return (xdr_u_int64_t(xdrs, (uint64_t *)ullp));