xref: /openbsd-src/lib/libc/rpc/xdr_stdio.c (revision a4afd6dad3fba28f80e70208181c06c482259988)
1 /*
2  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3  * unrestricted use provided that this legend is included on all tape
4  * media and as a part of the software program in whole or part.  Users
5  * may copy or modify Sun RPC without charge, but are not authorized
6  * to license or distribute it to anyone else except as part of a product or
7  * program developed by the user.
8  *
9  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12  *
13  * Sun RPC is provided with no support and without any obligation on the
14  * part of Sun Microsystems, Inc. to assist in its use, correction,
15  * modification or enhancement.
16  *
17  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19  * OR ANY PART THEREOF.
20  *
21  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22  * or profits or other special, indirect and consequential damages, even if
23  * Sun has been advised of the possibility of such damages.
24  *
25  * Sun Microsystems, Inc.
26  * 2550 Garcia Avenue
27  * Mountain View, California  94043
28  */
29 
30 #if defined(LIBC_SCCS) && !defined(lint)
31 static char *rcsid = "$OpenBSD: xdr_stdio.c,v 1.4 1996/09/15 09:31:44 tholo Exp $";
32 #endif /* LIBC_SCCS and not lint */
33 
34 /*
35  * xdr_stdio.c, XDR implementation on standard i/o file.
36  *
37  * Copyright (C) 1984, Sun Microsystems, Inc.
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 <rpc/types.h>
45 #include <stdio.h>
46 #include <rpc/xdr.h>
47 
48 static bool_t	xdrstdio_getlong();
49 static bool_t	xdrstdio_putlong();
50 static bool_t	xdrstdio_getbytes();
51 static bool_t	xdrstdio_putbytes();
52 static u_int	xdrstdio_getpos();
53 static bool_t	xdrstdio_setpos();
54 static int32_t *xdrstdio_inline();
55 static void	xdrstdio_destroy();
56 
57 /*
58  * Ops vector for stdio type XDR
59  */
60 static struct xdr_ops	xdrstdio_ops = {
61 	xdrstdio_getlong,	/* deseraialize a long int */
62 	xdrstdio_putlong,	/* seraialize a long int */
63 	xdrstdio_getbytes,	/* deserialize counted bytes */
64 	xdrstdio_putbytes,	/* serialize counted bytes */
65 	xdrstdio_getpos,	/* get offset in the stream */
66 	xdrstdio_setpos,	/* set offset in the stream */
67 	xdrstdio_inline,	/* prime stream for inline macros */
68 	xdrstdio_destroy	/* destroy stream */
69 };
70 
71 /*
72  * Initialize a stdio xdr stream.
73  * Sets the xdr stream handle xdrs for use on the stream file.
74  * Operation flag is set to op.
75  */
76 void
77 xdrstdio_create(xdrs, file, op)
78 	register XDR *xdrs;
79 	FILE *file;
80 	enum xdr_op op;
81 {
82 
83 	xdrs->x_op = op;
84 	xdrs->x_ops = &xdrstdio_ops;
85 	xdrs->x_private = (caddr_t)file;
86 	xdrs->x_handy = 0;
87 	xdrs->x_base = 0;
88 }
89 
90 /*
91  * Destroy a stdio xdr stream.
92  * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
93  */
94 static void
95 xdrstdio_destroy(xdrs)
96 	register XDR *xdrs;
97 {
98 	(void)fflush((FILE *)xdrs->x_private);
99 	/* xx should we close the file ?? */
100 }
101 
102 static bool_t
103 xdrstdio_getlong(xdrs, lp)
104 	XDR *xdrs;
105 	register long *lp;
106 {
107 
108 	if (fread((caddr_t)lp, sizeof(int32_t), 1,
109 	    (FILE *)xdrs->x_private) != 1)
110 		return (FALSE);
111 	*lp = (long)ntohl((int32_t)*lp);
112 	return (TRUE);
113 }
114 
115 static bool_t
116 xdrstdio_putlong(xdrs, lp)
117 	XDR *xdrs;
118 	long *lp;
119 {
120 	long mycopy = (long)htonl((int32_t)*lp);
121 
122 	if (fwrite((caddr_t)&mycopy, sizeof(int32_t), 1,
123 	    (FILE *)xdrs->x_private) != 1)
124 		return (FALSE);
125 	return (TRUE);
126 }
127 
128 static bool_t
129 xdrstdio_getbytes(xdrs, addr, len)
130 	XDR *xdrs;
131 	caddr_t addr;
132 	u_int len;
133 {
134 
135 	if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
136 		return (FALSE);
137 	return (TRUE);
138 }
139 
140 static bool_t
141 xdrstdio_putbytes(xdrs, addr, len)
142 	XDR *xdrs;
143 	caddr_t addr;
144 	u_int len;
145 {
146 
147 	if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
148 		return (FALSE);
149 	return (TRUE);
150 }
151 
152 static u_int
153 xdrstdio_getpos(xdrs)
154 	XDR *xdrs;
155 {
156 
157 	return ((u_int) ftell((FILE *)xdrs->x_private));
158 }
159 
160 static bool_t
161 xdrstdio_setpos(xdrs, pos)
162 	XDR *xdrs;
163 	u_int pos;
164 {
165 
166 	return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
167 		FALSE : TRUE);
168 }
169 
170 /* ARGSUSED */
171 static int32_t *
172 xdrstdio_inline(xdrs, len)
173 	XDR *xdrs;
174 	u_int len;
175 {
176 
177 	/*
178 	 * Must do some work to implement this: must insure
179 	 * enough data in the underlying stdio buffer,
180 	 * that the buffer is aligned so that we can indirect through a
181 	 * long *, and stuff this pointer in xdrs->x_buf.  Doing
182 	 * a fread or fwrite to a scratch buffer would defeat
183 	 * most of the gains to be had here and require storage
184 	 * management on this buffer, so we don't do this.
185 	 */
186 	return (NULL);
187 }
188