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