home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / utils / sossntr3 / src / xdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  10.3 KB  |  504 lines

  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.1 86/02/03 Copyr 1984 Sun Micro";
  31. #endif
  32.  
  33. /*
  34.  * xdr.c, Generic XDR routines implementation.
  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 <stdio.h>
  44. #include <malloc.h>
  45. #include <string.h>
  46. #include <winsock.h>
  47. #include "types.h"
  48. #include "xdr.h"
  49.  
  50. /*
  51.  * constants specific to the xdr "protocol"
  52.  */
  53. #define XDR_FALSE    ((long) 0)
  54. #define XDR_TRUE    ((long) 1)
  55. #define LASTUNSIGNED    ((u_int) 0-1)
  56.  
  57. /*
  58.  * for unit alignment
  59.  */
  60. static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
  61.  
  62.  
  63. /*
  64.  * XDR nothing
  65.  */
  66. bool_t
  67. xdr_void(/* xdrs, addr */)
  68.     /* XDR *xdrs; */
  69.     /* caddr_t addr; */
  70. {
  71.  
  72.     return (TRUE);
  73. }
  74.  
  75. /*
  76.  * XDR integers
  77.  */
  78. bool_t
  79. xdr_int(xdrs, ip)
  80.     XDR *xdrs;
  81.     int *ip;
  82. {
  83.  
  84. #ifdef lint
  85.     (void) (xdr_short(xdrs, (short *)ip));
  86.     return (xdr_long(xdrs, (long *)ip));
  87. #else
  88.     if (sizeof (int) == sizeof (long)) {
  89.         return (xdr_long(xdrs, (long *)ip));
  90.     } else {
  91.         return (xdr_short(xdrs, (short *)ip));
  92.     }
  93. #endif
  94. }
  95.  
  96. /*
  97.  * XDR unsigned integers
  98.  */
  99. bool_t
  100. xdr_u_int(xdrs, up)
  101.     XDR *xdrs;
  102.     u_int *up;
  103. {
  104.  
  105. #ifdef lint
  106.     (void) (xdr_short(xdrs, (short *)up));
  107.     return (xdr_u_long(xdrs, (u_long *)up));
  108. #else
  109.     if (sizeof (u_int) == sizeof (u_long)) {
  110.         return (xdr_u_long(xdrs, (u_long *)up));
  111.     } else {
  112.         return (xdr_short(xdrs, (short *)up));
  113.     }
  114. #endif
  115. }
  116.  
  117. /*
  118.  * XDR long integers
  119.  * same as xdr_u_long - open coded to save a proc call!
  120.  */
  121. bool_t
  122. xdr_long(xdrs, lp)
  123.     register XDR *xdrs;
  124.     long *lp;
  125. {
  126.  
  127.     if (xdrs->x_op == XDR_ENCODE)
  128.         return (XDR_PUTLONG(xdrs, lp));
  129.  
  130.     if (xdrs->x_op == XDR_DECODE)
  131.         return (XDR_GETLONG(xdrs, lp));
  132.  
  133.     if (xdrs->x_op == XDR_FREE)
  134.         return (TRUE);
  135.  
  136.     return (FALSE);
  137. }
  138.  
  139. /*
  140.  * XDR unsigned long integers
  141.  * same as xdr_long - open coded to save a proc call!
  142.  */
  143. bool_t
  144. xdr_u_long(xdrs, ulp)
  145.     register XDR *xdrs;
  146.     u_long *ulp;
  147. {
  148.  
  149.     if (xdrs->x_op == XDR_DECODE)
  150.         return (XDR_GETLONG(xdrs, (long *)ulp));
  151.     if (xdrs->x_op == XDR_ENCODE)
  152.         return (XDR_PUTLONG(xdrs, (long *)ulp));
  153.     if (xdrs->x_op == XDR_FREE)
  154.         return (TRUE);
  155.     return (FALSE);
  156. }
  157.  
  158. /*
  159.  * XDR short integers
  160.  */
  161. bool_t
  162. xdr_short(xdrs, sp)
  163.     register XDR *xdrs;
  164.     short *sp;
  165. {
  166.     long l;
  167.  
  168.     switch (xdrs->x_op) {
  169.  
  170.     case XDR_ENCODE:
  171.         l = (long) *sp;
  172.         return (XDR_PUTLONG(xdrs, &l));
  173.  
  174.     case XDR_DECODE:
  175.         if (!XDR_GETLONG(xdrs, &l)) {
  176.             return (FALSE);
  177.         }
  178.         *sp = (short) l;
  179.         return (TRUE);
  180.  
  181.     case XDR_FREE:
  182.         return (TRUE);
  183.     }
  184.     return (FALSE);
  185. }
  186.  
  187. /*
  188.  * XDR unsigned short integers
  189.  */
  190. bool_t
  191. xdr_u_short(xdrs, usp)
  192.     register XDR *xdrs;
  193.     u_short *usp;
  194. {
  195.     u_long l;
  196.  
  197.     switch (xdrs->x_op) {
  198.  
  199.     case XDR_ENCODE:
  200.         l = (u_long) *usp;
  201.         return (XDR_PUTLONG(xdrs, &l));
  202.  
  203.     case XDR_DECODE:
  204.         if (!XDR_GETLONG(xdrs, &l)) {
  205.             return (FALSE);
  206.         }
  207.         *usp = (u_short) l;
  208.         return (TRUE);
  209.  
  210.     case XDR_FREE:
  211.         return (TRUE);
  212.     }
  213.     return (FALSE);
  214. }
  215.  
  216.  
  217. /*
  218.  * XDR booleans
  219.  */
  220. bool_t
  221. xdr_bool(xdrs, bp)
  222.     register XDR *xdrs;
  223.     bool_t *bp;
  224. {
  225.     long lb;
  226.  
  227.     switch (xdrs->x_op) {
  228.  
  229.     case XDR_ENCODE:
  230.         lb = *bp ? XDR_TRUE : XDR_FALSE;
  231.         return (XDR_PUTLONG(xdrs, &lb));
  232.  
  233.     case XDR_DECODE:
  234.         if (!XDR_GETLONG(xdrs, &lb)) {
  235.             return (FALSE);
  236.         }
  237.         *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
  238.         return (TRUE);
  239.  
  240.     case XDR_FREE:
  241.         return (TRUE);
  242.     }
  243.     return (FALSE);
  244. }
  245.  
  246. /*
  247.  * XDR enumerations
  248.  */
  249. bool_t
  250. xdr_enum(xdrs, ep)
  251.     XDR *xdrs;
  252.     enum_t *ep;
  253. {
  254.     enum sizecheck { SIZEVAL };    /* used to find the size of an enum */
  255.  
  256.     /*
  257.      * enums are treated as ints
  258.      */
  259. #ifdef lint
  260.     (void) (xdr_short(xdrs, (short *)ep));
  261.     return (xdr_long(xdrs, (long *)ep));
  262. #else
  263.     if (sizeof (enum sizecheck) == sizeof (long)) {
  264.         return (xdr_long(xdrs, (long *)ep));
  265.     } else if (sizeof (enum sizecheck) == sizeof (short)) {
  266.         return (xdr_short(xdrs, (short *)ep));
  267.     } else {
  268.         return (FALSE);
  269.     }
  270. #endif
  271. }
  272.  
  273. /*
  274.  * XDR opaque data
  275.  * Allows the specification of a fixed size sequence of opaque bytes.
  276.  * cp points to the opaque object and cnt gives the byte length.
  277.  */
  278. bool_t
  279. xdr_opaque(xdrs, cp, cnt)
  280.     register XDR *xdrs;
  281.     caddr_t cp;
  282.     register u_int cnt;
  283. {
  284.     register u_int rndup;
  285.     static crud[BYTES_PER_XDR_UNIT];
  286.  
  287.     /*
  288.      * if no data we are done
  289.      */
  290.     if (cnt == 0)
  291.         return (TRUE);
  292.  
  293.     /*
  294.      * round byte count to full xdr units
  295.      */
  296.     rndup = cnt % BYTES_PER_XDR_UNIT;
  297.     if (rndup > 0)
  298.         rndup = BYTES_PER_XDR_UNIT - rndup;
  299.  
  300.     if (xdrs->x_op == XDR_DECODE) {
  301.         if (!XDR_GETBYTES(xdrs, cp, cnt)) {
  302.             return (FALSE);
  303.         }
  304.         if (rndup == 0)
  305.             return (TRUE);
  306.         return (XDR_GETBYTES(xdrs, crud, rndup));
  307.     }
  308.  
  309.     if (xdrs->x_op == XDR_ENCODE) {
  310.         if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
  311.             return (FALSE);
  312.         }
  313.         if (rndup == 0)
  314.             return (TRUE);
  315.         return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
  316.     }
  317.  
  318.     if (xdrs->x_op == XDR_FREE) {
  319.         return (TRUE);
  320.     }
  321.  
  322.     return (FALSE);
  323. }
  324.  
  325. /*
  326.  * XDR counted bytes
  327.  * *cpp is a pointer to the bytes, *sizep is the count.
  328.  * If *cpp is NULL maxsize bytes are allocated
  329.  */
  330. bool_t
  331. xdr_bytes(xdrs, cpp, sizep, maxsize)
  332.     register XDR *xdrs;
  333.     char **cpp;
  334.     u_int *sizep;
  335.     u_int maxsize;
  336. {
  337.     char *sp = *cpp;  /* sp is the actual string pointer */
  338.     u_int nodesize;
  339.  
  340.     /*
  341.      * first deal with the length since xdr bytes are counted
  342.      */
  343.     if (! xdr_u_int(xdrs, sizep)) {
  344.         return (FALSE);
  345.     }
  346.     nodesize = *sizep;
  347.     if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
  348.         return (FALSE);
  349.     }
  350.  
  351.     /*
  352.      * now deal with the actual bytes
  353.      */
  354.     switch (xdrs->x_op) {
  355.  
  356.     case XDR_DECODE:
  357.         if (sp == NULL) {
  358.             *cpp = sp = (char *)mem_alloc(nodesize);
  359.         }
  360.         if (sp == NULL) {
  361.             fprintf(stderr, "xdr_bytes: out of memory\n");
  362.             return (FALSE);
  363.         }
  364.         /* fall into ... */
  365.  
  366.     case XDR_ENCODE:
  367.         return (xdr_opaque(xdrs, sp, nodesize));
  368.  
  369.     case XDR_FREE:
  370.         if (sp != NULL) {
  371.             mem_free(sp, nodesize);
  372.             *cpp = NULL;
  373.         }
  374.         return (TRUE);
  375.     }
  376.     return (FALSE);
  377. }
  378.  
  379. /*
  380.  * XDR a descriminated union
  381.  * Support routine for discriminated unions.
  382.  * You create an array of xdrdiscrim structures, terminated with
  383.  * an entry with a null procedure pointer.  The routine gets
  384.  * the discriminant value and then searches the array of xdrdiscrims
  385.  * looking for that value.  It calls the procedure given in the xdrdiscrim
  386.  * to handle the discriminant.  If there is no specific routine a default
  387.  * routine may be called.
  388.  * If there is no specific or default routine an error is returned.
  389.  */
  390. bool_t
  391. xdr_union(xdrs, dscmp, unp, choices, dfault)
  392.     register XDR *xdrs;
  393.     enum_t *dscmp;        /* enum to decide which arm to work on */
  394.     caddr_t unp;        /* the union itself */
  395.     struct xdr_discrim *choices;    /* [value, xdr proc] for each arm */
  396.     xdrproc_t dfault;    /* default xdr routine */
  397. {
  398.     register enum_t dscm;
  399.  
  400.     /*
  401.      * we deal with the discriminator;  it's an enum
  402.      */
  403.     if (! xdr_enum(xdrs, dscmp)) {
  404.         return (FALSE);
  405.     }
  406.     dscm = *dscmp;
  407.  
  408.     /*
  409.      * search choices for a value that matches the discriminator.
  410.      * if we find one, execute the xdr routine for that value.
  411.      */
  412.     for (; choices->proc != NULL_xdrproc_t; choices++) {
  413.         if (choices->value == dscm)
  414.             return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
  415.     }
  416.  
  417.     /*
  418.      * no match - execute the default xdr routine if there is one
  419.      */
  420.     return ((dfault == NULL_xdrproc_t) ? FALSE :
  421.         (*dfault)(xdrs, unp, LASTUNSIGNED));
  422. }
  423.  
  424.  
  425. /*
  426.  * Non-portable xdr primitives.
  427.  * Care should be taken when moving these routines to new architectures.
  428.  */
  429.  
  430.  
  431. /*
  432.  * XDR null terminated ASCII strings
  433.  * xdr_string deals with "C strings" - arrays of bytes that are
  434.  * terminated by a NULL character.  The parameter cpp references a
  435.  * pointer to storage; If the pointer is null, then the necessary
  436.  * storage is allocated.  The last parameter is the max allowed length
  437.  * of the string as specified by a protocol.
  438.  */
  439. bool_t
  440. xdr_string(xdrs, cpp, maxsize)
  441.     register XDR *xdrs;
  442.     char **cpp;
  443.     u_int maxsize;
  444. {
  445.     register char *sp = *cpp;  /* sp is the actual string pointer */
  446.     u_int size;
  447.     u_int nodesize;
  448.  
  449.     /*
  450.      * first deal with the length since xdr strings are counted-strings
  451.      */
  452.     if ((xdrs->x_op) != XDR_DECODE)
  453.         size = strlen(sp);
  454.     if (! xdr_u_int(xdrs, &size)) {
  455.         return (FALSE);
  456.     }
  457.     if (size > maxsize) {
  458.         return (FALSE);
  459.     }
  460.     nodesize = size + 1;
  461.  
  462.     /*
  463.      * now deal with the actual bytes
  464.      */
  465.     switch (xdrs->x_op) {
  466.  
  467.     case XDR_DECODE:
  468.         if (sp == NULL)
  469.             *cpp = sp = (char *)mem_alloc(nodesize);
  470.         if (sp == NULL) {
  471.             fprintf(stderr, "xdr_string: out of memory\n");
  472.             return (FALSE);
  473.         }
  474.         sp[size] = 0;
  475.         /* fall into ... */
  476.  
  477.     case XDR_ENCODE:
  478.         return (xdr_opaque(xdrs, sp, size));
  479.  
  480.     case XDR_FREE:
  481.         if (sp != NULL) {
  482.             mem_free(sp, nodesize);
  483.             *cpp = NULL;
  484.         }
  485.         return (TRUE);
  486.     }
  487.     return (FALSE);
  488. }
  489.  
  490. /* 
  491.  * Wrapper for xdr_string that can be called directly from 
  492.  * routines like clnt_call
  493.  */
  494. bool_t
  495. xdr_wrapstring(xdrs, cpp)
  496.     XDR *xdrs;
  497.     char **cpp;
  498. {
  499.     if (xdr_string(xdrs, cpp, BUFSIZ)) {
  500.         return(TRUE);
  501.     }
  502.     return(FALSE);
  503. }
  504.