xref: /openbsd/lib/libc/rpc/xdr_stdio.c (revision 7b36286a)
1 /*	$OpenBSD: xdr_stdio.c,v 1.11 2007/09/17 16:04:24 blambert 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 <rpc/types.h>
42 #include <stdio.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 };
67 
68 /*
69  * Initialize a stdio xdr stream.
70  * Sets the xdr stream handle xdrs for use on the stream file.
71  * Operation flag is set to op.
72  */
73 void
74 xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op)
75 {
76 
77 	xdrs->x_op = op;
78 	xdrs->x_ops = &xdrstdio_ops;
79 	xdrs->x_private = (caddr_t)file;
80 	xdrs->x_handy = 0;
81 	xdrs->x_base = 0;
82 }
83 
84 /*
85  * Destroy a stdio xdr stream.
86  * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
87  */
88 static void
89 xdrstdio_destroy(XDR *xdrs)
90 {
91 	(void)fflush((FILE *)xdrs->x_private);
92 	/* xx should we close the file ?? */
93 }
94 
95 static bool_t
96 xdrstdio_getlong(XDR *xdrs, long int *lp)
97 {
98 	u_int32_t temp;
99 
100 	if (fread(&temp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
101 		return (FALSE);
102 	*lp = (long)ntohl(temp);
103 	return (TRUE);
104 }
105 
106 static bool_t
107 xdrstdio_putlong(XDR *xdrs, long int *lp)
108 {
109 	int32_t mycopy = htonl((u_int32_t)*lp);
110 
111 	if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
112 		return (FALSE);
113 	return (TRUE);
114 }
115 
116 static bool_t
117 xdrstdio_getbytes(XDR *xdrs, caddr_t addr, u_int len)
118 {
119 
120 	if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
121 		return (FALSE);
122 	return (TRUE);
123 }
124 
125 static bool_t
126 xdrstdio_putbytes(XDR *xdrs, caddr_t addr, u_int len)
127 {
128 
129 	if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
130 		return (FALSE);
131 	return (TRUE);
132 }
133 
134 static u_int
135 xdrstdio_getpos(XDR *xdrs)
136 {
137 
138 	return ((u_int) ftell((FILE *)xdrs->x_private));
139 }
140 
141 static bool_t
142 xdrstdio_setpos(XDR *xdrs, u_int pos)
143 {
144 
145 	return ((fseek((FILE *)xdrs->x_private, (long)pos, SEEK_SET) < 0) ?
146 		FALSE : TRUE);
147 }
148 
149 /* ARGSUSED */
150 static int32_t *
151 xdrstdio_inline(XDR *xdrs, u_int len)
152 {
153 
154 	/*
155 	 * Must do some work to implement this: must ensure
156 	 * enough data in the underlying stdio buffer,
157 	 * that the buffer is aligned so that we can indirect through a
158 	 * long *, and stuff this pointer in xdrs->x_buf.  Doing
159 	 * a fread or fwrite to a scratch buffer would defeat
160 	 * most of the gains to be had here and require storage
161 	 * management on this buffer, so we don't do this.
162 	 */
163 	return (NULL);
164 }
165