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