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