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 bool_t 105 harmless_getlong(XDR *xdr __unused, long *l __unused) 106 { 107 /* Always return FALSE/NULL, as the case may be */ 108 return (FALSE); 109 } 110 111 static bool_t 112 harmless_getbytes(XDR *xdr __unused, caddr_t p __unused, int i __unused) 113 { 114 return (FALSE); 115 } 116 117 #if defined(_LP64) 118 static bool_t 119 harmless_getint32(XDR *xdr __unused, int32_t *p __unused) 120 { 121 return (FALSE); 122 } 123 #endif 124 125 static void 126 x_destroy(XDR *xdrs) 127 { 128 xdrs->x_handy = 0; 129 xdrs->x_base = 0; 130 if (xdrs->x_private) { 131 free(xdrs->x_private); 132 xdrs->x_private = NULL; 133 } 134 } 135 136 uint_t 137 xdr_sizeof(xdrproc_t func, void *data) 138 { 139 XDR x; 140 struct xdr_ops ops; 141 bool_t stat; 142 /* to stop ANSI-C compiler from complaining */ 143 144 ops.x_putlong = x_putlong; 145 ops.x_getlong = harmless_getlong; 146 ops.x_putbytes = x_putbytes; 147 ops.x_inline = x_inline; 148 ops.x_getpostn = x_getpostn; 149 ops.x_setpostn = x_setpostn; 150 ops.x_destroy = x_destroy; 151 #if defined(_LP64) 152 ops.x_getint32 = harmless_getint32; 153 ops.x_putint32 = x_putint32_t; 154 #endif 155 156 /* the other harmless ones */ 157 ops.x_getbytes = harmless_getbytes; 158 159 x.x_op = XDR_ENCODE; 160 x.x_ops = &ops; 161 x.x_handy = 0; 162 x.x_private = NULL; 163 x.x_base = NULL; 164 165 stat = func(&x, data); 166 if (x.x_private) 167 free(x.x_private); 168 return (stat == TRUE ? (uint_t)x.x_handy : 0); 169 } 170