(root)/
glibc-2.38/
sunrpc/
xdr_stdio.c
       1  /*
       2   * xdr_stdio.c, XDR implementation on standard i/o file.
       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   * This set of routines implements a XDR on a stdio stream.
      34   * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
      35   * from the stream.
      36   */
      37  
      38  #include <rpc/types.h>
      39  #include <stdio.h>
      40  #include <rpc/xdr.h>
      41  
      42  #include <libio/iolibio.h>
      43  #include <shlib-compat.h>
      44  
      45  #define fflush(s) _IO_fflush (s)
      46  #define fread(p, m, n, s) _IO_fread (p, m, n, s)
      47  #define ftell(s) _IO_ftell (s)
      48  #define fwrite(p, m, n, s) _IO_fwrite (p, m, n, s)
      49  
      50  static bool_t xdrstdio_getlong (XDR *, long *);
      51  static bool_t xdrstdio_putlong (XDR *, const long *);
      52  static bool_t xdrstdio_getbytes (XDR *, caddr_t, u_int);
      53  static bool_t xdrstdio_putbytes (XDR *, const char *, u_int);
      54  static u_int xdrstdio_getpos (const XDR *);
      55  static bool_t xdrstdio_setpos (XDR *, u_int);
      56  static int32_t *xdrstdio_inline (XDR *, u_int);
      57  static void xdrstdio_destroy (XDR *);
      58  static bool_t xdrstdio_getint32 (XDR *, int32_t *);
      59  static bool_t xdrstdio_putint32 (XDR *, const int32_t *);
      60  
      61  /*
      62   * Ops vector for stdio type XDR
      63   */
      64  static const struct xdr_ops xdrstdio_ops =
      65  {
      66    xdrstdio_getlong,		/* deserialize a long int */
      67    xdrstdio_putlong,		/* serialize a long int */
      68    xdrstdio_getbytes,		/* deserialize counted bytes */
      69    xdrstdio_putbytes,		/* serialize counted bytes */
      70    xdrstdio_getpos,		/* get offset in the stream */
      71    xdrstdio_setpos,		/* set offset in the stream */
      72    xdrstdio_inline,		/* prime stream for inline macros */
      73    xdrstdio_destroy,		/* destroy stream */
      74    xdrstdio_getint32,		/* deserialize a int */
      75    xdrstdio_putint32		/* serialize a int */
      76  };
      77  
      78  /*
      79   * Initialize a stdio xdr stream.
      80   * Sets the xdr stream handle xdrs for use on the stream file.
      81   * Operation flag is set to op.
      82   */
      83  void
      84  xdrstdio_create (XDR *xdrs, FILE *file, enum xdr_op op)
      85  {
      86    xdrs->x_op = op;
      87    /* We have to add the const since the `struct xdr_ops' in `struct XDR'
      88       is not `const'.  */
      89    xdrs->x_ops = (struct xdr_ops *) &xdrstdio_ops;
      90    xdrs->x_private = (caddr_t) file;
      91    xdrs->x_handy = 0;
      92    xdrs->x_base = 0;
      93  }
      94  
      95  /*
      96   * Destroy a stdio xdr stream.
      97   * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
      98   */
      99  static void
     100  xdrstdio_destroy (XDR *xdrs)
     101  {
     102    (void) fflush ((FILE *) xdrs->x_private);
     103    /* xx should we close the file ?? */
     104  };
     105  
     106  static bool_t
     107  xdrstdio_getlong (XDR *xdrs, long *lp)
     108  {
     109    uint32_t mycopy;
     110  
     111    if (fread ((caddr_t) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1)
     112      return FALSE;
     113    *lp = (long) ntohl (mycopy);
     114    return TRUE;
     115  }
     116  
     117  static bool_t
     118  xdrstdio_putlong (XDR *xdrs, const long *lp)
     119  {
     120    int32_t mycopy = htonl ((uint32_t) *lp);
     121  
     122    if (fwrite ((caddr_t) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1)
     123      return FALSE;
     124    return TRUE;
     125  }
     126  
     127  static bool_t
     128  xdrstdio_getbytes (XDR *xdrs, const caddr_t addr, u_int len)
     129  {
     130    if ((len != 0) && (fread (addr, (int) len, 1,
     131  			    (FILE *) xdrs->x_private) != 1))
     132      return FALSE;
     133    return TRUE;
     134  }
     135  
     136  static bool_t
     137  xdrstdio_putbytes (XDR *xdrs, const char *addr, u_int len)
     138  {
     139    if ((len != 0) && (fwrite (addr, (int) len, 1,
     140  			     (FILE *) xdrs->x_private) != 1))
     141      return FALSE;
     142    return TRUE;
     143  }
     144  
     145  static u_int
     146  xdrstdio_getpos (const XDR *xdrs)
     147  {
     148    return (u_int) ftell ((FILE *) xdrs->x_private);
     149  }
     150  
     151  static bool_t
     152  xdrstdio_setpos (XDR *xdrs, u_int pos)
     153  {
     154    return fseek ((FILE *) xdrs->x_private, (long) pos, 0) < 0 ? FALSE : TRUE;
     155  }
     156  
     157  static int32_t *
     158  xdrstdio_inline (XDR *xdrs, u_int len)
     159  {
     160    /*
     161     * Must do some work to implement this: must insure
     162     * enough data in the underlying stdio buffer,
     163     * that the buffer is aligned so that we can indirect through a
     164     * long *, and stuff this pointer in xdrs->x_buf.  Doing
     165     * a fread or fwrite to a scratch buffer would defeat
     166     * most of the gains to be had here and require storage
     167     * management on this buffer, so we don't do this.
     168     */
     169    return NULL;
     170  }
     171  
     172  static bool_t
     173  xdrstdio_getint32 (XDR *xdrs, int32_t *ip)
     174  {
     175    int32_t mycopy;
     176  
     177    if (fread ((caddr_t) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1)
     178      return FALSE;
     179    *ip = ntohl (mycopy);
     180    return TRUE;
     181  }
     182  
     183  static bool_t
     184  xdrstdio_putint32 (XDR *xdrs, const int32_t *ip)
     185  {
     186    int32_t mycopy = htonl (*ip);
     187  
     188    ip = &mycopy;
     189    if (fwrite ((caddr_t) ip, 4, 1, (FILE *) xdrs->x_private) != 1)
     190      return FALSE;
     191    return TRUE;
     192  }
     193  #ifdef EXPORT_RPC_SYMBOLS
     194  libc_hidden_def (xdrstdio_create)
     195  #else
     196  libc_hidden_nolink_sunrpc (xdrstdio_create, GLIBC_2_0)
     197  #endif