Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/ntirpc/rpc/xdr_inline.h
$ cat -n /usr/include/ntirpc/rpc/xdr_inline.h 1 /* 2 * Copyright (c) 2009, Sun Microsystems, Inc. 3 * Copyright (c) 2012-2018 Red Hat, Inc. and/or its affiliates. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * - Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * - Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * - Neither the name of Sun Microsystems, Inc. nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include
31 32 /* 33 * xdr.c, Generic XDR routines implementation. 34 * 35 * Copyright (C) 1986, Sun Microsystems, Inc. 36 * 37 * These are the "generic" xdr routines used to serialize and de-serialize 38 * most common data items. See xdr.h for more info on the interface to 39 * xdr. 40 */ 41 42 #ifndef _TIRPC_INLINE_XDR_H 43 #define _TIRPC_INLINE_XDR_H 44 45 #if !defined(_WIN32) 46 #include
47 #endif 48 #include
49 #include
50 #include
51 52 #include
53 #include
54 55 /* 56 * XDR integers 57 */ 58 static inline bool 59 inline_xdr_int(XDR *xdrs, int *ip) 60 { 61 long l; 62 63 switch (xdrs->x_op) { 64 65 case XDR_ENCODE: 66 l = (long)*ip; 67 return (XDR_PUTLONG(xdrs, &l)); 68 69 case XDR_DECODE: 70 if (!XDR_GETLONG(xdrs, &l)) 71 return (false); 72 *ip = (int)l; 73 return (true); 74 75 case XDR_FREE: 76 return (true); 77 } 78 /* NOTREACHED */ 79 return (false); 80 } 81 82 /* 83 * XDR unsigned integers 84 */ 85 static inline bool 86 inline_xdr_u_int(XDR *xdrs, u_int *up) 87 { 88 u_long l; 89 90 switch (xdrs->x_op) { 91 92 case XDR_ENCODE: 93 l = (u_long) *up; 94 return (XDR_PUTLONG(xdrs, (long *)&l)); 95 96 case XDR_DECODE: 97 if (!XDR_GETLONG(xdrs, (long *)&l)) 98 return (false); 99 *up = (u_int) l; 100 return (true); 101 102 case XDR_FREE: 103 return (true); 104 } 105 /* NOTREACHED */ 106 return (false); 107 } 108 109 /* 110 * XDR long integers 111 * same as xdr_u_long - open coded to save a proc call! 112 */ 113 static inline bool 114 inline_xdr_long(XDR *xdrs, long *lp) 115 { 116 switch (xdrs->x_op) { 117 case XDR_ENCODE: 118 return (XDR_PUTLONG(xdrs, lp)); 119 case XDR_DECODE: 120 return (XDR_GETLONG(xdrs, lp)); 121 case XDR_FREE: 122 return (true); 123 } 124 /* NOTREACHED */ 125 return (false); 126 } 127 128 /* 129 * XDR unsigned long integers 130 * same as xdr_long - open coded to save a proc call! 131 */ 132 static inline bool 133 inline_xdr_u_long(XDR *xdrs, u_long *ulp) 134 { 135 switch (xdrs->x_op) { 136 case XDR_ENCODE: 137 return (XDR_PUTLONG(xdrs, (long *)ulp)); 138 case XDR_DECODE: 139 return (XDR_GETLONG(xdrs, (long *)ulp)); 140 case XDR_FREE: 141 return (true); 142 } 143 /* NOTREACHED */ 144 return (false); 145 } 146 147 /* 148 * XDR 64-bit integers 149 * (always transmitted as unsigned 32-bit) 150 */ 151 static inline bool 152 xdr_uint64_t(XDR *xdrs, uint64_t *uint64_p) 153 { 154 uint32_t u[2]; 155 156 switch (xdrs->x_op) { 157 case XDR_ENCODE: 158 u[0] = (uint32_t) (*uint64_p >> 32) & 0xffffffff; 159 u[1] = (uint32_t) (*uint64_p) & 0xffffffff; 160 if (!XDR_PUTUINT32(xdrs, u[0])) 161 return (false); 162 return (XDR_PUTUINT32(xdrs, u[1])); 163 case XDR_DECODE: 164 if (!XDR_GETUINT32(xdrs, &u[0]) 165 || !XDR_GETUINT32(xdrs, &u[1])) 166 return (false); 167 *uint64_p = (((uint64_t) u[0] << 32) | ((uint64_t) u[1])); 168 return (true); 169 case XDR_FREE: 170 return (true); 171 } 172 /* NOTREACHED */ 173 return (false); 174 } 175 176 static inline bool 177 xdr_u_int64_t(XDR *xdrs, u_int64_t *u_int64_p) 178 { 179 return (xdr_uint64_t(xdrs, (uint64_t *)u_int64_p)); 180 } 181 #define inline_xdr_u_int64_t xdr_u_int64_t 182 183 static inline bool 184 xdr_int64_t(XDR *xdrs, int64_t *int64_p) 185 { 186 return (xdr_uint64_t(xdrs, (uint64_t *)int64_p)); 187 } 188 #define inline_xdr_int64_t xdr_int64_t 189 190 /* 191 * XDR 32-bit integers 192 */ 193 static inline bool 194 xdr_int32_t(XDR *xdrs, int32_t *int32_p) 195 { 196 switch (xdrs->x_op) { 197 198 case XDR_ENCODE: 199 return (XDR_PUTINT32(xdrs, *int32_p)); 200 201 case XDR_DECODE: 202 return (XDR_GETINT32(xdrs, int32_p)); 203 204 case XDR_FREE: 205 return (true); 206 } 207 /* NOTREACHED */ 208 return (false); 209 } 210 #define inline_xdr_int32_t xdr_int32_t 211 212 /* 213 * XDR unsigned 32-bit integers 214 */ 215 static inline bool 216 xdr_uint32_t(XDR *xdrs, uint32_t *u_int32_p) 217 { 218 switch (xdrs->x_op) { 219 220 case XDR_ENCODE: 221 return (XDR_PUTUINT32(xdrs, *u_int32_p)); 222 223 case XDR_DECODE: 224 return (XDR_GETUINT32(xdrs, u_int32_p)); 225 226 case XDR_FREE: 227 return (true); 228 } 229 /* NOTREACHED */ 230 return (false); 231 } 232 233 static inline bool 234 xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p) 235 { 236 return (xdr_uint32_t(xdrs, (uint32_t *)u_int32_p)); 237 } 238 #define inline_xdr_u_int32_t xdr_u_int32_t 239 240 /* 241 * Solaris strips the '_t' from these types -- not sure why. 242 * But, let's be compatible. 243 */ 244 static inline bool 245 xdr_rpcprog(XDR *xdrs, rpcprog_t *u_int32_p) 246 { 247 return (xdr_uint32_t(xdrs, (uint32_t *)u_int32_p)); 248 } 249 250 static inline bool 251 xdr_rpcvers(XDR *xdrs, rpcvers_t *u_int32_p) 252 { 253 return (xdr_uint32_t(xdrs, (uint32_t *)u_int32_p)); 254 } 255 256 static inline bool 257 xdr_rpcproc(XDR *xdrs, rpcproc_t *u_int32_p) 258 { 259 return (xdr_uint32_t(xdrs, (uint32_t *)u_int32_p)); 260 } 261 262 static inline bool 263 xdr_rpcprot(XDR *xdrs, rpcprot_t *u_int32_p) 264 { 265 return (xdr_uint32_t(xdrs, (uint32_t *)u_int32_p)); 266 } 267 268 static inline bool 269 xdr_rpcport(XDR *xdrs, rpcport_t *u_int32_p) 270 { 271 return (xdr_uint32_t(xdrs, (uint32_t *)u_int32_p)); 272 } 273 274 /* 275 * XDR 16-bit integers 276 */ 277 static inline bool 278 xdr_int16_t(XDR *xdrs, int16_t *int16_p) 279 { 280 switch (xdrs->x_op) { 281 282 case XDR_ENCODE: 283 return (XDR_PUTINT16(xdrs, *int16_p)); 284 285 case XDR_DECODE: 286 return (XDR_GETINT16(xdrs, int16_p)); 287 288 case XDR_FREE: 289 return (true); 290 } 291 /* NOTREACHED */ 292 return (false); 293 } 294 #define inline_xdr_int16_t xdr_int16_t 295 296 /* 297 * XDR unsigned 16-bit integers 298 */ 299 static inline bool 300 xdr_uint16_t(XDR *xdrs, uint16_t *u_int16_p) 301 { 302 switch (xdrs->x_op) { 303 304 case XDR_ENCODE: 305 return (XDR_PUTUINT16(xdrs, *u_int16_p)); 306 307 case XDR_DECODE: 308 return (XDR_GETUINT16(xdrs, u_int16_p)); 309 310 case XDR_FREE: 311 return (true); 312 } 313 /* NOTREACHED */ 314 return (false); 315 } 316 317 static inline bool 318 xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p) 319 { 320 return (xdr_uint16_t(xdrs, (uint16_t *)u_int16_p)); 321 } 322 #define inline_xdr_u_int16_t xdr_u_int16_t 323 324 /* 325 * XDR 8-bit integers 326 */ 327 static inline bool 328 xdr_int8_t(XDR *xdrs, int8_t *int8_p) 329 { 330 switch (xdrs->x_op) { 331 332 case XDR_ENCODE: 333 return (XDR_PUTINT8(xdrs, *int8_p)); 334 335 case XDR_DECODE: 336 return (XDR_GETINT8(xdrs, int8_p)); 337 338 case XDR_FREE: 339 return (true); 340 } 341 /* NOTREACHED */ 342 return (false); 343 } 344 #define inline_xdr_int8_t xdr_int8_t 345 346 /* 347 * XDR unsigned 8-bit integers 348 */ 349 static inline bool 350 xdr_uint8_t(XDR *xdrs, uint8_t *u_int8_p) 351 { 352 switch (xdrs->x_op) { 353 354 case XDR_ENCODE: 355 return (XDR_PUTUINT8(xdrs, *u_int8_p)); 356 357 case XDR_DECODE: 358 return (XDR_GETUINT8(xdrs, u_int8_p)); 359 360 case XDR_FREE: 361 return (true); 362 } 363 /* NOTREACHED */ 364 return (false); 365 } 366 367 static inline bool 368 xdr_u_int8_t(XDR *xdrs, u_int8_t *u_int8_p) 369 { 370 return (xdr_uint8_t(xdrs, (uint8_t *)u_int8_p)); 371 } 372 #define inline_xdr_u_int8_t xdr_u_int8_t 373 374 /* 375 * XDR booleans 376 */ 377 static inline bool 378 xdr_bool(XDR *xdrs, bool_t *bp) 379 { 380 switch (xdrs->x_op) { 381 382 case XDR_ENCODE: 383 return (xdr_putbool(xdrs, *bp)); 384 385 case XDR_DECODE: 386 return (xdr_getbool(xdrs, bp)); 387 388 case XDR_FREE: 389 return (true); 390 } 391 /* NOTREACHED */ 392 return (false); 393 } 394 #define inline_xdr_bool xdr_bool 395 396 /* 397 * XDR enumerations 398 */ 399 static inline bool 400 xdr_enum(XDR *xdrs, enum_t *ep) 401 { 402 switch (xdrs->x_op) { 403 404 case XDR_ENCODE: 405 return (xdr_putenum(xdrs, *ep)); 406 407 case XDR_DECODE: 408 return (xdr_getenum(xdrs, ep)); 409 410 case XDR_FREE: 411 return (true); 412 } 413 /* NOTREACHED */ 414 return (false); 415 } 416 #define inline_xdr_enum xdr_enum 417 418 /* 419 * decode opaque data 420 * Allows the specification of a fixed size sequence of opaque bytes. 421 * cp points to the opaque object and cnt gives the byte length. 422 */ 423 static inline bool 424 xdr_opaque_decode(XDR *xdrs, char *cp, u_int cnt) 425 { 426 u_int rndup; 427 428 /* 429 * if no data we are done 430 */ 431 if (cnt == 0) 432 return (true); 433 434 /* 435 * XDR_INLINE is just as likely to do a function call, 436 * so don't bother with it here. 437 */ 438 if (!XDR_GETBYTES(xdrs, cp, cnt)) { 439 __warnx(TIRPC_DEBUG_FLAG_ERROR, 440 "%s:%u ERROR opaque", 441 __func__, __LINE__); 442 return (false); 443 } 444 445 /* 446 * round byte count to full xdr units 447 */ 448 rndup = cnt & (BYTES_PER_XDR_UNIT - 1); 449 450 if (rndup > 0) { 451 uint32_t crud; 452 453 if (!XDR_GETBYTES(xdrs, (char *) &crud, 454 BYTES_PER_XDR_UNIT - rndup)) { 455 __warnx(TIRPC_DEBUG_FLAG_ERROR, 456 "%s:%u ERROR crud", 457 __func__, __LINE__); 458 return (false); 459 } 460 } 461 462 return (true); 463 } 464 465 /* 466 * encode opaque data 467 * Allows the specification of a fixed size sequence of opaque bytes. 468 * cp points to the opaque object and cnt gives the byte length. 469 */ 470 static inline bool 471 xdr_opaque_encode(XDR *xdrs, const char *cp, u_int cnt) 472 { 473 u_int rndup; 474 475 /* 476 * if no data we are done 477 */ 478 if (cnt == 0) 479 return (true); 480 481 /* 482 * XDR_INLINE is just as likely to do a function call, 483 * so don't bother with it here. 484 */ 485 if (!XDR_PUTBYTES(xdrs, cp, cnt)) 486 return (false); 487 488 /* 489 * round byte count to full xdr units 490 */ 491 rndup = cnt & (BYTES_PER_XDR_UNIT - 1); 492 493 if (rndup > 0) { 494 uint32_t zero = 0; 495 496 if (!XDR_PUTBYTES(xdrs, (char *) &zero, 497 BYTES_PER_XDR_UNIT - rndup)) 498 return (false); 499 } 500 501 return (true); 502 } 503 504 /* 505 * XDR opaque data 506 * Allows the specification of a fixed size sequence of opaque bytes. 507 * cp points to the opaque object and cnt gives the byte length. 508 */ 509 static inline bool 510 xdr_opaque(XDR *xdrs, char *cp, u_int cnt) 511 { 512 switch (xdrs->x_op) { 513 case XDR_DECODE: 514 return (xdr_opaque_decode(xdrs, cp, cnt)); 515 case XDR_ENCODE: 516 return (xdr_opaque_encode(xdrs, cp, cnt)); 517 case XDR_FREE: 518 return (true); 519 } 520 521 __warnx(TIRPC_DEBUG_FLAG_ERROR, 522 "%s:%u ERROR xdrs->x_op (%u)", 523 __func__, __LINE__, 524 xdrs->x_op); 525 return (false); 526 } 527 528 /* 529 * XDR counted opaques 530 * *sp is a pointer to the bytes, *sizep is the count. 531 */ 532 static inline bool 533 xdr_opaques(XDR *xdrs, char *sp, uint32_t *sizep, uint32_t maxsize) 534 { 535 uint32_t nodesize; 536 537 /* 538 * first deal with the length since xdr bytes are counted 539 */ 540 if (!xdr_uint32_t(xdrs, sizep)) 541 return (false); 542 543 nodesize = *sizep; 544 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) 545 return (false); 546 547 /* 548 * now deal with the actual bytes 549 */ 550 switch (xdrs->x_op) { 551 case XDR_DECODE: 552 return (xdr_opaque_decode(xdrs, sp, nodesize)); 553 case XDR_ENCODE: 554 return (xdr_opaque_encode(xdrs, sp, nodesize)); 555 case XDR_FREE: 556 return (true); 557 } 558 /* NOTREACHED */ 559 return (false); 560 } 561 562 /* 563 * XDR counted bytes 564 * *cpp is a pointer to the bytes, *sizep is the count. 565 * If *cpp is NULL maxsize bytes are allocated 566 */ 567 static inline bool 568 xdr_bytes_decode(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) 569 { 570 char *sp = *cpp; /* sp is the actual string pointer */ 571 uint32_t size; 572 bool ret; 573 574 /* 575 * first deal with the length since xdr bytes are counted 576 */ 577 if (!XDR_GETUINT32(xdrs, &size)) { 578 __warnx(TIRPC_DEBUG_FLAG_ERROR, 579 "%s:%u ERROR size", 580 __func__, __LINE__); 581 return (false); 582 } 583 if (size > maxsize) { 584 __warnx(TIRPC_DEBUG_FLAG_ERROR, 585 "%s:%u ERROR size %" PRIu32 " > max %u", 586 __func__, __LINE__, 587 size, maxsize); 588 return (false); 589 } 590 *sizep = (u_int)size; /* only valid size */ 591 592 /* 593 * now deal with the actual bytes 594 */ 595 if (!size) 596 return (true); 597 if (!sp) 598 sp = (char *)mem_alloc(size); 599 600 ret = xdr_opaque_decode(xdrs, sp, size); 601 if (!ret) { 602 if (!*cpp) { 603 /* Only free if we allocated */ 604 mem_free(sp, size); 605 } 606 return (ret); 607 } 608 *cpp = sp; /* only valid pointer */ 609 return (ret); 610 } 611 612 static inline bool 613 xdr_bytes_encode(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) 614 { 615 char *sp = *cpp; /* sp is the actual string pointer */ 616 uint32_t size = (uint32_t)*sizep; 617 618 if (*sizep > maxsize) { 619 __warnx(TIRPC_DEBUG_FLAG_ERROR, 620 "%s:%u ERROR size %u > max %u", 621 __func__, __LINE__, 622 *sizep, maxsize); 623 return (false); 624 } 625 626 if (*sizep > size) { 627 /* caller provided very large maxsize */ 628 __warnx(TIRPC_DEBUG_FLAG_ERROR, 629 "%s:%u ERROR overflow %u", 630 __func__, __LINE__, 631 *sizep); 632 return (false); 633 } 634 635 if (!XDR_PUTUINT32(xdrs, size)) 636 return (false); 637 638 return (xdr_opaque_encode(xdrs, sp, size)); 639 } 640 641 static inline bool 642 xdr_bytes_free(XDR *xdrs, char **cpp, size_t size) 643 { 644 if (*cpp) { 645 mem_free(*cpp, size); 646 *cpp = NULL; 647 return (true); 648 } 649 650 /* normal for switch x_op, sometimes useful to track */ 651 __warnx(TIRPC_DEBUG_FLAG_XDR, 652 "%s:%u already free", 653 __func__, __LINE__); 654 return (true); 655 } 656 657 static inline bool 658 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) 659 { 660 switch (xdrs->x_op) { 661 case XDR_DECODE: 662 return (xdr_bytes_decode(xdrs, cpp, sizep, maxsize)); 663 case XDR_ENCODE: 664 return (xdr_bytes_encode(xdrs, cpp, sizep, maxsize)); 665 case XDR_FREE: 666 return (xdr_bytes_free(xdrs, cpp, *sizep)); 667 } 668 669 __warnx(TIRPC_DEBUG_FLAG_ERROR, 670 "%s:%u ERROR xdrs->x_op (%u)", 671 __func__, __LINE__, 672 xdrs->x_op); 673 return (false); 674 } 675 #define inline_xdr_bytes xdr_bytes 676 677 /* 678 * XDR a descriminated union 679 * Support routine for discriminated unions. 680 * You create an array of xdrdiscrim structures, terminated with 681 * an entry with a null procedure pointer. The routine gets 682 * the discriminant value and then searches the array of xdrdiscrims 683 * looking for that value. It calls the procedure given in the xdrdiscrim 684 * to handle the discriminant. If there is no specific routine a default 685 * routine may be called. 686 * If there is no specific or default routine an error is returned. 687 */ 688 static inline bool 689 xdr_union(XDR *xdrs, 690 enum_t *dscmp, /* enum to decide which arm to work on */ 691 void *unp, /* the union itself */ 692 const struct xdr_discrim *choices, 693 /* [value, xdr proc] for each arm */ 694 xdrproc_t dfault /* default xdr routine */) 695 { 696 enum_t dscm; 697 698 /* 699 * we deal with the discriminator; it's an enum 700 */ 701 if (!inline_xdr_enum(xdrs, dscmp)) 702 return (false); 703 dscm = *dscmp; 704 705 /* 706 * search choices for a value that matches the discriminator. 707 * if we find one, execute the xdr routine for that value. 708 */ 709 for (; choices->proc != NULL_xdrproc_t; choices++) { 710 if (choices->value == dscm) 711 return ((*(choices->proc)) (xdrs, unp)); 712 } 713 714 /* 715 * no match - execute the default xdr routine if there is one 716 */ 717 return ((dfault == NULL_xdrproc_t) ? false : (*dfault) (xdrs, unp)); 718 } 719 #define inline_xdr_union xdr_union 720 721 /* 722 * XDR a fixed length array. Unlike variable-length arrays, 723 * the storage of fixed length arrays is static and unfreeable. 724 * > basep: pointer of the array 725 * > nelem: number of elements 726 * > selem: size (in bytes) of each element 727 * > xdr_elem: routine to XDR each element 728 */ 729 static inline bool 730 xdr_vector(XDR *xdrs, char *basep, u_int nelem, u_int selem, 731 xdrproc_t xdr_elem) 732 { 733 char *target = basep; 734 u_int i = 0; 735 736 for (; i < nelem; i++) { 737 if (!(*xdr_elem) (xdrs, target)) 738 return (false); 739 target += selem; 740 } 741 return (true); 742 } 743 744 /* 745 * XDR an array of arbitrary elements 746 * > **cpp: pointer to the array 747 * > *sizep: number of elements 748 * > maxsize: maximum number of elements 749 * > selem: size (in bytes) of each element 750 * > xdr_elem: routine to XDR each element 751 * 752 * If *cpp is NULL, (*sizep * selem) bytes are allocated. 753 */ 754 static inline bool 755 xdr_array_decode(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize, 756 u_int selem, xdrproc_t xdr_elem) 757 { 758 char *target = *cpp; 759 u_int i = 0; 760 uint32_t size; 761 bool stat = true; 762 763 if (maxsize > (UINT_MAX / selem)) { 764 __warnx(TIRPC_DEBUG_FLAG_ERROR, 765 "%s:%u ERROR maxsize %u > max %u", 766 __func__, __LINE__, 767 maxsize, (UINT_MAX / selem)); 768 return (false); 769 } 770 771 /* 772 * first deal with the length since xdr arrays are counted-arrays 773 */ 774 if (!XDR_GETUINT32(xdrs, &size)) { 775 __warnx(TIRPC_DEBUG_FLAG_ERROR, 776 "%s:%u ERROR size", 777 __func__, __LINE__); 778 return (false); 779 } 780 if (size > maxsize) { 781 __warnx(TIRPC_DEBUG_FLAG_ERROR, 782 "%s:%u ERROR size %" PRIu32 " > max %u", 783 __func__, __LINE__, 784 size, maxsize); 785 return (false); 786 } 787 *sizep = (u_int)size; /* only valid size */ 788 789 /* 790 * now deal with the actual elements 791 */ 792 if (!size) 793 return (true); 794 if (!target) 795 *cpp = target = (char*) mem_zalloc(size * selem); 796 797 for (; (i < size) && stat; i++) { 798 stat = (*xdr_elem) (xdrs, target); 799 target += selem; 800 } 801 802 return (stat); 803 } 804 805 static inline bool 806 xdr_array_encode(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize, 807 u_int selem, xdrproc_t xdr_elem) 808 { 809 char *target = *cpp; 810 u_int i = 0; 811 uint32_t size = (uint32_t)*sizep; 812 bool stat = true; 813 814 if (*sizep > maxsize) { 815 __warnx(TIRPC_DEBUG_FLAG_ERROR, 816 "%s:%u ERROR size %u > max %u", 817 __func__, __LINE__, 818 *sizep, maxsize); 819 return (false); 820 } 821 822 if (*sizep > size) { 823 /* caller provided very large maxsize */ 824 __warnx(TIRPC_DEBUG_FLAG_ERROR, 825 "%s:%u ERROR overflow %u", 826 __func__, __LINE__, 827 *sizep); 828 return (false); 829 } 830 831 if (!XDR_PUTUINT32(xdrs, size)) 832 return (false); 833 834 for (; (i < size) && stat; i++) { 835 stat = (*xdr_elem) (xdrs, target); 836 target += selem; 837 } 838 839 return (stat); 840 } 841 842 static inline bool 843 xdr_array_free(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize, 844 u_int selem, xdrproc_t xdr_elem) 845 { 846 char *target = *cpp; 847 u_int i = 0; 848 uint32_t size = *sizep; 849 bool stat = true; 850 851 if (!target) { 852 __warnx(TIRPC_DEBUG_FLAG_XDR, 853 "%s:%u already free", 854 __func__, __LINE__); 855 return (true); 856 } 857 858 for (; (i < size) && stat; i++) { 859 stat = (*xdr_elem) (xdrs, target); 860 target += selem; 861 } 862 863 mem_free(*cpp, size * selem); 864 *cpp = NULL; 865 866 return (stat); 867 } 868 869 static inline bool 870 xdr_array(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize, 871 u_int selem, xdrproc_t xdr_elem) 872 { 873 switch (xdrs->x_op) { 874 case XDR_DECODE: 875 return (xdr_array_decode(xdrs, cpp, sizep, maxsize, selem, 876 xdr_elem)); 877 case XDR_ENCODE: 878 return (xdr_array_encode(xdrs, cpp, sizep, maxsize, selem, 879 xdr_elem)); 880 case XDR_FREE: 881 return (xdr_array_free(xdrs, cpp, sizep, maxsize, selem, 882 xdr_elem)); 883 } 884 885 __warnx(TIRPC_DEBUG_FLAG_ERROR, 886 "%s:%u ERROR xdrs->x_op (%u)", 887 __func__, __LINE__, 888 xdrs->x_op); 889 return (false); 890 } 891 892 /* 893 * Non-portable xdr primitives. 894 * Care should be taken when moving these routines to new architectures. 895 */ 896 897 /* 898 * XDR null terminated ASCII strings 899 * xdr_string deals with "C strings" - arrays of bytes that are 900 * terminated by a NULL character. The parameter cpp references a 901 * pointer to storage; If the pointer is null, then the necessary 902 * storage is allocated. The last parameter is the max allowed length 903 * of the string as specified by a protocol. 904 */ 905 static inline bool 906 xdr_string_decode(XDR *xdrs, char **cpp, u_int maxsize) 907 { 908 char *sp = *cpp; /* sp is the actual string pointer */ 909 uint32_t size; 910 u_int nodesize; 911 bool ret; 912 913 /* 914 * first deal with the length since xdr strings are counted-strings 915 */ 916 if (!XDR_GETUINT32(xdrs, &size)) { 917 __warnx(TIRPC_DEBUG_FLAG_ERROR, 918 "%s:%u ERROR size", 919 __func__, __LINE__); 920 return (false); 921 } 922 923 if (size > maxsize) { 924 __warnx(TIRPC_DEBUG_FLAG_ERROR, 925 "%s:%u ERROR size %" PRIu32 " > max %u", 926 __func__, __LINE__, 927 size, maxsize); 928 return (false); 929 } 930 931 nodesize = (uint32_t)(size + 1); 932 if (nodesize < (size + 1)) { 933 /* caller provided very large maxsize */ 934 __warnx(TIRPC_DEBUG_FLAG_ERROR, 935 "%s:%u ERROR overflow %" PRIu32, 936 __func__, __LINE__, 937 size); 938 return (false); 939 } 940 941 /* 942 * now deal with the actual bytes 943 */ 944 if (!sp) 945 sp = (char *)mem_alloc(nodesize); 946 947 ret = xdr_opaque_decode(xdrs, sp, size); 948 if (!ret) { 949 mem_free(sp, nodesize); 950 return (ret); 951 } 952 sp[size] = '\0'; 953 *cpp = sp; /* only valid pointer */ 954 return (ret); 955 } 956 957 static inline bool 958 xdr_string_encode(XDR *xdrs, char **cpp, u_int maxsize) 959 { 960 u_long size; 961 u_int nodesize; 962 963 if (!(*cpp)) { 964 __warnx(TIRPC_DEBUG_FLAG_ERROR, 965 "%s:%u ERROR missing string pointer", 966 __func__, __LINE__); 967 return (false); 968 } 969 970 size = strlen(*cpp); 971 if (size > maxsize) { 972 __warnx(TIRPC_DEBUG_FLAG_ERROR, 973 "%s:%u ERROR size %ul > max %u", 974 __func__, __LINE__, 975 size, maxsize); 976 return (false); 977 } 978 979 nodesize = (uint32_t)(size + 1); 980 if (nodesize < (size + 1)) { 981 /* caller provided very large maxsize */ 982 __warnx(TIRPC_DEBUG_FLAG_ERROR, 983 "%s:%u ERROR overflow %ul", 984 __func__, __LINE__, 985 size); 986 return (false); 987 } 988 989 if (!XDR_PUTUINT32(xdrs, size)) 990 return (false); 991 992 return (xdr_opaque_encode(xdrs, *cpp, size)); 993 } 994 995 static inline bool 996 xdr_string_free(XDR *xdrs, char **cpp) 997 { 998 if (*cpp) { 999 mem_free(*cpp, strlen(*cpp) + 1); 1000 *cpp = NULL; 1001 return (true); 1002 } 1003 1004 /* normal for switch x_op, sometimes useful to track */ 1005 __warnx(TIRPC_DEBUG_FLAG_XDR, 1006 "%s:%u already free", 1007 __func__, __LINE__); 1008 return (true); 1009 } 1010 1011 static inline bool 1012 xdr_string(XDR *xdrs, char **cpp, u_int maxsize) 1013 { 1014 switch (xdrs->x_op) { 1015 case XDR_DECODE: 1016 return (xdr_string_decode(xdrs, cpp, maxsize)); 1017 case XDR_ENCODE: 1018 return (xdr_string_encode(xdrs, cpp, maxsize)); 1019 case XDR_FREE: 1020 return (xdr_string_free(xdrs, cpp)); 1021 } 1022 1023 __warnx(TIRPC_DEBUG_FLAG_ERROR, 1024 "%s:%u ERROR xdrs->x_op (%u)", 1025 __func__, __LINE__, 1026 xdrs->x_op); 1027 return (false); 1028 } 1029 #define inline_xdr_string xdr_string 1030 1031 /* 1032 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t() 1033 * are in the "non-portable" section because they require that a `long long' 1034 * be a 64-bit type. 1035 * 1036 * --thorpej@netbsd.org, November 30, 1999 1037 */ 1038 1039 /* 1040 * XDR longlong_t's 1041 */ 1042 static inline bool 1043 inline_xdr_longlong_t(XDR *xdrs, quad_t *llp) 1044 { 1045 1046 /* 1047 * Don't bother open-coding this; it's a fair amount of code. Just 1048 * call xdr_int64_t(). 1049 */ 1050 return (inline_xdr_int64_t(xdrs, (int64_t *) llp)); 1051 } 1052 1053 /* 1054 * XDR u_longlong_t's 1055 */ 1056 static inline bool 1057 inline_xdr_u_longlong_t(XDR *xdrs, u_quad_t *ullp) 1058 { 1059 1060 /* 1061 * Don't bother open-coding this; it's a fair amount of code. Just 1062 * call xdr_u_int64_t(). 1063 */ 1064 return (inline_xdr_u_int64_t(xdrs, (u_int64_t *) ullp)); 1065 } 1066 1067 #endif /* _TIRPC_INLINE_XDR_H */
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™