1*45095Smckusick /* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */ 2*45095Smckusick /* 3*45095Smckusick * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4*45095Smckusick * unrestricted use provided that this legend is included on all tape 5*45095Smckusick * media and as a part of the software program in whole or part. Users 6*45095Smckusick * may copy or modify Sun RPC without charge, but are not authorized 7*45095Smckusick * to license or distribute it to anyone else except as part of a product or 8*45095Smckusick * program developed by the user. 9*45095Smckusick * 10*45095Smckusick * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11*45095Smckusick * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12*45095Smckusick * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13*45095Smckusick * 14*45095Smckusick * Sun RPC is provided with no support and without any obligation on the 15*45095Smckusick * part of Sun Microsystems, Inc. to assist in its use, correction, 16*45095Smckusick * modification or enhancement. 17*45095Smckusick * 18*45095Smckusick * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19*45095Smckusick * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20*45095Smckusick * OR ANY PART THEREOF. 21*45095Smckusick * 22*45095Smckusick * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23*45095Smckusick * or profits or other special, indirect and consequential damages, even if 24*45095Smckusick * Sun has been advised of the possibility of such damages. 25*45095Smckusick * 26*45095Smckusick * Sun Microsystems, Inc. 27*45095Smckusick * 2550 Garcia Avenue 28*45095Smckusick * Mountain View, California 94043 29*45095Smckusick */ 30*45095Smckusick #if !defined(lint) && defined(SCCSIDS) 31*45095Smckusick static char sccsid[] = "@(#)xdr.c 1.35 87/08/12"; 32*45095Smckusick #endif 33*45095Smckusick 34*45095Smckusick /* 35*45095Smckusick * xdr.c, Generic XDR routines implementation. 36*45095Smckusick * 37*45095Smckusick * Copyright (C) 1986, Sun Microsystems, Inc. 38*45095Smckusick * 39*45095Smckusick * These are the "generic" xdr routines used to serialize and de-serialize 40*45095Smckusick * most common data items. See xdr.h for more info on the interface to 41*45095Smckusick * xdr. 42*45095Smckusick */ 43*45095Smckusick 44*45095Smckusick #include <stdio.h> 45*45095Smckusick char *malloc(); 46*45095Smckusick 47*45095Smckusick #include <rpc/types.h> 48*45095Smckusick #include <rpc/xdr.h> 49*45095Smckusick 50*45095Smckusick /* 51*45095Smckusick * constants specific to the xdr "protocol" 52*45095Smckusick */ 53*45095Smckusick #define XDR_FALSE ((long) 0) 54*45095Smckusick #define XDR_TRUE ((long) 1) 55*45095Smckusick #define LASTUNSIGNED ((u_int) 0-1) 56*45095Smckusick 57*45095Smckusick /* 58*45095Smckusick * for unit alignment 59*45095Smckusick */ 60*45095Smckusick static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; 61*45095Smckusick 62*45095Smckusick /* 63*45095Smckusick * Free a data structure using XDR 64*45095Smckusick * Not a filter, but a convenient utility nonetheless 65*45095Smckusick */ 66*45095Smckusick void 67*45095Smckusick xdr_free(proc, objp) 68*45095Smckusick xdrproc_t proc; 69*45095Smckusick char *objp; 70*45095Smckusick { 71*45095Smckusick XDR x; 72*45095Smckusick 73*45095Smckusick x.x_op = XDR_FREE; 74*45095Smckusick (*proc)(&x, objp); 75*45095Smckusick } 76*45095Smckusick 77*45095Smckusick /* 78*45095Smckusick * XDR nothing 79*45095Smckusick */ 80*45095Smckusick bool_t 81*45095Smckusick xdr_void(/* xdrs, addr */) 82*45095Smckusick /* XDR *xdrs; */ 83*45095Smckusick /* caddr_t addr; */ 84*45095Smckusick { 85*45095Smckusick 86*45095Smckusick return (TRUE); 87*45095Smckusick } 88*45095Smckusick 89*45095Smckusick /* 90*45095Smckusick * XDR integers 91*45095Smckusick */ 92*45095Smckusick bool_t 93*45095Smckusick xdr_int(xdrs, ip) 94*45095Smckusick XDR *xdrs; 95*45095Smckusick int *ip; 96*45095Smckusick { 97*45095Smckusick 98*45095Smckusick #ifdef lint 99*45095Smckusick (void) (xdr_short(xdrs, (short *)ip)); 100*45095Smckusick return (xdr_long(xdrs, (long *)ip)); 101*45095Smckusick #else 102*45095Smckusick if (sizeof (int) == sizeof (long)) { 103*45095Smckusick return (xdr_long(xdrs, (long *)ip)); 104*45095Smckusick } else { 105*45095Smckusick return (xdr_short(xdrs, (short *)ip)); 106*45095Smckusick } 107*45095Smckusick #endif 108*45095Smckusick } 109*45095Smckusick 110*45095Smckusick /* 111*45095Smckusick * XDR unsigned integers 112*45095Smckusick */ 113*45095Smckusick bool_t 114*45095Smckusick xdr_u_int(xdrs, up) 115*45095Smckusick XDR *xdrs; 116*45095Smckusick u_int *up; 117*45095Smckusick { 118*45095Smckusick 119*45095Smckusick #ifdef lint 120*45095Smckusick (void) (xdr_short(xdrs, (short *)up)); 121*45095Smckusick return (xdr_u_long(xdrs, (u_long *)up)); 122*45095Smckusick #else 123*45095Smckusick if (sizeof (u_int) == sizeof (u_long)) { 124*45095Smckusick return (xdr_u_long(xdrs, (u_long *)up)); 125*45095Smckusick } else { 126*45095Smckusick return (xdr_short(xdrs, (short *)up)); 127*45095Smckusick } 128*45095Smckusick #endif 129*45095Smckusick } 130*45095Smckusick 131*45095Smckusick /* 132*45095Smckusick * XDR long integers 133*45095Smckusick * same as xdr_u_long - open coded to save a proc call! 134*45095Smckusick */ 135*45095Smckusick bool_t 136*45095Smckusick xdr_long(xdrs, lp) 137*45095Smckusick register XDR *xdrs; 138*45095Smckusick long *lp; 139*45095Smckusick { 140*45095Smckusick 141*45095Smckusick if (xdrs->x_op == XDR_ENCODE) 142*45095Smckusick return (XDR_PUTLONG(xdrs, lp)); 143*45095Smckusick 144*45095Smckusick if (xdrs->x_op == XDR_DECODE) 145*45095Smckusick return (XDR_GETLONG(xdrs, lp)); 146*45095Smckusick 147*45095Smckusick if (xdrs->x_op == XDR_FREE) 148*45095Smckusick return (TRUE); 149*45095Smckusick 150*45095Smckusick return (FALSE); 151*45095Smckusick } 152*45095Smckusick 153*45095Smckusick /* 154*45095Smckusick * XDR unsigned long integers 155*45095Smckusick * same as xdr_long - open coded to save a proc call! 156*45095Smckusick */ 157*45095Smckusick bool_t 158*45095Smckusick xdr_u_long(xdrs, ulp) 159*45095Smckusick register XDR *xdrs; 160*45095Smckusick u_long *ulp; 161*45095Smckusick { 162*45095Smckusick 163*45095Smckusick if (xdrs->x_op == XDR_DECODE) 164*45095Smckusick return (XDR_GETLONG(xdrs, (long *)ulp)); 165*45095Smckusick if (xdrs->x_op == XDR_ENCODE) 166*45095Smckusick return (XDR_PUTLONG(xdrs, (long *)ulp)); 167*45095Smckusick if (xdrs->x_op == XDR_FREE) 168*45095Smckusick return (TRUE); 169*45095Smckusick return (FALSE); 170*45095Smckusick } 171*45095Smckusick 172*45095Smckusick /* 173*45095Smckusick * XDR short integers 174*45095Smckusick */ 175*45095Smckusick bool_t 176*45095Smckusick xdr_short(xdrs, sp) 177*45095Smckusick register XDR *xdrs; 178*45095Smckusick short *sp; 179*45095Smckusick { 180*45095Smckusick long l; 181*45095Smckusick 182*45095Smckusick switch (xdrs->x_op) { 183*45095Smckusick 184*45095Smckusick case XDR_ENCODE: 185*45095Smckusick l = (long) *sp; 186*45095Smckusick return (XDR_PUTLONG(xdrs, &l)); 187*45095Smckusick 188*45095Smckusick case XDR_DECODE: 189*45095Smckusick if (!XDR_GETLONG(xdrs, &l)) { 190*45095Smckusick return (FALSE); 191*45095Smckusick } 192*45095Smckusick *sp = (short) l; 193*45095Smckusick return (TRUE); 194*45095Smckusick 195*45095Smckusick case XDR_FREE: 196*45095Smckusick return (TRUE); 197*45095Smckusick } 198*45095Smckusick return (FALSE); 199*45095Smckusick } 200*45095Smckusick 201*45095Smckusick /* 202*45095Smckusick * XDR unsigned short integers 203*45095Smckusick */ 204*45095Smckusick bool_t 205*45095Smckusick xdr_u_short(xdrs, usp) 206*45095Smckusick register XDR *xdrs; 207*45095Smckusick u_short *usp; 208*45095Smckusick { 209*45095Smckusick u_long l; 210*45095Smckusick 211*45095Smckusick switch (xdrs->x_op) { 212*45095Smckusick 213*45095Smckusick case XDR_ENCODE: 214*45095Smckusick l = (u_long) *usp; 215*45095Smckusick return (XDR_PUTLONG(xdrs, &l)); 216*45095Smckusick 217*45095Smckusick case XDR_DECODE: 218*45095Smckusick if (!XDR_GETLONG(xdrs, &l)) { 219*45095Smckusick return (FALSE); 220*45095Smckusick } 221*45095Smckusick *usp = (u_short) l; 222*45095Smckusick return (TRUE); 223*45095Smckusick 224*45095Smckusick case XDR_FREE: 225*45095Smckusick return (TRUE); 226*45095Smckusick } 227*45095Smckusick return (FALSE); 228*45095Smckusick } 229*45095Smckusick 230*45095Smckusick 231*45095Smckusick /* 232*45095Smckusick * XDR a char 233*45095Smckusick */ 234*45095Smckusick bool_t 235*45095Smckusick xdr_char(xdrs, cp) 236*45095Smckusick XDR *xdrs; 237*45095Smckusick char *cp; 238*45095Smckusick { 239*45095Smckusick int i; 240*45095Smckusick 241*45095Smckusick i = (*cp); 242*45095Smckusick if (!xdr_int(xdrs, &i)) { 243*45095Smckusick return (FALSE); 244*45095Smckusick } 245*45095Smckusick *cp = i; 246*45095Smckusick return (TRUE); 247*45095Smckusick } 248*45095Smckusick 249*45095Smckusick /* 250*45095Smckusick * XDR an unsigned char 251*45095Smckusick */ 252*45095Smckusick bool_t 253*45095Smckusick xdr_u_char(xdrs, cp) 254*45095Smckusick XDR *xdrs; 255*45095Smckusick char *cp; 256*45095Smckusick { 257*45095Smckusick u_int u; 258*45095Smckusick 259*45095Smckusick u = (*cp); 260*45095Smckusick if (!xdr_u_int(xdrs, &u)) { 261*45095Smckusick return (FALSE); 262*45095Smckusick } 263*45095Smckusick *cp = u; 264*45095Smckusick return (TRUE); 265*45095Smckusick } 266*45095Smckusick 267*45095Smckusick /* 268*45095Smckusick * XDR booleans 269*45095Smckusick */ 270*45095Smckusick bool_t 271*45095Smckusick xdr_bool(xdrs, bp) 272*45095Smckusick register XDR *xdrs; 273*45095Smckusick bool_t *bp; 274*45095Smckusick { 275*45095Smckusick long lb; 276*45095Smckusick 277*45095Smckusick switch (xdrs->x_op) { 278*45095Smckusick 279*45095Smckusick case XDR_ENCODE: 280*45095Smckusick lb = *bp ? XDR_TRUE : XDR_FALSE; 281*45095Smckusick return (XDR_PUTLONG(xdrs, &lb)); 282*45095Smckusick 283*45095Smckusick case XDR_DECODE: 284*45095Smckusick if (!XDR_GETLONG(xdrs, &lb)) { 285*45095Smckusick return (FALSE); 286*45095Smckusick } 287*45095Smckusick *bp = (lb == XDR_FALSE) ? FALSE : TRUE; 288*45095Smckusick return (TRUE); 289*45095Smckusick 290*45095Smckusick case XDR_FREE: 291*45095Smckusick return (TRUE); 292*45095Smckusick } 293*45095Smckusick return (FALSE); 294*45095Smckusick } 295*45095Smckusick 296*45095Smckusick /* 297*45095Smckusick * XDR enumerations 298*45095Smckusick */ 299*45095Smckusick bool_t 300*45095Smckusick xdr_enum(xdrs, ep) 301*45095Smckusick XDR *xdrs; 302*45095Smckusick enum_t *ep; 303*45095Smckusick { 304*45095Smckusick #ifndef lint 305*45095Smckusick enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ 306*45095Smckusick 307*45095Smckusick /* 308*45095Smckusick * enums are treated as ints 309*45095Smckusick */ 310*45095Smckusick if (sizeof (enum sizecheck) == sizeof (long)) { 311*45095Smckusick return (xdr_long(xdrs, (long *)ep)); 312*45095Smckusick } else if (sizeof (enum sizecheck) == sizeof (short)) { 313*45095Smckusick return (xdr_short(xdrs, (short *)ep)); 314*45095Smckusick } else { 315*45095Smckusick return (FALSE); 316*45095Smckusick } 317*45095Smckusick #else 318*45095Smckusick (void) (xdr_short(xdrs, (short *)ep)); 319*45095Smckusick return (xdr_long(xdrs, (long *)ep)); 320*45095Smckusick #endif 321*45095Smckusick } 322*45095Smckusick 323*45095Smckusick /* 324*45095Smckusick * XDR opaque data 325*45095Smckusick * Allows the specification of a fixed size sequence of opaque bytes. 326*45095Smckusick * cp points to the opaque object and cnt gives the byte length. 327*45095Smckusick */ 328*45095Smckusick bool_t 329*45095Smckusick xdr_opaque(xdrs, cp, cnt) 330*45095Smckusick register XDR *xdrs; 331*45095Smckusick caddr_t cp; 332*45095Smckusick register u_int cnt; 333*45095Smckusick { 334*45095Smckusick register u_int rndup; 335*45095Smckusick static crud[BYTES_PER_XDR_UNIT]; 336*45095Smckusick 337*45095Smckusick /* 338*45095Smckusick * if no data we are done 339*45095Smckusick */ 340*45095Smckusick if (cnt == 0) 341*45095Smckusick return (TRUE); 342*45095Smckusick 343*45095Smckusick /* 344*45095Smckusick * round byte count to full xdr units 345*45095Smckusick */ 346*45095Smckusick rndup = cnt % BYTES_PER_XDR_UNIT; 347*45095Smckusick if (rndup > 0) 348*45095Smckusick rndup = BYTES_PER_XDR_UNIT - rndup; 349*45095Smckusick 350*45095Smckusick if (xdrs->x_op == XDR_DECODE) { 351*45095Smckusick if (!XDR_GETBYTES(xdrs, cp, cnt)) { 352*45095Smckusick return (FALSE); 353*45095Smckusick } 354*45095Smckusick if (rndup == 0) 355*45095Smckusick return (TRUE); 356*45095Smckusick return (XDR_GETBYTES(xdrs, crud, rndup)); 357*45095Smckusick } 358*45095Smckusick 359*45095Smckusick if (xdrs->x_op == XDR_ENCODE) { 360*45095Smckusick if (!XDR_PUTBYTES(xdrs, cp, cnt)) { 361*45095Smckusick return (FALSE); 362*45095Smckusick } 363*45095Smckusick if (rndup == 0) 364*45095Smckusick return (TRUE); 365*45095Smckusick return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); 366*45095Smckusick } 367*45095Smckusick 368*45095Smckusick if (xdrs->x_op == XDR_FREE) { 369*45095Smckusick return (TRUE); 370*45095Smckusick } 371*45095Smckusick 372*45095Smckusick return (FALSE); 373*45095Smckusick } 374*45095Smckusick 375*45095Smckusick /* 376*45095Smckusick * XDR counted bytes 377*45095Smckusick * *cpp is a pointer to the bytes, *sizep is the count. 378*45095Smckusick * If *cpp is NULL maxsize bytes are allocated 379*45095Smckusick */ 380*45095Smckusick bool_t 381*45095Smckusick xdr_bytes(xdrs, cpp, sizep, maxsize) 382*45095Smckusick register XDR *xdrs; 383*45095Smckusick char **cpp; 384*45095Smckusick register u_int *sizep; 385*45095Smckusick u_int maxsize; 386*45095Smckusick { 387*45095Smckusick register char *sp = *cpp; /* sp is the actual string pointer */ 388*45095Smckusick register u_int nodesize; 389*45095Smckusick 390*45095Smckusick /* 391*45095Smckusick * first deal with the length since xdr bytes are counted 392*45095Smckusick */ 393*45095Smckusick if (! xdr_u_int(xdrs, sizep)) { 394*45095Smckusick return (FALSE); 395*45095Smckusick } 396*45095Smckusick nodesize = *sizep; 397*45095Smckusick if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { 398*45095Smckusick return (FALSE); 399*45095Smckusick } 400*45095Smckusick 401*45095Smckusick /* 402*45095Smckusick * now deal with the actual bytes 403*45095Smckusick */ 404*45095Smckusick switch (xdrs->x_op) { 405*45095Smckusick 406*45095Smckusick case XDR_DECODE: 407*45095Smckusick if (nodesize == 0) { 408*45095Smckusick return (TRUE); 409*45095Smckusick } 410*45095Smckusick if (sp == NULL) { 411*45095Smckusick *cpp = sp = (char *)mem_alloc(nodesize); 412*45095Smckusick } 413*45095Smckusick if (sp == NULL) { 414*45095Smckusick (void) fprintf(stderr, "xdr_bytes: out of memory\n"); 415*45095Smckusick return (FALSE); 416*45095Smckusick } 417*45095Smckusick /* fall into ... */ 418*45095Smckusick 419*45095Smckusick case XDR_ENCODE: 420*45095Smckusick return (xdr_opaque(xdrs, sp, nodesize)); 421*45095Smckusick 422*45095Smckusick case XDR_FREE: 423*45095Smckusick if (sp != NULL) { 424*45095Smckusick mem_free(sp, nodesize); 425*45095Smckusick *cpp = NULL; 426*45095Smckusick } 427*45095Smckusick return (TRUE); 428*45095Smckusick } 429*45095Smckusick return (FALSE); 430*45095Smckusick } 431*45095Smckusick 432*45095Smckusick /* 433*45095Smckusick * Implemented here due to commonality of the object. 434*45095Smckusick */ 435*45095Smckusick bool_t 436*45095Smckusick xdr_netobj(xdrs, np) 437*45095Smckusick XDR *xdrs; 438*45095Smckusick struct netobj *np; 439*45095Smckusick { 440*45095Smckusick 441*45095Smckusick return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); 442*45095Smckusick } 443*45095Smckusick 444*45095Smckusick /* 445*45095Smckusick * XDR a descriminated union 446*45095Smckusick * Support routine for discriminated unions. 447*45095Smckusick * You create an array of xdrdiscrim structures, terminated with 448*45095Smckusick * an entry with a null procedure pointer. The routine gets 449*45095Smckusick * the discriminant value and then searches the array of xdrdiscrims 450*45095Smckusick * looking for that value. It calls the procedure given in the xdrdiscrim 451*45095Smckusick * to handle the discriminant. If there is no specific routine a default 452*45095Smckusick * routine may be called. 453*45095Smckusick * If there is no specific or default routine an error is returned. 454*45095Smckusick */ 455*45095Smckusick bool_t 456*45095Smckusick xdr_union(xdrs, dscmp, unp, choices, dfault) 457*45095Smckusick register XDR *xdrs; 458*45095Smckusick enum_t *dscmp; /* enum to decide which arm to work on */ 459*45095Smckusick char *unp; /* the union itself */ 460*45095Smckusick struct xdr_discrim *choices; /* [value, xdr proc] for each arm */ 461*45095Smckusick xdrproc_t dfault; /* default xdr routine */ 462*45095Smckusick { 463*45095Smckusick register enum_t dscm; 464*45095Smckusick 465*45095Smckusick /* 466*45095Smckusick * we deal with the discriminator; it's an enum 467*45095Smckusick */ 468*45095Smckusick if (! xdr_enum(xdrs, dscmp)) { 469*45095Smckusick return (FALSE); 470*45095Smckusick } 471*45095Smckusick dscm = *dscmp; 472*45095Smckusick 473*45095Smckusick /* 474*45095Smckusick * search choices for a value that matches the discriminator. 475*45095Smckusick * if we find one, execute the xdr routine for that value. 476*45095Smckusick */ 477*45095Smckusick for (; choices->proc != NULL_xdrproc_t; choices++) { 478*45095Smckusick if (choices->value == dscm) 479*45095Smckusick return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); 480*45095Smckusick } 481*45095Smckusick 482*45095Smckusick /* 483*45095Smckusick * no match - execute the default xdr routine if there is one 484*45095Smckusick */ 485*45095Smckusick return ((dfault == NULL_xdrproc_t) ? FALSE : 486*45095Smckusick (*dfault)(xdrs, unp, LASTUNSIGNED)); 487*45095Smckusick } 488*45095Smckusick 489*45095Smckusick 490*45095Smckusick /* 491*45095Smckusick * Non-portable xdr primitives. 492*45095Smckusick * Care should be taken when moving these routines to new architectures. 493*45095Smckusick */ 494*45095Smckusick 495*45095Smckusick 496*45095Smckusick /* 497*45095Smckusick * XDR null terminated ASCII strings 498*45095Smckusick * xdr_string deals with "C strings" - arrays of bytes that are 499*45095Smckusick * terminated by a NULL character. The parameter cpp references a 500*45095Smckusick * pointer to storage; If the pointer is null, then the necessary 501*45095Smckusick * storage is allocated. The last parameter is the max allowed length 502*45095Smckusick * of the string as specified by a protocol. 503*45095Smckusick */ 504*45095Smckusick bool_t 505*45095Smckusick xdr_string(xdrs, cpp, maxsize) 506*45095Smckusick register XDR *xdrs; 507*45095Smckusick char **cpp; 508*45095Smckusick u_int maxsize; 509*45095Smckusick { 510*45095Smckusick register char *sp = *cpp; /* sp is the actual string pointer */ 511*45095Smckusick u_int size; 512*45095Smckusick u_int nodesize; 513*45095Smckusick 514*45095Smckusick /* 515*45095Smckusick * first deal with the length since xdr strings are counted-strings 516*45095Smckusick */ 517*45095Smckusick switch (xdrs->x_op) { 518*45095Smckusick case XDR_FREE: 519*45095Smckusick if (sp == NULL) { 520*45095Smckusick return(TRUE); /* already free */ 521*45095Smckusick } 522*45095Smckusick /* fall through... */ 523*45095Smckusick case XDR_ENCODE: 524*45095Smckusick size = strlen(sp); 525*45095Smckusick break; 526*45095Smckusick } 527*45095Smckusick if (! xdr_u_int(xdrs, &size)) { 528*45095Smckusick return (FALSE); 529*45095Smckusick } 530*45095Smckusick if (size > maxsize) { 531*45095Smckusick return (FALSE); 532*45095Smckusick } 533*45095Smckusick nodesize = size + 1; 534*45095Smckusick 535*45095Smckusick /* 536*45095Smckusick * now deal with the actual bytes 537*45095Smckusick */ 538*45095Smckusick switch (xdrs->x_op) { 539*45095Smckusick 540*45095Smckusick case XDR_DECODE: 541*45095Smckusick if (nodesize == 0) { 542*45095Smckusick return (TRUE); 543*45095Smckusick } 544*45095Smckusick if (sp == NULL) 545*45095Smckusick *cpp = sp = (char *)mem_alloc(nodesize); 546*45095Smckusick if (sp == NULL) { 547*45095Smckusick (void) fprintf(stderr, "xdr_string: out of memory\n"); 548*45095Smckusick return (FALSE); 549*45095Smckusick } 550*45095Smckusick sp[size] = 0; 551*45095Smckusick /* fall into ... */ 552*45095Smckusick 553*45095Smckusick case XDR_ENCODE: 554*45095Smckusick return (xdr_opaque(xdrs, sp, size)); 555*45095Smckusick 556*45095Smckusick case XDR_FREE: 557*45095Smckusick mem_free(sp, nodesize); 558*45095Smckusick *cpp = NULL; 559*45095Smckusick return (TRUE); 560*45095Smckusick } 561*45095Smckusick return (FALSE); 562*45095Smckusick } 563*45095Smckusick 564*45095Smckusick /* 565*45095Smckusick * Wrapper for xdr_string that can be called directly from 566*45095Smckusick * routines like clnt_call 567*45095Smckusick */ 568*45095Smckusick bool_t 569*45095Smckusick xdr_wrapstring(xdrs, cpp) 570*45095Smckusick XDR *xdrs; 571*45095Smckusick char **cpp; 572*45095Smckusick { 573*45095Smckusick if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { 574*45095Smckusick return (TRUE); 575*45095Smckusick } 576*45095Smckusick return (FALSE); 577*45095Smckusick } 578