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

Defined functions

xdr_bool defined in line 209; used 2 times
xdr_enum defined in line 238; used 9 times
xdr_int defined in line 77; used 4 times
xdr_long defined in line 110; used 3 times
xdr_opaque defined in line 259; used 4 times
xdr_short defined in line 150; used 4 times
xdr_string defined in line 420; used 3 times
xdr_u_int defined in line 93; used 4 times
xdr_u_short defined in line 179; used 1 times
xdr_union defined in line 371; used 2 times
xdr_void defined in line 65; used 1 times
xdr_wrapstring defined in line 476; used 1 times

Defined variables

sccsid defined in line 30; never used
xdr_zero defined in line 59; used 1 times

Defined macros

LASTUNSIGNED defined in line 54; used 2 times
XDR_FALSE defined in line 52; used 2 times
XDR_TRUE defined in line 53; used 1 times
Last modified: 1985-04-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1699
Valid CSS Valid XHTML 1.0 Strict