1 /* $NetBSD: xdr_stdio.c,v 1.14 2000/01/22 22:19:19 mycroft Exp $ */ 2 3 /*- 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * Copyright (c) 2010, Oracle America, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are 10 * met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials 17 * provided with the distribution. 18 * * Neither the name of the "Oracle America, Inc." nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 29 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* 37 * xdr_stdio.c, XDR implementation on standard i/o file. 38 * 39 * This set of routines implements a XDR on a stdio stream. 40 * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes 41 * from the stream. 42 */ 43 44 #include "namespace.h" 45 #include <stdio.h> 46 47 #include <arpa/inet.h> 48 #include <rpc/types.h> 49 #include <rpc/xdr.h> 50 #include "un-namespace.h" 51 52 static void xdrstdio_destroy(XDR *); 53 static bool_t xdrstdio_getlong(XDR *, long *); 54 static bool_t xdrstdio_putlong(XDR *, const long *); 55 static bool_t xdrstdio_getbytes(XDR *, char *, u_int); 56 static bool_t xdrstdio_putbytes(XDR *, const char *, u_int); 57 static u_int xdrstdio_getpos(XDR *); 58 static bool_t xdrstdio_setpos(XDR *, u_int); 59 static int32_t *xdrstdio_inline(XDR *, u_int); 60 61 /* 62 * Ops vector for stdio type XDR 63 */ 64 static const struct xdr_ops xdrstdio_ops = { 65 xdrstdio_getlong, /* deseraialize a long int */ 66 xdrstdio_putlong, /* seraialize a long int */ 67 xdrstdio_getbytes, /* deserialize counted bytes */ 68 xdrstdio_putbytes, /* serialize counted bytes */ 69 xdrstdio_getpos, /* get offset in the stream */ 70 xdrstdio_setpos, /* set offset in the stream */ 71 xdrstdio_inline, /* prime stream for inline macros */ 72 xdrstdio_destroy /* destroy stream */ 73 }; 74 75 /* 76 * Initialize a stdio xdr stream. 77 * Sets the xdr stream handle xdrs for use on the stream file. 78 * Operation flag is set to op. 79 */ 80 void 81 xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op) 82 { 83 84 xdrs->x_op = op; 85 xdrs->x_ops = &xdrstdio_ops; 86 xdrs->x_private = file; 87 xdrs->x_handy = 0; 88 xdrs->x_base = 0; 89 } 90 91 /* 92 * Destroy a stdio xdr stream. 93 * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. 94 */ 95 static void 96 xdrstdio_destroy(XDR *xdrs) 97 { 98 (void)fflush((FILE *)xdrs->x_private); 99 /* XXX: should we close the file ?? */ 100 } 101 102 static bool_t 103 xdrstdio_getlong(XDR *xdrs, long *lp) 104 { 105 u_int32_t temp; 106 107 if (fread(&temp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1) 108 return (FALSE); 109 *lp = (long)ntohl(temp); 110 return (TRUE); 111 } 112 113 static bool_t 114 xdrstdio_putlong(XDR *xdrs, const long *lp) 115 { 116 int32_t mycopy = htonl((u_int32_t)*lp); 117 118 if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1) 119 return (FALSE); 120 return (TRUE); 121 } 122 123 static bool_t 124 xdrstdio_getbytes(XDR *xdrs, char *addr, u_int len) 125 { 126 127 if ((len != 0) && (fread(addr, (size_t)len, 1, (FILE *)xdrs->x_private) != 1)) 128 return (FALSE); 129 return (TRUE); 130 } 131 132 static bool_t 133 xdrstdio_putbytes(XDR *xdrs, const char *addr, u_int len) 134 { 135 136 if ((len != 0) && (fwrite(addr, (size_t)len, 1, 137 (FILE *)xdrs->x_private) != 1)) 138 return (FALSE); 139 return (TRUE); 140 } 141 142 static u_int 143 xdrstdio_getpos(XDR *xdrs) 144 { 145 146 return ((u_int) ftell((FILE *)xdrs->x_private)); 147 } 148 149 static bool_t 150 xdrstdio_setpos(XDR *xdrs, u_int pos) 151 { 152 153 return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ? 154 FALSE : TRUE); 155 } 156 157 /* ARGSUSED */ 158 static int32_t * 159 xdrstdio_inline(XDR *xdrs, u_int len) 160 { 161 162 /* 163 * Must do some work to implement this: must insure 164 * enough data in the underlying stdio buffer, 165 * that the buffer is aligned so that we can indirect through a 166 * long *, and stuff this pointer in xdrs->x_buf. Doing 167 * a fread or fwrite to a scratch buffer would defeat 168 * most of the gains to be had here and require storage 169 * management on this buffer, so we don't do this. 170 */ 171 return (NULL); 172 } 173