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 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 /* 31 * General purpose routine to see how much space something will use 32 * when serialized using XDR. 33 */ 34 #include "mt.h" 35 #include <rpc/types.h> 36 #include <rpc/xdr.h> 37 #include <sys/types.h> 38 #include <stdlib.h> 39 40 /* ARGSUSED1 */ 41 static bool_t 42 x_putlong(XDR *xdrs, long *ip) 43 { 44 xdrs->x_handy += BYTES_PER_XDR_UNIT; 45 return (TRUE); 46 } 47 48 #if defined(_LP64) 49 /* ARGSUSED1 */ 50 static bool_t 51 x_putint32_t(XDR *xdrs, int32_t *ip) 52 { 53 xdrs->x_handy += BYTES_PER_XDR_UNIT; 54 return (TRUE); 55 } 56 #endif 57 58 /* ARGSUSED */ 59 static bool_t 60 x_putbytes(XDR *xdrs, char *bp, int len) 61 { 62 xdrs->x_handy += len; 63 return (TRUE); 64 } 65 66 static uint_t 67 x_getpostn(XDR *xdrs) 68 { 69 return (xdrs->x_handy); 70 } 71 72 /* ARGSUSED */ 73 static bool_t 74 x_setpostn(XDR *xdrs, uint_t pos) 75 { 76 /* This is not allowed */ 77 return (FALSE); 78 } 79 80 static rpc_inline_t * 81 x_inline(XDR *xdrs, int len) 82 { 83 if (len == 0) 84 return (NULL); 85 if (xdrs->x_op != XDR_ENCODE) 86 return (NULL); 87 if (len < (intptr_t)xdrs->x_base) { 88 /* x_private was already allocated */ 89 xdrs->x_handy += len; 90 /* LINTED pointer cast */ 91 return ((rpc_inline_t *)xdrs->x_private); 92 } 93 /* Free the earlier space and allocate new area */ 94 if (xdrs->x_private) 95 free(xdrs->x_private); 96 if ((xdrs->x_private = malloc(len)) == NULL) { 97 xdrs->x_base = 0; 98 return (NULL); 99 } 100 xdrs->x_base = (caddr_t)(intptr_t)len; 101 xdrs->x_handy += len; 102 /* LINTED pointer cast */ 103 return ((rpc_inline_t *)xdrs->x_private); 104 } 105 106 static int 107 harmless(void) 108 { 109 /* Always return FALSE/NULL, as the case may be */ 110 return (0); 111 } 112 113 static void 114 x_destroy(XDR *xdrs) 115 { 116 xdrs->x_handy = 0; 117 xdrs->x_base = 0; 118 if (xdrs->x_private) { 119 free(xdrs->x_private); 120 xdrs->x_private = NULL; 121 } 122 } 123 124 uint_t 125 xdr_sizeof(xdrproc_t func, void *data) 126 { 127 XDR x; 128 struct xdr_ops ops; 129 bool_t stat; 130 /* to stop ANSI-C compiler from complaining */ 131 typedef bool_t (* dummyfunc1)(XDR *, long *); 132 typedef bool_t (* dummyfunc2)(XDR *, caddr_t, int); 133 typedef bool_t (* dummyfunc3)(XDR *, int32_t *); 134 135 ops.x_putlong = x_putlong; 136 ops.x_getlong = (dummyfunc1) harmless; 137 ops.x_putbytes = x_putbytes; 138 ops.x_inline = x_inline; 139 ops.x_getpostn = x_getpostn; 140 ops.x_setpostn = x_setpostn; 141 ops.x_destroy = x_destroy; 142 #if defined(_LP64) 143 ops.x_getint32 = (dummyfunc3) harmless; 144 ops.x_putint32 = x_putint32_t; 145 #endif 146 147 /* the other harmless ones */ 148 ops.x_getbytes = (dummyfunc2) harmless; 149 150 x.x_op = XDR_ENCODE; 151 x.x_ops = &ops; 152 x.x_handy = 0; 153 x.x_private = NULL; 154 x.x_base = NULL; 155 156 stat = func(&x, data); 157 if (x.x_private) 158 free(x.x_private); 159 return (stat == TRUE ? (uint_t)x.x_handy : 0); 160 } 161