xref: /illumos-gate/usr/src/lib/libnsl/rpc/xdr_stdio.c (revision 683007910b81ed9ff942db7c464d1b6df524048a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29 /*
30  * Portions of this source code were derived from Berkeley
31  * 4.3 BSD under license from the Regents of the University of
32  * California.
33  */
34 
35 #pragma ident	"%Z%%M%	%I%	%E% SMI"
36 
37 /*
38  * xdr_stdio.c, XDR implementation on standard i/o file.
39  *
40  * This set of routines implements a XDR on a stdio stream.
41  * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
42  * from the stream.
43  */
44 
45 #include "mt.h"
46 #include "rpc_mt.h"
47 #include <rpc/types.h>
48 #include <stdio.h>
49 #include <rpc/xdr.h>
50 #include <sys/types.h>
51 #include <inttypes.h>
52 
53 static struct xdr_ops *xdrstdio_ops(void);
54 
55 /*
56  * Initialize a stdio xdr stream.
57  * Sets the xdr stream handle xdrs for use on the stream file.
58  * Operation flag is set to op.
59  */
60 void
61 xdrstdio_create(XDR *xdrs, FILE *file, const enum xdr_op op)
62 {
63 	xdrs->x_op = op;
64 	xdrs->x_ops = xdrstdio_ops();
65 	xdrs->x_private = (caddr_t)file;
66 	xdrs->x_handy = 0;
67 	xdrs->x_base = 0;
68 }
69 
70 /*
71  * Destroy a stdio xdr stream.
72  * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
73  */
74 static void
75 xdrstdio_destroy(XDR *xdrs)
76 {
77 	/* LINTED pointer cast */
78 	(void) fflush((FILE *)xdrs->x_private);
79 	/* xx should we close the file ?? */
80 }
81 
82 
83 static bool_t
84 xdrstdio_getint32(XDR *xdrs, int32_t *lp)
85 {
86 	if (fread((caddr_t)lp, sizeof (int32_t), 1,
87 			/* LINTED pointer cast */
88 			(FILE *)xdrs->x_private) != 1)
89 		return (FALSE);
90 	*lp = ntohl(*lp);
91 	return (TRUE);
92 }
93 
94 static bool_t
95 xdrstdio_putint32(XDR *xdrs, int32_t *lp)
96 {
97 
98 	int32_t mycopy = htonl(*lp);
99 	lp = &mycopy;
100 
101 	if (fwrite((caddr_t)lp, sizeof (int32_t), 1,
102 			/* LINTED pointer cast */
103 			(FILE *)xdrs->x_private) != 1)
104 		return (FALSE);
105 	return (TRUE);
106 }
107 
108 static bool_t
109 xdrstdio_getlong(XDR *xdrs, long *lp)
110 {
111 	int32_t i;
112 
113 	if (!xdrstdio_getint32(xdrs, &i))
114 		return (FALSE);
115 	*lp = (long)i;
116 	return (TRUE);
117 }
118 
119 static bool_t
120 xdrstdio_putlong(XDR *xdrs, long *lp)
121 {
122 	int32_t i;
123 
124 #if defined(_LP64)
125 	if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
126 		return (FALSE);
127 #endif
128 	i = (int32_t)*lp;
129 
130 	return (xdrstdio_putint32(xdrs, &i));
131 }
132 
133 static bool_t
134 xdrstdio_getbytes(XDR *xdrs, caddr_t addr, int len)
135 {
136 	if ((len != 0) &&
137 		/* LINTED pointer cast */
138 		(fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
139 		return (FALSE);
140 	return (TRUE);
141 }
142 
143 static bool_t
144 xdrstdio_putbytes(XDR *xdrs, caddr_t addr, int len)
145 {
146 	if ((len != 0) &&
147 		/* LINTED pointer cast */
148 		(fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
149 		return (FALSE);
150 	return (TRUE);
151 }
152 
153 static uint_t
154 xdrstdio_getpos(XDR *xdrs)
155 {
156 	/* LINTED pointer cast */
157 	return ((uint_t)ftell((FILE *)xdrs->x_private));
158 }
159 
160 static bool_t
161 xdrstdio_setpos(XDR *xdrs, uint_t pos)
162 {
163 	/* LINTED pointer cast */
164 	return ((fseek((FILE *)xdrs->x_private,
165 			(int)pos, 0) < 0) ? FALSE : TRUE);
166 }
167 
168 /* ARGSUSED */
169 static rpc_inline_t *
170 xdrstdio_inline(XDR *xdrs, int len)
171 {
172 	/*
173 	 * Must do some work to implement this: must insure
174 	 * enough data in the underlying stdio buffer,
175 	 * that the buffer is aligned so that we can indirect through a
176 	 * long *, and stuff this pointer in xdrs->x_buf.  Doing
177 	 * a fread or fwrite to a scratch buffer would defeat
178 	 * most of the gains to be had here and require storage
179 	 * management on this buffer, so we don't do this.
180 	 */
181 	return (NULL);
182 }
183 
184 /* ARGSUSED */
185 static bool_t
186 xdrstdio_control(XDR *xdrs, int request, void *info)
187 {
188 	return (FALSE);
189 }
190 
191 static struct xdr_ops *
192 xdrstdio_ops(void)
193 {
194 	static struct xdr_ops ops;
195 	extern mutex_t	ops_lock;
196 
197 /* VARIABLES PROTECTED BY ops_lock: ops */
198 
199 	(void) mutex_lock(&ops_lock);
200 	if (ops.x_getlong == NULL) {
201 		ops.x_getlong = xdrstdio_getlong;
202 		ops.x_putlong = xdrstdio_putlong;
203 		ops.x_getbytes = xdrstdio_getbytes;
204 		ops.x_putbytes = xdrstdio_putbytes;
205 		ops.x_getpostn = xdrstdio_getpos;
206 		ops.x_setpostn = xdrstdio_setpos;
207 		ops.x_inline = xdrstdio_inline;
208 		ops.x_destroy = xdrstdio_destroy;
209 		ops.x_control = xdrstdio_control;
210 #if defined(_LP64)
211 		ops.x_getint32 = xdrstdio_getint32;
212 		ops.x_putint32 = xdrstdio_putint32;
213 #endif
214 	}
215 	(void) mutex_unlock(&ops_lock);
216 	return (&ops);
217 }
218