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