|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.