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 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 /* 28 * Portions of this source code were derived from Berkeley 29 * 4.3 BSD under license from the Regents of the University of 30 * California. 31 */ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 /* 36 * xdr_stdio.c, XDR implementation on standard i/o file. 37 * 38 * This set of routines implements a XDR on a stdio stream. 39 * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes 40 * from the stream. 41 */ 42 43 #include "mt.h" 44 #include "rpc_mt.h" 45 #include <rpc/types.h> 46 #include <stdio.h> 47 #include <rpc/xdr.h> 48 #include <sys/types.h> 49 #include <rpc/trace.h> 50 #include <inttypes.h> 51 52 static struct xdr_ops *xdrstdio_ops(void); 53 54 /* 55 * Initialize a stdio xdr stream. 56 * Sets the xdr stream handle xdrs for use on the stream file. 57 * Operation flag is set to op. 58 */ 59 void 60 xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op) 61 { 62 trace1(TR_xdrstdio_create, 0); 63 xdrs->x_op = op; 64 xdrs->x_ops = xdrstdio_ops(); 65 xdrs->x_private = (caddr_t)file; 66 xdrs->x_handy = 0; 67 xdrs->x_base = 0; 68 trace1(TR_xdrstdio_create, 1); 69 } 70 71 /* 72 * Destroy a stdio xdr stream. 73 * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. 74 */ 75 static void 76 xdrstdio_destroy(XDR *xdrs) 77 { 78 trace1(TR_xdrstdio_destroy, 0); 79 (void) fflush((FILE *)xdrs->x_private); 80 /* xx should we close the file ?? */ 81 trace1(TR_xdrstdio_destroy, 1); 82 } 83 84 85 static bool_t 86 xdrstdio_getint32(XDR *xdrs, int32_t *lp) 87 { 88 trace1(TR_xdrstdio_getint32, 0); 89 if (fread((caddr_t)lp, sizeof (int32_t), 1, 90 (FILE *)xdrs->x_private) != 1) { 91 trace1(TR_xdrstdio_getint32, 1); 92 return (FALSE); 93 } 94 *lp = ntohl(*lp); 95 trace1(TR_xdrstdio_getint32, 1); 96 return (TRUE); 97 } 98 99 static bool_t 100 xdrstdio_putint32(XDR *xdrs, int32_t *lp) 101 { 102 103 int32_t mycopy = htonl(*lp); 104 lp = &mycopy; 105 106 trace1(TR_xdrstdio_putint32, 0); 107 if (fwrite((caddr_t)lp, sizeof (int32_t), 1, 108 (FILE *)xdrs->x_private) != 1) { 109 trace1(TR_xdrstdio_putint32, 1); 110 return (FALSE); 111 } 112 trace1(TR_xdrstdio_putint32, 1); 113 return (TRUE); 114 } 115 116 static bool_t 117 xdrstdio_getlong(xdrs, lp) 118 XDR *xdrs; 119 long *lp; 120 { 121 int32_t i; 122 123 if (!xdrstdio_getint32(xdrs, &i)) 124 return (FALSE); 125 126 *lp = (long)i; 127 128 return (TRUE); 129 } 130 131 static bool_t 132 xdrstdio_putlong(xdrs, lp) 133 XDR *xdrs; 134 long *lp; 135 { 136 int32_t i; 137 138 #if defined(_LP64) 139 if ((*lp > INT32_MAX) || (*lp < INT32_MIN)) { 140 return (FALSE); 141 } 142 #endif 143 144 i = (int32_t)*lp; 145 146 return (xdrstdio_putint32(xdrs, &i)); 147 } 148 149 static bool_t 150 xdrstdio_getbytes(XDR *xdrs, caddr_t addr, int len) 151 { 152 trace2(TR_xdrstdio_getbytes, 0, len); 153 if ((len != 0) && 154 (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) { 155 trace1(TR_xdrstdio_getbytes, 1); 156 return (FALSE); 157 } 158 trace1(TR_xdrstdio_getbytes, 1); 159 return (TRUE); 160 } 161 162 static bool_t 163 xdrstdio_putbytes(XDR *xdrs, caddr_t addr, int len) 164 { 165 trace2(TR_xdrstdio_putbytes, 0, len); 166 if ((len != 0) && 167 (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) { 168 trace1(TR_xdrstdio_putbytes, 1); 169 return (FALSE); 170 } 171 trace1(TR_xdrstdio_putbytes, 1); 172 return (TRUE); 173 } 174 175 static uint_t 176 xdrstdio_getpos(XDR *xdrs) 177 { 178 uint_t dummy1; 179 180 trace1(TR_xdrstdio_getpos, 0); 181 dummy1 = (uint_t)ftell((FILE *)xdrs->x_private); 182 trace1(TR_xdrstdio_getpos, 1); 183 return (dummy1); 184 } 185 186 static bool_t 187 xdrstdio_setpos(XDR *xdrs, uint_t pos) 188 { 189 bool_t dummy2; 190 191 trace2(TR_xdrstdio_setpos, 0, pos); 192 dummy2 = (fseek((FILE *)xdrs->x_private, 193 (int)pos, 0) < 0) ? FALSE : TRUE; 194 trace1(TR_xdrstdio_setpos, 1); 195 return (dummy2); 196 } 197 198 static rpc_inline_t * 199 xdrstdio_inline(XDR *xdrs, int len) 200 { 201 202 /* 203 * Must do some work to implement this: must insure 204 * enough data in the underlying stdio buffer, 205 * that the buffer is aligned so that we can indirect through a 206 * long *, and stuff this pointer in xdrs->x_buf. Doing 207 * a fread or fwrite to a scratch buffer would defeat 208 * most of the gains to be had here and require storage 209 * management on this buffer, so we don't do this. 210 */ 211 trace2(TR_xdrstdio_inline, 0, len); 212 trace2(TR_xdrstdio_inline, 1, len); 213 return (NULL); 214 } 215 216 static bool_t 217 xdrstdio_control(XDR *xdrs, int request, void *info) 218 { 219 switch (request) { 220 221 default: 222 return (FALSE); 223 } 224 } 225 226 static struct xdr_ops * 227 xdrstdio_ops() 228 { 229 static struct xdr_ops ops; 230 extern mutex_t ops_lock; 231 232 /* VARIABLES PROTECTED BY ops_lock: ops */ 233 234 trace1(TR_xdrstdio_ops, 0); 235 mutex_lock(&ops_lock); 236 if (ops.x_getlong == NULL) { 237 ops.x_getlong = xdrstdio_getlong; 238 ops.x_putlong = xdrstdio_putlong; 239 ops.x_getbytes = xdrstdio_getbytes; 240 ops.x_putbytes = xdrstdio_putbytes; 241 ops.x_getpostn = xdrstdio_getpos; 242 ops.x_setpostn = xdrstdio_setpos; 243 ops.x_inline = xdrstdio_inline; 244 ops.x_destroy = xdrstdio_destroy; 245 ops.x_control = xdrstdio_control; 246 #if defined(_LP64) 247 ops.x_getint32 = xdrstdio_getint32; 248 ops.x_putint32 = xdrstdio_putint32; 249 #endif 250 } 251 mutex_unlock(&ops_lock); 252 trace1(TR_xdrstdio_ops, 1); 253 return (&ops); 254 } 255