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