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