1/*	$NetBSD: xdr_stdio.c,v 1.17 2006/10/15 16:14:46 christos Exp $	*/
2
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
34#include <sys/cdefs.h>
35#if defined(LIBC_SCCS) && !defined(lint)
36#if 0
37static char *sccsid = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";
38static char *sccsid = "@(#)xdr_stdio.c	2.1 88/07/29 4.0 RPCSRC";
39#else
40__RCSID("$NetBSD: xdr_stdio.c,v 1.17 2006/10/15 16:14:46 christos Exp $");
41#endif
42#endif
43
44/*
45 * xdr_stdio.c, XDR implementation on standard i/o file.
46 *
47 * Copyright (C) 1984, Sun Microsystems, Inc.
48 *
49 * This set of routines implements a XDR on a stdio stream.
50 * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
51 * from the stream.
52 */
53
54#include "namespace.h"
55
56#include <stdio.h>
57
58#include <rpc/types.h>
59#include <rpc/xdr.h>
60
61#ifdef __weak_alias
62__weak_alias(xdrstdio_create,_xdrstdio_create)
63#endif
64
65static void xdrstdio_destroy __P((XDR *));
66static bool_t xdrstdio_getlong __P((XDR *, long *));
67static bool_t xdrstdio_putlong __P((XDR *, const long *));
68static bool_t xdrstdio_getbytes __P((XDR *, char *, u_int));
69static bool_t xdrstdio_putbytes __P((XDR *, const char *, u_int));
70static u_int xdrstdio_getpos __P((XDR *));
71static bool_t xdrstdio_setpos __P((XDR *, u_int));
72static int32_t *xdrstdio_inline __P((XDR *, u_int));
73
74/*
75 * Ops vector for stdio type XDR
76 */
77static const struct xdr_ops	xdrstdio_ops = {
78	xdrstdio_getlong,	/* deseraialize a long int */
79	xdrstdio_putlong,	/* seraialize a long int */
80	xdrstdio_getbytes,	/* deserialize counted bytes */
81	xdrstdio_putbytes,	/* serialize counted bytes */
82	xdrstdio_getpos,	/* get offset in the stream */
83	xdrstdio_setpos,	/* set offset in the stream */
84	xdrstdio_inline,	/* prime stream for inline macros */
85	xdrstdio_destroy,	/* destroy stream */
86	NULL,			/* xdrstdio_control */
87};
88
89/*
90 * Initialize a stdio xdr stream.
91 * Sets the xdr stream handle xdrs for use on the stream file.
92 * Operation flag is set to op.
93 */
94void
95xdrstdio_create(xdrs, file, op)
96	XDR *xdrs;
97	FILE *file;
98	enum xdr_op op;
99{
100
101	xdrs->x_op = op;
102	xdrs->x_ops = &xdrstdio_ops;
103	xdrs->x_private = file;
104	xdrs->x_handy = 0;
105	xdrs->x_base = 0;
106}
107
108/*
109 * Destroy a stdio xdr stream.
110 * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
111 */
112static void
113xdrstdio_destroy(xdrs)
114	XDR *xdrs;
115{
116	(void)fflush((FILE *)xdrs->x_private);
117		/* XXX: should we close the file ?? */
118}
119
120static bool_t
121xdrstdio_getlong(xdrs, lp)
122	XDR *xdrs;
123	long *lp;
124{
125	u_int32_t temp;
126
127	if (fread(&temp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
128		return (FALSE);
129	*lp = (long)ntohl(temp);
130	return (TRUE);
131}
132
133static bool_t
134xdrstdio_putlong(xdrs, lp)
135	XDR *xdrs;
136	const long *lp;
137{
138	int32_t mycopy = htonl((u_int32_t)*lp);
139
140	if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
141		return (FALSE);
142	return (TRUE);
143}
144
145static bool_t
146xdrstdio_getbytes(xdrs, addr, len)
147	XDR *xdrs;
148	char *addr;
149	u_int len;
150{
151
152	if ((len != 0) && (fread(addr, (size_t)len, 1, (FILE *)xdrs->x_private) != 1))
153		return (FALSE);
154	return (TRUE);
155}
156
157static bool_t
158xdrstdio_putbytes(xdrs, addr, len)
159	XDR *xdrs;
160	const char *addr;
161	u_int len;
162{
163
164	if ((len != 0) && (fwrite(addr, (size_t)len, 1,
165	    (FILE *)xdrs->x_private) != 1))
166		return (FALSE);
167	return (TRUE);
168}
169
170static u_int
171xdrstdio_getpos(xdrs)
172	XDR *xdrs;
173{
174
175	return ((u_int) ftell((FILE *)xdrs->x_private));
176}
177
178static bool_t
179xdrstdio_setpos(xdrs, pos)
180	XDR *xdrs;
181	u_int pos;
182{
183
184	return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
185		FALSE : TRUE);
186}
187
188/* ARGSUSED */
189static int32_t *
190xdrstdio_inline(xdrs, len)
191	XDR *xdrs;
192	u_int len;
193{
194
195	/*
196	 * Must do some work to implement this: must insure
197	 * enough data in the underlying stdio buffer,
198	 * that the buffer is aligned so that we can indirect through a
199	 * long *, and stuff this pointer in xdrs->x_buf.  Doing
200	 * a fread or fwrite to a scratch buffer would defeat
201	 * most of the gains to be had here and require storage
202	 * management on this buffer, so we don't do this.
203	 */
204	return (NULL);
205}
206