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 /* 29 * General purpose routine to see how much space something will use 30 * when serialized using XDR. 31 */ 32 #include "mt.h" 33 #include <rpc/types.h> 34 #include <rpc/xdr.h> 35 #include <sys/types.h> 36 #include <stdlib.h> 37 38 /* ARGSUSED1 */ 39 static bool_t 40 x_putlong(XDR *xdrs, long *ip) 41 { 42 xdrs->x_handy += BYTES_PER_XDR_UNIT; 43 return (TRUE); 44 } 45 46 #if defined(_LP64) 47 /* ARGSUSED1 */ 48 static bool_t 49 x_putint32_t(XDR *xdrs, int32_t *ip) 50 { 51 xdrs->x_handy += BYTES_PER_XDR_UNIT; 52 return (TRUE); 53 } 54 #endif 55 56 /* ARGSUSED */ 57 static bool_t 58 x_putbytes(XDR *xdrs, char *bp, int len) 59 { 60 xdrs->x_handy += len; 61 return (TRUE); 62 } 63 64 static uint_t 65 x_getpostn(XDR *xdrs) 66 { 67 return (xdrs->x_handy); 68 } 69 70 /* ARGSUSED */ 71 static bool_t 72 x_setpostn(XDR *xdrs, uint_t pos) 73 { 74 /* This is not allowed */ 75 return (FALSE); 76 } 77 78 static rpc_inline_t * 79 x_inline(XDR *xdrs, int len) 80 { 81 if (len == 0) 82 return (NULL); 83 if (xdrs->x_op != XDR_ENCODE) 84 return (NULL); 85 if (len < (intptr_t)xdrs->x_base) { 86 /* x_private was already allocated */ 87 xdrs->x_handy += len; 88 /* LINTED pointer cast */ 89 return ((rpc_inline_t *)xdrs->x_private); 90 } 91 /* Free the earlier space and allocate new area */ 92 if (xdrs->x_private) 93 free(xdrs->x_private); 94 if ((xdrs->x_private = malloc(len)) == NULL) { 95 xdrs->x_base = 0; 96 return (NULL); 97 } 98 xdrs->x_base = (caddr_t)(intptr_t)len; 99 xdrs->x_handy += len; 100 /* LINTED pointer cast */ 101 return ((rpc_inline_t *)xdrs->x_private); 102 } 103 104 static int 105 harmless(void) 106 { 107 /* Always return FALSE/NULL, as the case may be */ 108 return (0); 109 } 110 111 static void 112 x_destroy(XDR *xdrs) 113 { 114 xdrs->x_handy = 0; 115 xdrs->x_base = 0; 116 if (xdrs->x_private) { 117 free(xdrs->x_private); 118 xdrs->x_private = NULL; 119 } 120 } 121 122 uint_t 123 xdr_sizeof(xdrproc_t func, void *data) 124 { 125 XDR x; 126 struct xdr_ops ops; 127 bool_t stat; 128 /* to stop ANSI-C compiler from complaining */ 129 typedef bool_t (* dummyfunc1)(XDR *, long *); 130 typedef bool_t (* dummyfunc2)(XDR *, caddr_t, int); 131 #if defined(_LP64) 132 typedef bool_t (* dummyfunc3)(XDR *, int32_t *); 133 #endif 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