(root)/
glibc-2.38/
sunrpc/
xdr_mem.c
       1  /*
       2   * xdr_mem.c, XDR implementation using memory buffers.
       3   *
       4   * Copyright (c) 2010, Oracle America, Inc.
       5   *
       6   * Redistribution and use in source and binary forms, with or without
       7   * modification, are permitted provided that the following conditions are
       8   * met:
       9   *
      10   *     * Redistributions of source code must retain the above copyright
      11   *       notice, this list of conditions and the following disclaimer.
      12   *     * Redistributions in binary form must reproduce the above
      13   *       copyright notice, this list of conditions and the following
      14   *       disclaimer in the documentation and/or other materials
      15   *       provided with the distribution.
      16   *     * Neither the name of the "Oracle America, Inc." nor the names of its
      17   *       contributors may be used to endorse or promote products derived
      18   *       from this software without specific prior written permission.
      19   *
      20   *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21   *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22   *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
      23   *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      24   *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
      25   *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26   *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
      27   *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      28   *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      29   *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      30   *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      31   *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      32   *
      33   * If you have some data to be interpreted as external data representation
      34   * or to be converted to external data representation in a memory buffer,
      35   * then this is the package for you.
      36   */
      37  
      38  #include <string.h>
      39  #include <limits.h>
      40  #include <rpc/rpc.h>
      41  #include <shlib-compat.h>
      42  
      43  static bool_t xdrmem_getlong (XDR *, long *);
      44  static bool_t xdrmem_putlong (XDR *, const long *);
      45  static bool_t xdrmem_getbytes (XDR *, caddr_t, u_int);
      46  static bool_t xdrmem_putbytes (XDR *, const char *, u_int);
      47  static u_int xdrmem_getpos (const XDR *);
      48  static bool_t xdrmem_setpos (XDR *, u_int);
      49  static int32_t *xdrmem_inline (XDR *, u_int);
      50  static void xdrmem_destroy (XDR *);
      51  static bool_t xdrmem_getint32 (XDR *, int32_t *);
      52  static bool_t xdrmem_putint32 (XDR *, const int32_t *);
      53  
      54  static const struct xdr_ops xdrmem_ops =
      55  {
      56    xdrmem_getlong,
      57    xdrmem_putlong,
      58    xdrmem_getbytes,
      59    xdrmem_putbytes,
      60    xdrmem_getpos,
      61    xdrmem_setpos,
      62    xdrmem_inline,
      63    xdrmem_destroy,
      64    xdrmem_getint32,
      65    xdrmem_putint32
      66  };
      67  
      68  /*
      69   * The procedure xdrmem_create initializes a stream descriptor for a
      70   * memory buffer.
      71   */
      72  void
      73  xdrmem_create (XDR *xdrs, const caddr_t addr, u_int size, enum xdr_op op)
      74  {
      75    xdrs->x_op = op;
      76    /* We have to add the const since the `struct xdr_ops' in `struct XDR'
      77       is not `const'.  */
      78    xdrs->x_ops = (struct xdr_ops *) &xdrmem_ops;
      79    xdrs->x_private = xdrs->x_base = addr;
      80    xdrs->x_handy = size;
      81  }
      82  #ifdef EXPORT_RPC_SYMBOLS
      83  libc_hidden_def (xdrmem_create)
      84  #else
      85  libc_hidden_nolink_sunrpc (xdrmem_create, GLIBC_2_0)
      86  #endif
      87  
      88  /*
      89   * Nothing needs to be done for the memory case.  The argument is clearly
      90   * const.
      91   */
      92  
      93  static void
      94  xdrmem_destroy (XDR *xdrs)
      95  {
      96  }
      97  
      98  /*
      99   * Gets the next word from the memory referenced by xdrs and places it
     100   * in the long pointed to by lp.  It then increments the private word to
     101   * point at the next element.  Neither object pointed to is const
     102   */
     103  static bool_t
     104  xdrmem_getlong (XDR *xdrs, long *lp)
     105  {
     106    if (xdrs->x_handy < 4)
     107      return FALSE;
     108    xdrs->x_handy -= 4;
     109    *lp = (int32_t) ntohl ((*((int32_t *) (xdrs->x_private))));
     110    xdrs->x_private += 4;
     111    return TRUE;
     112  }
     113  
     114  /*
     115   * Puts the long pointed to by lp in the memory referenced by xdrs.  It
     116   * then increments the private word to point at the next element.  The
     117   * long pointed at is const
     118   */
     119  static bool_t
     120  xdrmem_putlong (XDR *xdrs, const long *lp)
     121  {
     122    if (xdrs->x_handy < 4)
     123      return FALSE;
     124    xdrs->x_handy -= 4;
     125    *(int32_t *) xdrs->x_private = htonl (*lp);
     126    xdrs->x_private += 4;
     127    return TRUE;
     128  }
     129  
     130  /*
     131   * Gets an unaligned number of bytes from the xdrs structure and writes them
     132   * to the address passed in addr.  Be very careful when calling this routine
     133   * as it could leave the xdrs pointing to an unaligned structure which is not
     134   * a good idea.  None of the things pointed to are const.
     135   */
     136  static bool_t
     137  xdrmem_getbytes (XDR *xdrs, caddr_t addr, u_int len)
     138  {
     139    if (xdrs->x_handy < len)
     140      return FALSE;
     141    xdrs->x_handy -= len;
     142    memcpy (addr, xdrs->x_private, len);
     143    xdrs->x_private += len;
     144    return TRUE;
     145  }
     146  
     147  /*
     148   * The complementary function to the above.  The same warnings apply about
     149   * unaligned data.  The source address is const.
     150   */
     151  static bool_t
     152  xdrmem_putbytes (XDR *xdrs, const char *addr, u_int len)
     153  {
     154    if (xdrs->x_handy < len)
     155      return FALSE;
     156    xdrs->x_handy -= len;
     157    memcpy (xdrs->x_private, addr, len);
     158    xdrs->x_private += len;
     159    return TRUE;
     160  }
     161  
     162  /*
     163   * Not sure what this one does.  But it clearly doesn't modify the contents
     164   * of xdrs.  **FIXME** does this not assume u_int == u_long?
     165   */
     166  static u_int
     167  xdrmem_getpos (const XDR *xdrs)
     168  {
     169    return (u_long) xdrs->x_private - (u_long) xdrs->x_base;
     170  }
     171  
     172  /*
     173   * xdrs modified
     174   */
     175  static bool_t
     176  xdrmem_setpos (XDR *xdrs, u_int pos)
     177  {
     178    caddr_t newaddr = xdrs->x_base + pos;
     179    caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
     180    size_t handy = lastaddr - newaddr;
     181  
     182    if (newaddr > lastaddr
     183        || newaddr < xdrs->x_base
     184        || handy != (u_int) handy)
     185      return FALSE;
     186  
     187    xdrs->x_private = newaddr;
     188    xdrs->x_handy = (u_int) handy;
     189    return TRUE;
     190  }
     191  
     192  /*
     193   * xdrs modified
     194   */
     195  static int32_t *
     196  xdrmem_inline (XDR *xdrs, u_int len)
     197  {
     198    int32_t *buf = 0;
     199  
     200    if (xdrs->x_handy >= len)
     201      {
     202        xdrs->x_handy -= len;
     203        buf = (int32_t *) xdrs->x_private;
     204        xdrs->x_private += len;
     205      }
     206    return buf;
     207  }
     208  
     209  /*
     210   * Gets the next word from the memory referenced by xdrs and places it
     211   * in the int pointed to by ip.  It then increments the private word to
     212   * point at the next element.  Neither object pointed to is const
     213   */
     214  static bool_t
     215  xdrmem_getint32 (XDR *xdrs, int32_t *ip)
     216  {
     217    if (xdrs->x_handy < 4)
     218      return FALSE;
     219    xdrs->x_handy -= 4;
     220    *ip = ntohl ((*((int32_t *) (xdrs->x_private))));
     221    xdrs->x_private += 4;
     222    return TRUE;
     223  }
     224  
     225  /*
     226   * Puts the long pointed to by lp in the memory referenced by xdrs.  It
     227   * then increments the private word to point at the next element.  The
     228   * long pointed at is const
     229   */
     230  static bool_t
     231  xdrmem_putint32 (XDR *xdrs, const int32_t *ip)
     232  {
     233    if (xdrs->x_handy < 4)
     234      return FALSE;
     235    xdrs->x_handy -= 4;
     236    *(int32_t *) xdrs->x_private = htonl (*ip);
     237    xdrs->x_private += 4;
     238    return TRUE;
     239  }