xdr.c revision 184588
11590Srgrimes/* $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $ */ 21590Srgrimes 31590Srgrimes/* 41590Srgrimes * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 51590Srgrimes * unrestricted use provided that this legend is included on all tape 61590Srgrimes * media and as a part of the software program in whole or part. Users 71590Srgrimes * may copy or modify Sun RPC without charge, but are not authorized 81590Srgrimes * to license or distribute it to anyone else except as part of a product or 91590Srgrimes * program developed by the user. 101590Srgrimes * 111590Srgrimes * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 121590Srgrimes * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 131590Srgrimes * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 141590Srgrimes * 151590Srgrimes * Sun RPC is provided with no support and without any obligation on the 161590Srgrimes * part of Sun Microsystems, Inc. to assist in its use, correction, 171590Srgrimes * modification or enhancement. 181590Srgrimes * 191590Srgrimes * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 201590Srgrimes * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 211590Srgrimes * OR ANY PART THEREOF. 221590Srgrimes * 231590Srgrimes * In no event will Sun Microsystems, Inc. be liable for any lost revenue 241590Srgrimes * or profits or other special, indirect and consequential damages, even if 251590Srgrimes * Sun has been advised of the possibility of such damages. 261590Srgrimes * 271590Srgrimes * Sun Microsystems, Inc. 281590Srgrimes * 2550 Garcia Avenue 291590Srgrimes * Mountain View, California 94043 301590Srgrimes */ 311590Srgrimes 321590Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 331590Srgrimesstatic char *sccsid2 = "@(#)xdr.c 1.35 87/08/12"; 341590Srgrimesstatic char *sccsid = "@(#)xdr.c 2.1 88/07/29 4.0 RPCSRC"; 351590Srgrimes#endif 361590Srgrimes#include <sys/cdefs.h> 371590Srgrimes__FBSDID("$FreeBSD: head/lib/libc/xdr/xdr.c 184588 2008-11-03 10:38:00Z dfr $"); 381590Srgrimes 391590Srgrimes/* 401590Srgrimes * xdr.c, Generic XDR routines implementation. 411590Srgrimes * 421590Srgrimes * Copyright (C) 1986, Sun Microsystems, Inc. 431590Srgrimes * 441590Srgrimes * These are the "generic" xdr routines used to serialize and de-serialize 451590Srgrimes * most common data items. See xdr.h for more info on the interface to 461590Srgrimes * xdr. 471590Srgrimes */ 481590Srgrimes 491590Srgrimes#include "namespace.h" 501590Srgrimes#include <err.h> 511590Srgrimes#include <stdio.h> 521590Srgrimes#include <stdlib.h> 531590Srgrimes#include <string.h> 541590Srgrimes 551590Srgrimes#include <rpc/types.h> 561590Srgrimes#include <rpc/xdr.h> 571590Srgrimes#include "un-namespace.h" 581590Srgrimes 591590Srgrimestypedef quad_t longlong_t; /* ANSI long long type */ 601590Srgrimestypedef u_quad_t u_longlong_t; /* ANSI unsigned long long type */ 611590Srgrimes 621590Srgrimes/* 631590Srgrimes * constants specific to the xdr "protocol" 641590Srgrimes */ 651590Srgrimes#define XDR_FALSE ((long) 0) 661590Srgrimes#define XDR_TRUE ((long) 1) 671590Srgrimes#define LASTUNSIGNED ((u_int) 0-1) 681590Srgrimes 691590Srgrimes/* 701590Srgrimes * for unit alignment 711590Srgrimes */ 721590Srgrimesstatic const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; 731590Srgrimes 741590Srgrimes/* 751590Srgrimes * Free a data structure using XDR 761590Srgrimes * Not a filter, but a convenient utility nonetheless 771590Srgrimes */ 781590Srgrimesvoid 791590Srgrimesxdr_free(proc, objp) 801590Srgrimes xdrproc_t proc; 811590Srgrimes void *objp; 821590Srgrimes{ 831590Srgrimes XDR x; 841590Srgrimes 851590Srgrimes x.x_op = XDR_FREE; 861590Srgrimes (*proc)(&x, objp); 871590Srgrimes} 881590Srgrimes 891590Srgrimes/* 901590Srgrimes * XDR nothing 911590Srgrimes */ 921590Srgrimesbool_t 931590Srgrimesxdr_void(void) 941590Srgrimes{ 951590Srgrimes 961590Srgrimes return (TRUE); 971590Srgrimes} 981590Srgrimes 991590Srgrimes 1001590Srgrimes/* 1011590Srgrimes * XDR integers 1021590Srgrimes */ 1031590Srgrimesbool_t 1041590Srgrimesxdr_int(xdrs, ip) 1051590Srgrimes XDR *xdrs; 1061590Srgrimes int *ip; 1071590Srgrimes{ 1081590Srgrimes long l; 1091590Srgrimes 1101590Srgrimes switch (xdrs->x_op) { 1111590Srgrimes 1121590Srgrimes case XDR_ENCODE: 1131590Srgrimes l = (long) *ip; 1141590Srgrimes return (XDR_PUTLONG(xdrs, &l)); 1151590Srgrimes 1161590Srgrimes case XDR_DECODE: 1171590Srgrimes if (!XDR_GETLONG(xdrs, &l)) { 1181590Srgrimes return (FALSE); 1191590Srgrimes } 1201590Srgrimes *ip = (int) l; 1211590Srgrimes return (TRUE); 1221590Srgrimes 1231590Srgrimes case XDR_FREE: 1241590Srgrimes return (TRUE); 1251590Srgrimes } 1261590Srgrimes /* NOTREACHED */ 1271590Srgrimes return (FALSE); 1281590Srgrimes} 1291590Srgrimes 1301590Srgrimes/* 1311590Srgrimes * XDR unsigned integers 1321590Srgrimes */ 1331590Srgrimesbool_t 1341590Srgrimesxdr_u_int(xdrs, up) 1351590Srgrimes XDR *xdrs; 1361590Srgrimes u_int *up; 1371590Srgrimes{ 1381590Srgrimes u_long l; 1391590Srgrimes 1401590Srgrimes switch (xdrs->x_op) { 1411590Srgrimes 1421590Srgrimes case XDR_ENCODE: 1431590Srgrimes l = (u_long) *up; 1441590Srgrimes return (XDR_PUTLONG(xdrs, (long *)&l)); 1451590Srgrimes 1461590Srgrimes case XDR_DECODE: 1471590Srgrimes if (!XDR_GETLONG(xdrs, (long *)&l)) { 1481590Srgrimes return (FALSE); 1491590Srgrimes } 1501590Srgrimes *up = (u_int) l; 1511590Srgrimes return (TRUE); 1521590Srgrimes 1531590Srgrimes case XDR_FREE: 1541590Srgrimes return (TRUE); 1551590Srgrimes } 1561590Srgrimes /* NOTREACHED */ 1571590Srgrimes return (FALSE); 1581590Srgrimes} 1591590Srgrimes 1601590Srgrimes 1611590Srgrimes/* 1621590Srgrimes * XDR long integers 1631590Srgrimes * same as xdr_u_long - open coded to save a proc call! 1641590Srgrimes */ 1651590Srgrimesbool_t 1661590Srgrimesxdr_long(xdrs, lp) 1671590Srgrimes XDR *xdrs; 1681590Srgrimes long *lp; 1691590Srgrimes{ 1701590Srgrimes switch (xdrs->x_op) { 1711590Srgrimes case XDR_ENCODE: 1721590Srgrimes return (XDR_PUTLONG(xdrs, lp)); 1731590Srgrimes case XDR_DECODE: 1741590Srgrimes return (XDR_GETLONG(xdrs, lp)); 1751590Srgrimes case XDR_FREE: 1761590Srgrimes return (TRUE); 1771590Srgrimes } 1781590Srgrimes /* NOTREACHED */ 1791590Srgrimes return (FALSE); 1801590Srgrimes} 1811590Srgrimes 1821590Srgrimes/* 1831590Srgrimes * XDR unsigned long integers 1841590Srgrimes * same as xdr_long - open coded to save a proc call! 1851590Srgrimes */ 1861590Srgrimesbool_t 1871590Srgrimesxdr_u_long(xdrs, ulp) 1881590Srgrimes XDR *xdrs; 1891590Srgrimes u_long *ulp; 1901590Srgrimes{ 1911590Srgrimes switch (xdrs->x_op) { 1921590Srgrimes case XDR_ENCODE: 1931590Srgrimes return (XDR_PUTLONG(xdrs, (long *)ulp)); 1941590Srgrimes case XDR_DECODE: 1951590Srgrimes return (XDR_GETLONG(xdrs, (long *)ulp)); 1961590Srgrimes case XDR_FREE: 1971590Srgrimes return (TRUE); 1981590Srgrimes } 1991590Srgrimes /* NOTREACHED */ 2001590Srgrimes return (FALSE); 2011590Srgrimes} 2021590Srgrimes 2031590Srgrimes 2041590Srgrimes/* 2051590Srgrimes * XDR 32-bit integers 2061590Srgrimes * same as xdr_u_int32_t - open coded to save a proc call! 2071590Srgrimes */ 2081590Srgrimesbool_t 2091590Srgrimesxdr_int32_t(xdrs, int32_p) 2101590Srgrimes XDR *xdrs; 2111590Srgrimes int32_t *int32_p; 2121590Srgrimes{ 2131590Srgrimes long l; 2141590Srgrimes 2151590Srgrimes switch (xdrs->x_op) { 2161590Srgrimes 2171590Srgrimes case XDR_ENCODE: 2181590Srgrimes l = (long) *int32_p; 2191590Srgrimes return (XDR_PUTLONG(xdrs, &l)); 2201590Srgrimes 2211590Srgrimes case XDR_DECODE: 2221590Srgrimes if (!XDR_GETLONG(xdrs, &l)) { 2231590Srgrimes return (FALSE); 2241590Srgrimes } 2251590Srgrimes *int32_p = (int32_t) l; 2261590Srgrimes return (TRUE); 2271590Srgrimes 2281590Srgrimes case XDR_FREE: 2291590Srgrimes return (TRUE); 2301590Srgrimes } 2311590Srgrimes /* NOTREACHED */ 2321590Srgrimes return (FALSE); 2331590Srgrimes} 2341590Srgrimes 2351590Srgrimes/* 2361590Srgrimes * XDR unsigned 32-bit integers 2371590Srgrimes * same as xdr_int32_t - open coded to save a proc call! 2381590Srgrimes */ 2391590Srgrimesbool_t 2401590Srgrimesxdr_u_int32_t(xdrs, u_int32_p) 2411590Srgrimes XDR *xdrs; 2421590Srgrimes u_int32_t *u_int32_p; 2431590Srgrimes{ 2441590Srgrimes u_long l; 2451590Srgrimes 2461590Srgrimes switch (xdrs->x_op) { 2471590Srgrimes 2481590Srgrimes case XDR_ENCODE: 2491590Srgrimes l = (u_long) *u_int32_p; 2501590Srgrimes return (XDR_PUTLONG(xdrs, (long *)&l)); 2511590Srgrimes 2521590Srgrimes case XDR_DECODE: 2531590Srgrimes if (!XDR_GETLONG(xdrs, (long *)&l)) { 2541590Srgrimes return (FALSE); 2551590Srgrimes } 2561590Srgrimes *u_int32_p = (u_int32_t) l; 2571590Srgrimes return (TRUE); 2581590Srgrimes 2591590Srgrimes case XDR_FREE: 2601590Srgrimes return (TRUE); 2611590Srgrimes } 2621590Srgrimes /* NOTREACHED */ 2631590Srgrimes return (FALSE); 2641590Srgrimes} 2651590Srgrimes 2661590Srgrimes/* 2671590Srgrimes * XDR unsigned 32-bit integers 2681590Srgrimes * same as xdr_int32_t - open coded to save a proc call! 2691590Srgrimes */ 2701590Srgrimesbool_t 2711590Srgrimesxdr_uint32_t(xdrs, u_int32_p) 2721590Srgrimes XDR *xdrs; 2731590Srgrimes uint32_t *u_int32_p; 2741590Srgrimes{ 2751590Srgrimes u_long l; 2761590Srgrimes 2771590Srgrimes switch (xdrs->x_op) { 2781590Srgrimes 2791590Srgrimes case XDR_ENCODE: 2801590Srgrimes l = (u_long) *u_int32_p; 2811590Srgrimes return (XDR_PUTLONG(xdrs, (long *)&l)); 2821590Srgrimes 2831590Srgrimes case XDR_DECODE: 2841590Srgrimes if (!XDR_GETLONG(xdrs, (long *)&l)) { 2851590Srgrimes return (FALSE); 2861590Srgrimes } 2871590Srgrimes *u_int32_p = (u_int32_t) l; 2881590Srgrimes return (TRUE); 2891590Srgrimes 2901590Srgrimes case XDR_FREE: 2911590Srgrimes return (TRUE); 2921590Srgrimes } 2931590Srgrimes /* NOTREACHED */ 2941590Srgrimes return (FALSE); 2951590Srgrimes} 2961590Srgrimes 2971590Srgrimes/* 2981590Srgrimes * XDR short integers 2991590Srgrimes */ 3001590Srgrimesbool_t 3011590Srgrimesxdr_short(xdrs, sp) 3021590Srgrimes XDR *xdrs; 3031590Srgrimes short *sp; 3041590Srgrimes{ 3051590Srgrimes long l; 3061590Srgrimes 3071590Srgrimes switch (xdrs->x_op) { 3081590Srgrimes 3091590Srgrimes case XDR_ENCODE: 3101590Srgrimes l = (long) *sp; 3111590Srgrimes return (XDR_PUTLONG(xdrs, &l)); 3121590Srgrimes 3131590Srgrimes case XDR_DECODE: 3141590Srgrimes if (!XDR_GETLONG(xdrs, &l)) { 3151590Srgrimes return (FALSE); 3161590Srgrimes } 3171590Srgrimes *sp = (short) l; 3181590Srgrimes return (TRUE); 3191590Srgrimes 3201590Srgrimes case XDR_FREE: 3211590Srgrimes return (TRUE); 3221590Srgrimes } 3231590Srgrimes /* NOTREACHED */ 3241590Srgrimes return (FALSE); 3251590Srgrimes} 3261590Srgrimes 3271590Srgrimes/* 3281590Srgrimes * XDR unsigned short integers 3291590Srgrimes */ 3301590Srgrimesbool_t 3311590Srgrimesxdr_u_short(xdrs, usp) 3321590Srgrimes XDR *xdrs; 3331590Srgrimes u_short *usp; 3341590Srgrimes{ 3351590Srgrimes u_long l; 3361590Srgrimes 3371590Srgrimes switch (xdrs->x_op) { 3381590Srgrimes 3391590Srgrimes case XDR_ENCODE: 3401590Srgrimes l = (u_long) *usp; 3411590Srgrimes return (XDR_PUTLONG(xdrs, (long *)&l)); 3421590Srgrimes 3431590Srgrimes case XDR_DECODE: 3441590Srgrimes if (!XDR_GETLONG(xdrs, (long *)&l)) { 3451590Srgrimes return (FALSE); 3461590Srgrimes } 3471590Srgrimes *usp = (u_short) l; 3481590Srgrimes return (TRUE); 3491590Srgrimes 3501590Srgrimes case XDR_FREE: 3511590Srgrimes return (TRUE); 3521590Srgrimes } 3531590Srgrimes /* NOTREACHED */ 3541590Srgrimes return (FALSE); 3551590Srgrimes} 3561590Srgrimes 3571590Srgrimes 3581590Srgrimes/* 3591590Srgrimes * XDR 16-bit integers 3601590Srgrimes */ 3611590Srgrimesbool_t 3621590Srgrimesxdr_int16_t(xdrs, int16_p) 3631590Srgrimes XDR *xdrs; 3641590Srgrimes int16_t *int16_p; 3651590Srgrimes{ 3661590Srgrimes long l; 3671590Srgrimes 3681590Srgrimes switch (xdrs->x_op) { 3691590Srgrimes 3701590Srgrimes case XDR_ENCODE: 3711590Srgrimes l = (long) *int16_p; 3721590Srgrimes return (XDR_PUTLONG(xdrs, &l)); 3731590Srgrimes 3741590Srgrimes case XDR_DECODE: 3751590Srgrimes if (!XDR_GETLONG(xdrs, &l)) { 3761590Srgrimes return (FALSE); 3771590Srgrimes } 3781590Srgrimes *int16_p = (int16_t) l; 3791590Srgrimes return (TRUE); 3801590Srgrimes 3811590Srgrimes case XDR_FREE: 3821590Srgrimes return (TRUE); 3831590Srgrimes } 3841590Srgrimes /* NOTREACHED */ 3851590Srgrimes return (FALSE); 3861590Srgrimes} 3871590Srgrimes 3881590Srgrimes/* 3891590Srgrimes * XDR unsigned 16-bit integers 3901590Srgrimes */ 3911590Srgrimesbool_t 3921590Srgrimesxdr_u_int16_t(xdrs, u_int16_p) 3931590Srgrimes XDR *xdrs; 3941590Srgrimes u_int16_t *u_int16_p; 3951590Srgrimes{ 3961590Srgrimes u_long l; 3971590Srgrimes 3981590Srgrimes switch (xdrs->x_op) { 3991590Srgrimes 4001590Srgrimes case XDR_ENCODE: 4011590Srgrimes l = (u_long) *u_int16_p; 4021590Srgrimes return (XDR_PUTLONG(xdrs, (long *)&l)); 4031590Srgrimes 4041590Srgrimes case XDR_DECODE: 4051590Srgrimes if (!XDR_GETLONG(xdrs, (long *)&l)) { 4061590Srgrimes return (FALSE); 4071590Srgrimes } 4081590Srgrimes *u_int16_p = (u_int16_t) l; 4091590Srgrimes return (TRUE); 4101590Srgrimes 4111590Srgrimes case XDR_FREE: 4121590Srgrimes return (TRUE); 4131590Srgrimes } 4141590Srgrimes /* NOTREACHED */ 4151590Srgrimes return (FALSE); 4161590Srgrimes} 4171590Srgrimes 4181590Srgrimes/* 4191590Srgrimes * XDR unsigned 16-bit integers 4201590Srgrimes */ 4211590Srgrimesbool_t 4221590Srgrimesxdr_uint16_t(xdrs, u_int16_p) 4231590Srgrimes XDR *xdrs; 4241590Srgrimes uint16_t *u_int16_p; 4251590Srgrimes{ 4261590Srgrimes u_long l; 4271590Srgrimes 4281590Srgrimes switch (xdrs->x_op) { 4291590Srgrimes 4301590Srgrimes case XDR_ENCODE: 4311590Srgrimes l = (u_long) *u_int16_p; 4321590Srgrimes return (XDR_PUTLONG(xdrs, (long *)&l)); 4331590Srgrimes 4341590Srgrimes case XDR_DECODE: 4351590Srgrimes if (!XDR_GETLONG(xdrs, (long *)&l)) { 4361590Srgrimes return (FALSE); 4371590Srgrimes } 4381590Srgrimes *u_int16_p = (u_int16_t) l; 4391590Srgrimes return (TRUE); 4401590Srgrimes 4411590Srgrimes case XDR_FREE: 4421590Srgrimes return (TRUE); 4431590Srgrimes } 4441590Srgrimes /* NOTREACHED */ 4451590Srgrimes return (FALSE); 4461590Srgrimes} 4471590Srgrimes 4481590Srgrimes 4491590Srgrimes/* 4501590Srgrimes * XDR a char 4511590Srgrimes */ 4521590Srgrimesbool_t 4531590Srgrimesxdr_char(xdrs, cp) 4541590Srgrimes XDR *xdrs; 4551590Srgrimes char *cp; 4561590Srgrimes{ 4571590Srgrimes int i; 4581590Srgrimes 4591590Srgrimes i = (*cp); 4601590Srgrimes if (!xdr_int(xdrs, &i)) { 4611590Srgrimes return (FALSE); 4621590Srgrimes } 4631590Srgrimes *cp = i; 4641590Srgrimes return (TRUE); 4651590Srgrimes} 4661590Srgrimes 4671590Srgrimes/* 4681590Srgrimes * XDR an unsigned char 4691590Srgrimes */ 4701590Srgrimesbool_t 4711590Srgrimesxdr_u_char(xdrs, cp) 472 XDR *xdrs; 473 u_char *cp; 474{ 475 u_int u; 476 477 u = (*cp); 478 if (!xdr_u_int(xdrs, &u)) { 479 return (FALSE); 480 } 481 *cp = u; 482 return (TRUE); 483} 484 485/* 486 * XDR booleans 487 */ 488bool_t 489xdr_bool(xdrs, bp) 490 XDR *xdrs; 491 bool_t *bp; 492{ 493 long lb; 494 495 switch (xdrs->x_op) { 496 497 case XDR_ENCODE: 498 lb = *bp ? XDR_TRUE : XDR_FALSE; 499 return (XDR_PUTLONG(xdrs, &lb)); 500 501 case XDR_DECODE: 502 if (!XDR_GETLONG(xdrs, &lb)) { 503 return (FALSE); 504 } 505 *bp = (lb == XDR_FALSE) ? FALSE : TRUE; 506 return (TRUE); 507 508 case XDR_FREE: 509 return (TRUE); 510 } 511 /* NOTREACHED */ 512 return (FALSE); 513} 514 515/* 516 * XDR enumerations 517 */ 518bool_t 519xdr_enum(xdrs, ep) 520 XDR *xdrs; 521 enum_t *ep; 522{ 523 enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ 524 525 /* 526 * enums are treated as ints 527 */ 528 /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) { 529 return (xdr_long(xdrs, (long *)(void *)ep)); 530 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) { 531 return (xdr_int(xdrs, (int *)(void *)ep)); 532 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) { 533 return (xdr_short(xdrs, (short *)(void *)ep)); 534 } else { 535 return (FALSE); 536 } 537} 538 539/* 540 * XDR opaque data 541 * Allows the specification of a fixed size sequence of opaque bytes. 542 * cp points to the opaque object and cnt gives the byte length. 543 */ 544bool_t 545xdr_opaque(xdrs, cp, cnt) 546 XDR *xdrs; 547 caddr_t cp; 548 u_int cnt; 549{ 550 u_int rndup; 551 static int crud[BYTES_PER_XDR_UNIT]; 552 553 /* 554 * if no data we are done 555 */ 556 if (cnt == 0) 557 return (TRUE); 558 559 /* 560 * round byte count to full xdr units 561 */ 562 rndup = cnt % BYTES_PER_XDR_UNIT; 563 if (rndup > 0) 564 rndup = BYTES_PER_XDR_UNIT - rndup; 565 566 if (xdrs->x_op == XDR_DECODE) { 567 if (!XDR_GETBYTES(xdrs, cp, cnt)) { 568 return (FALSE); 569 } 570 if (rndup == 0) 571 return (TRUE); 572 return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup)); 573 } 574 575 if (xdrs->x_op == XDR_ENCODE) { 576 if (!XDR_PUTBYTES(xdrs, cp, cnt)) { 577 return (FALSE); 578 } 579 if (rndup == 0) 580 return (TRUE); 581 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); 582 } 583 584 if (xdrs->x_op == XDR_FREE) { 585 return (TRUE); 586 } 587 588 return (FALSE); 589} 590 591/* 592 * XDR counted bytes 593 * *cpp is a pointer to the bytes, *sizep is the count. 594 * If *cpp is NULL maxsize bytes are allocated 595 */ 596bool_t 597xdr_bytes(xdrs, cpp, sizep, maxsize) 598 XDR *xdrs; 599 char **cpp; 600 u_int *sizep; 601 u_int maxsize; 602{ 603 char *sp = *cpp; /* sp is the actual string pointer */ 604 u_int nodesize; 605 606 /* 607 * first deal with the length since xdr bytes are counted 608 */ 609 if (! xdr_u_int(xdrs, sizep)) { 610 return (FALSE); 611 } 612 nodesize = *sizep; 613 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { 614 return (FALSE); 615 } 616 617 /* 618 * now deal with the actual bytes 619 */ 620 switch (xdrs->x_op) { 621 622 case XDR_DECODE: 623 if (nodesize == 0) { 624 return (TRUE); 625 } 626 if (sp == NULL) { 627 *cpp = sp = mem_alloc(nodesize); 628 } 629 if (sp == NULL) { 630 warnx("xdr_bytes: out of memory"); 631 return (FALSE); 632 } 633 /* FALLTHROUGH */ 634 635 case XDR_ENCODE: 636 return (xdr_opaque(xdrs, sp, nodesize)); 637 638 case XDR_FREE: 639 if (sp != NULL) { 640 mem_free(sp, nodesize); 641 *cpp = NULL; 642 } 643 return (TRUE); 644 } 645 /* NOTREACHED */ 646 return (FALSE); 647} 648 649/* 650 * Implemented here due to commonality of the object. 651 */ 652bool_t 653xdr_netobj(xdrs, np) 654 XDR *xdrs; 655 struct netobj *np; 656{ 657 658 return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); 659} 660 661/* 662 * XDR a descriminated union 663 * Support routine for discriminated unions. 664 * You create an array of xdrdiscrim structures, terminated with 665 * an entry with a null procedure pointer. The routine gets 666 * the discriminant value and then searches the array of xdrdiscrims 667 * looking for that value. It calls the procedure given in the xdrdiscrim 668 * to handle the discriminant. If there is no specific routine a default 669 * routine may be called. 670 * If there is no specific or default routine an error is returned. 671 */ 672bool_t 673xdr_union(xdrs, dscmp, unp, choices, dfault) 674 XDR *xdrs; 675 enum_t *dscmp; /* enum to decide which arm to work on */ 676 char *unp; /* the union itself */ 677 const struct xdr_discrim *choices; /* [value, xdr proc] for each arm */ 678 xdrproc_t dfault; /* default xdr routine */ 679{ 680 enum_t dscm; 681 682 /* 683 * we deal with the discriminator; it's an enum 684 */ 685 if (! xdr_enum(xdrs, dscmp)) { 686 return (FALSE); 687 } 688 dscm = *dscmp; 689 690 /* 691 * search choices for a value that matches the discriminator. 692 * if we find one, execute the xdr routine for that value. 693 */ 694 for (; choices->proc != NULL_xdrproc_t; choices++) { 695 if (choices->value == dscm) 696 return ((*(choices->proc))(xdrs, unp)); 697 } 698 699 /* 700 * no match - execute the default xdr routine if there is one 701 */ 702 return ((dfault == NULL_xdrproc_t) ? FALSE : 703 (*dfault)(xdrs, unp)); 704} 705 706 707/* 708 * Non-portable xdr primitives. 709 * Care should be taken when moving these routines to new architectures. 710 */ 711 712 713/* 714 * XDR null terminated ASCII strings 715 * xdr_string deals with "C strings" - arrays of bytes that are 716 * terminated by a NULL character. The parameter cpp references a 717 * pointer to storage; If the pointer is null, then the necessary 718 * storage is allocated. The last parameter is the max allowed length 719 * of the string as specified by a protocol. 720 */ 721bool_t 722xdr_string(xdrs, cpp, maxsize) 723 XDR *xdrs; 724 char **cpp; 725 u_int maxsize; 726{ 727 char *sp = *cpp; /* sp is the actual string pointer */ 728 u_int size; 729 u_int nodesize; 730 731 /* 732 * first deal with the length since xdr strings are counted-strings 733 */ 734 switch (xdrs->x_op) { 735 case XDR_FREE: 736 if (sp == NULL) { 737 return(TRUE); /* already free */ 738 } 739 /* FALLTHROUGH */ 740 case XDR_ENCODE: 741 size = strlen(sp); 742 break; 743 case XDR_DECODE: 744 break; 745 } 746 if (! xdr_u_int(xdrs, &size)) { 747 return (FALSE); 748 } 749 if (size > maxsize) { 750 return (FALSE); 751 } 752 nodesize = size + 1; 753 754 /* 755 * now deal with the actual bytes 756 */ 757 switch (xdrs->x_op) { 758 759 case XDR_DECODE: 760 if (nodesize == 0) { 761 return (TRUE); 762 } 763 if (sp == NULL) 764 *cpp = sp = mem_alloc(nodesize); 765 if (sp == NULL) { 766 warnx("xdr_string: out of memory"); 767 return (FALSE); 768 } 769 sp[size] = 0; 770 /* FALLTHROUGH */ 771 772 case XDR_ENCODE: 773 return (xdr_opaque(xdrs, sp, size)); 774 775 case XDR_FREE: 776 mem_free(sp, nodesize); 777 *cpp = NULL; 778 return (TRUE); 779 } 780 /* NOTREACHED */ 781 return (FALSE); 782} 783 784/* 785 * Wrapper for xdr_string that can be called directly from 786 * routines like clnt_call 787 */ 788bool_t 789xdr_wrapstring(xdrs, cpp) 790 XDR *xdrs; 791 char **cpp; 792{ 793 return xdr_string(xdrs, cpp, LASTUNSIGNED); 794} 795 796/* 797 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t() 798 * are in the "non-portable" section because they require that a `long long' 799 * be a 64-bit type. 800 * 801 * --thorpej@netbsd.org, November 30, 1999 802 */ 803 804/* 805 * XDR 64-bit integers 806 */ 807bool_t 808xdr_int64_t(xdrs, llp) 809 XDR *xdrs; 810 int64_t *llp; 811{ 812 u_long ul[2]; 813 814 switch (xdrs->x_op) { 815 case XDR_ENCODE: 816 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff; 817 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff; 818 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 819 return (FALSE); 820 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 821 case XDR_DECODE: 822 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 823 return (FALSE); 824 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 825 return (FALSE); 826 *llp = (int64_t) 827 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 828 return (TRUE); 829 case XDR_FREE: 830 return (TRUE); 831 } 832 /* NOTREACHED */ 833 return (FALSE); 834} 835 836 837/* 838 * XDR unsigned 64-bit integers 839 */ 840bool_t 841xdr_u_int64_t(xdrs, ullp) 842 XDR *xdrs; 843 u_int64_t *ullp; 844{ 845 u_long ul[2]; 846 847 switch (xdrs->x_op) { 848 case XDR_ENCODE: 849 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 850 ul[1] = (u_long)(*ullp) & 0xffffffff; 851 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 852 return (FALSE); 853 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 854 case XDR_DECODE: 855 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 856 return (FALSE); 857 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 858 return (FALSE); 859 *ullp = (u_int64_t) 860 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 861 return (TRUE); 862 case XDR_FREE: 863 return (TRUE); 864 } 865 /* NOTREACHED */ 866 return (FALSE); 867} 868 869/* 870 * XDR unsigned 64-bit integers 871 */ 872bool_t 873xdr_uint64_t(xdrs, ullp) 874 XDR *xdrs; 875 uint64_t *ullp; 876{ 877 u_long ul[2]; 878 879 switch (xdrs->x_op) { 880 case XDR_ENCODE: 881 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 882 ul[1] = (u_long)(*ullp) & 0xffffffff; 883 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 884 return (FALSE); 885 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 886 case XDR_DECODE: 887 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 888 return (FALSE); 889 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 890 return (FALSE); 891 *ullp = (u_int64_t) 892 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 893 return (TRUE); 894 case XDR_FREE: 895 return (TRUE); 896 } 897 /* NOTREACHED */ 898 return (FALSE); 899} 900 901 902/* 903 * XDR hypers 904 */ 905bool_t 906xdr_hyper(xdrs, llp) 907 XDR *xdrs; 908 longlong_t *llp; 909{ 910 911 /* 912 * Don't bother open-coding this; it's a fair amount of code. Just 913 * call xdr_int64_t(). 914 */ 915 return (xdr_int64_t(xdrs, (int64_t *)llp)); 916} 917 918 919/* 920 * XDR unsigned hypers 921 */ 922bool_t 923xdr_u_hyper(xdrs, ullp) 924 XDR *xdrs; 925 u_longlong_t *ullp; 926{ 927 928 /* 929 * Don't bother open-coding this; it's a fair amount of code. Just 930 * call xdr_u_int64_t(). 931 */ 932 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 933} 934 935 936/* 937 * XDR longlong_t's 938 */ 939bool_t 940xdr_longlong_t(xdrs, llp) 941 XDR *xdrs; 942 longlong_t *llp; 943{ 944 945 /* 946 * Don't bother open-coding this; it's a fair amount of code. Just 947 * call xdr_int64_t(). 948 */ 949 return (xdr_int64_t(xdrs, (int64_t *)llp)); 950} 951 952 953/* 954 * XDR u_longlong_t's 955 */ 956bool_t 957xdr_u_longlong_t(xdrs, ullp) 958 XDR *xdrs; 959 u_longlong_t *ullp; 960{ 961 962 /* 963 * Don't bother open-coding this; it's a fair amount of code. Just 964 * call xdr_u_int64_t(). 965 */ 966 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 967} 968