xdr_sizeof.c revision 285830
1130331Sanholt/*
2145132Sanholt * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3145132Sanholt * unrestricted use provided that this legend is included on all tape
4145132Sanholt * media and as a part of the software program in whole or part.  Users
5130331Sanholt * may copy or modify Sun RPC without charge, but are not authorized
6130331Sanholt * to license or distribute it to anyone else except as part of a product or
7130331Sanholt * program developed by the user.
8130331Sanholt *
9182080Srnoland * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10182080Srnoland * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11182080Srnoland * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12182080Srnoland *
13182080Srnoland * Sun RPC is provided with no support and without any obligation on the
14182080Srnoland * part of Sun Microsystems, Inc. to assist in its use, correction,
15182080Srnoland * modification or enhancement.
16157617Sanholt *
17145132Sanholt * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18157617Sanholt * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19157617Sanholt * OR ANY PART THEREOF.
20157617Sanholt *
21157617Sanholt * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22157617Sanholt * or profits or other special, indirect and consequential damages, even if
23157617Sanholt * Sun has been advised of the possibility of such damages.
24145132Sanholt *
25157617Sanholt * Sun Microsystems, Inc.
26157617Sanholt * 2550 Garcia Avenue
27157617Sanholt * Mountain View, California  94043
28145132Sanholt */
29157617Sanholt/*
30157617Sanholt * xdr_sizeof.c
31182080Srnoland *
32145132Sanholt * Copyright 1990 Sun Microsystems, Inc.
33145132Sanholt *
34182080Srnoland * General purpose routine to see how much space something will use
35182080Srnoland * when serialized using XDR.
36182080Srnoland */
37157617Sanholt
38157617Sanholt#include <sys/cdefs.h>
39182080Srnoland__FBSDID("$FreeBSD: releng/10.2/sys/xdr/xdr_sizeof.c 177633 2008-03-26 15:23:12Z dfr $");
40182080Srnoland
41182080Srnoland#include <sys/param.h>
42182080Srnoland#include <sys/systm.h>
43182080Srnoland#include <sys/malloc.h>
44182080Srnoland
45182080Srnoland#include <rpc/types.h>
46182080Srnoland#include <rpc/xdr.h>
47182080Srnoland
48182080Srnoland/* ARGSUSED */
49182080Srnolandstatic bool_t
50182080Srnolandx_putlong(XDR *xdrs, const long *longp)
51182080Srnoland{
52182080Srnoland
53182080Srnoland	xdrs->x_handy += BYTES_PER_XDR_UNIT;
54182080Srnoland	return (TRUE);
55182080Srnoland}
56182080Srnoland
57182080Srnoland/* ARGSUSED */
58157617Sanholtstatic bool_t
59182080Srnolandx_putbytes(XDR *xdrs, const char *bp, u_int len)
60148211Sanholt{
61157617Sanholt
62157617Sanholt	xdrs->x_handy += len;
63148211Sanholt	return (TRUE);
64148211Sanholt}
65148211Sanholt
66157617Sanholtstatic u_int
67157617Sanholtx_getpostn(XDR *xdrs)
68182080Srnoland{
69182080Srnoland
70182080Srnoland	return (xdrs->x_handy);
71182080Srnoland}
72182080Srnoland
73182080Srnoland/* ARGSUSED */
74182080Srnolandstatic bool_t
75182080Srnolandx_setpostn(XDR *xdrs, u_int pos)
76182080Srnoland{
77182080Srnoland
78145132Sanholt	/* This is not allowed */
79145132Sanholt	return (FALSE);
80145132Sanholt}
81145132Sanholt
82145132Sanholtstatic int32_t *
83145132Sanholtx_inline(XDR *xdrs, u_int len)
84145132Sanholt{
85152909Sanholt
86182080Srnoland	if (len == 0) {
87182080Srnoland		return (NULL);
88182080Srnoland	}
89183830Srnoland	if (xdrs->x_op != XDR_ENCODE) {
90183830Srnoland		return (NULL);
91183830Srnoland	}
92183830Srnoland	if (len < (u_int)(uintptr_t)xdrs->x_base) {
93183830Srnoland		/* x_private was already allocated */
94183830Srnoland		xdrs->x_handy += len;
95183830Srnoland		return ((int32_t *) xdrs->x_private);
96183830Srnoland	} else {
97183830Srnoland		/* Free the earlier space and allocate new area */
98183830Srnoland		if (xdrs->x_private)
99183830Srnoland			free(xdrs->x_private, M_RPC);
100183830Srnoland		if ((xdrs->x_private = (caddr_t) malloc(len, M_RPC, M_WAITOK)) == NULL) {
101182080Srnoland			xdrs->x_base = 0;
102182080Srnoland			return (NULL);
103182080Srnoland		}
104182080Srnoland		xdrs->x_base = (caddr_t)(uintptr_t) len;
105182080Srnoland		xdrs->x_handy += len;
106182080Srnoland		return ((int32_t *) xdrs->x_private);
107182080Srnoland	}
108182080Srnoland}
109182080Srnoland
110182080Srnolandstatic int
111182080Srnolandharmless(void)
112182080Srnoland{
113157617Sanholt
114157617Sanholt	/* Always return FALSE/NULL, as the case may be */
115145132Sanholt	return (0);
116145132Sanholt}
117157617Sanholt
118145132Sanholtstatic void
119182080Srnolandx_destroy(XDR *xdrs)
120182080Srnoland{
121182080Srnoland
122182080Srnoland	xdrs->x_handy = 0;
123182080Srnoland	xdrs->x_base = 0;
124182080Srnoland	if (xdrs->x_private) {
125182080Srnoland		free(xdrs->x_private, M_RPC);
126182080Srnoland		xdrs->x_private = NULL;
127182080Srnoland	}
128182080Srnoland	return;
129182080Srnoland}
130183830Srnoland
131183830Srnolandunsigned long
132183830Srnolandxdr_sizeof(xdrproc_t func, void *data)
133183830Srnoland{
134183830Srnoland	XDR x;
135183830Srnoland	struct xdr_ops ops;
136183830Srnoland	bool_t stat;
137183830Srnoland	/* to stop ANSI-C compiler from complaining */
138183830Srnoland	typedef  bool_t (* dummyfunc1)(XDR *, long *);
139183830Srnoland	typedef  bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
140182080Srnoland
141182080Srnoland	ops.x_putlong = x_putlong;
142182080Srnoland	ops.x_putbytes = x_putbytes;
143182080Srnoland	ops.x_inline = x_inline;
144182080Srnoland	ops.x_getpostn = x_getpostn;
145182080Srnoland	ops.x_setpostn = x_setpostn;
146182080Srnoland	ops.x_destroy = x_destroy;
147182080Srnoland
148182080Srnoland	/* the other harmless ones */
149182080Srnoland	ops.x_getlong =  (dummyfunc1) harmless;
150182080Srnoland	ops.x_getbytes = (dummyfunc2) harmless;
151182080Srnoland
152182080Srnoland	x.x_op = XDR_ENCODE;
153182080Srnoland	x.x_ops = &ops;
154182080Srnoland	x.x_handy = 0;
155182080Srnoland	x.x_private = (caddr_t) NULL;
156182080Srnoland	x.x_base = (caddr_t) 0;
157182080Srnoland
158182080Srnoland	stat = func(&x, data);
159182080Srnoland	if (x.x_private)
160182080Srnoland		free(x.x_private, M_RPC);
161182080Srnoland	return (stat == TRUE ? (unsigned) x.x_handy: 0);
162182080Srnoland}
163182080Srnoland