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