| 1 | /* | 
|---|
| 2 | * xdr.c, Generic XDR routines implementation. | 
|---|
| 3 | * | 
|---|
| 4 | * Copyright (c) 2010, Oracle America, Inc. | 
|---|
| 5 | * | 
|---|
| 6 | * Redistribution and use in source and binary forms, with or without | 
|---|
| 7 | * modification, are permitted provided that the following conditions are | 
|---|
| 8 | * met: | 
|---|
| 9 | * | 
|---|
| 10 | *     * Redistributions of source code must retain the above copyright | 
|---|
| 11 | *       notice, this list of conditions and the following disclaimer. | 
|---|
| 12 | *     * Redistributions in binary form must reproduce the above | 
|---|
| 13 | *       copyright notice, this list of conditions and the following | 
|---|
| 14 | *       disclaimer in the documentation and/or other materials | 
|---|
| 15 | *       provided with the distribution. | 
|---|
| 16 | *     * Neither the name of the "Oracle America, Inc." nor the names of its | 
|---|
| 17 | *       contributors may be used to endorse or promote products derived | 
|---|
| 18 | *       from this software without specific prior written permission. | 
|---|
| 19 | * | 
|---|
| 20 | *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|---|
| 21 | *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|---|
| 22 | *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 
|---|
| 23 | *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 
|---|
| 24 | *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | 
|---|
| 25 | *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
|---|
| 26 | *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | 
|---|
| 27 | *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 
|---|
| 28 | *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 
|---|
| 29 | *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
|---|
| 30 | *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|---|
| 31 | *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|---|
| 32 | * | 
|---|
| 33 | * These are the "generic" xdr routines used to serialize and de-serialize | 
|---|
| 34 | * most common data items.  See xdr.h for more info on the interface to | 
|---|
| 35 | * xdr. | 
|---|
| 36 | */ | 
|---|
| 37 |  | 
|---|
| 38 | #include <stdio.h> | 
|---|
| 39 | #include <limits.h> | 
|---|
| 40 | #include <string.h> | 
|---|
| 41 | #include <libintl.h> | 
|---|
| 42 | #include <wchar.h> | 
|---|
| 43 | #include <stdint.h> | 
|---|
| 44 |  | 
|---|
| 45 | #include <rpc/types.h> | 
|---|
| 46 | #include <rpc/xdr.h> | 
|---|
| 47 | #include <shlib-compat.h> | 
|---|
| 48 |  | 
|---|
| 49 |  | 
|---|
| 50 | /* | 
|---|
| 51 | * constants specific to the xdr "protocol" | 
|---|
| 52 | */ | 
|---|
| 53 | #define XDR_FALSE	((long) 0) | 
|---|
| 54 | #define XDR_TRUE	((long) 1) | 
|---|
| 55 | #define LASTUNSIGNED	((u_int) 0-1) | 
|---|
| 56 |  | 
|---|
| 57 | /* | 
|---|
| 58 | * for unit alignment | 
|---|
| 59 | */ | 
|---|
| 60 | static const char xdr_zero[BYTES_PER_XDR_UNIT] = {0, 0, 0, 0}; | 
|---|
| 61 |  | 
|---|
| 62 | /* | 
|---|
| 63 | * Free a data structure using XDR | 
|---|
| 64 | * Not a filter, but a convenient utility nonetheless | 
|---|
| 65 | */ | 
|---|
| 66 | void | 
|---|
| 67 | xdr_free (xdrproc_t proc, char *objp) | 
|---|
| 68 | { | 
|---|
| 69 | XDR x; | 
|---|
| 70 |  | 
|---|
| 71 | x.x_op = XDR_FREE; | 
|---|
| 72 | (*proc) (&x, objp); | 
|---|
| 73 | } | 
|---|
| 74 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 75 | libc_hidden_def (xdr_free) | 
|---|
| 76 | #else | 
|---|
| 77 | libc_hidden_nolink_sunrpc (xdr_free, GLIBC_2_0) | 
|---|
| 78 | #endif | 
|---|
| 79 |  | 
|---|
| 80 | /* | 
|---|
| 81 | * XDR nothing | 
|---|
| 82 | */ | 
|---|
| 83 | bool_t | 
|---|
| 84 | xdr_void (void) | 
|---|
| 85 | { | 
|---|
| 86 | return TRUE; | 
|---|
| 87 | } | 
|---|
| 88 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 89 | libc_hidden_def (xdr_void) | 
|---|
| 90 | #else | 
|---|
| 91 | libc_hidden_nolink_sunrpc (xdr_void, GLIBC_2_0) | 
|---|
| 92 | #endif | 
|---|
| 93 |  | 
|---|
| 94 | /* | 
|---|
| 95 | * XDR integers | 
|---|
| 96 | */ | 
|---|
| 97 | bool_t | 
|---|
| 98 | xdr_int (XDR *xdrs, int *ip) | 
|---|
| 99 | { | 
|---|
| 100 |  | 
|---|
| 101 | #if INT_MAX < LONG_MAX | 
|---|
| 102 | long l; | 
|---|
| 103 |  | 
|---|
| 104 | switch (xdrs->x_op) | 
|---|
| 105 | { | 
|---|
| 106 | case XDR_ENCODE: | 
|---|
| 107 | l = (long) *ip; | 
|---|
| 108 | return XDR_PUTLONG (xdrs, &l); | 
|---|
| 109 |  | 
|---|
| 110 | case XDR_DECODE: | 
|---|
| 111 | if (!XDR_GETLONG (xdrs, &l)) | 
|---|
| 112 | { | 
|---|
| 113 | return FALSE; | 
|---|
| 114 | } | 
|---|
| 115 | *ip = (int) l; | 
|---|
| 116 | /* Fall through.  */ | 
|---|
| 117 | case XDR_FREE: | 
|---|
| 118 | return TRUE; | 
|---|
| 119 | } | 
|---|
| 120 | return FALSE; | 
|---|
| 121 | #elif INT_MAX == LONG_MAX | 
|---|
| 122 | return xdr_long (xdrs, (long *) ip); | 
|---|
| 123 | #elif INT_MAX == SHRT_MAX | 
|---|
| 124 | return xdr_short (xdrs, (short *) ip); | 
|---|
| 125 | #else | 
|---|
| 126 | #error unexpected integer sizes in_xdr_int() | 
|---|
| 127 | #endif | 
|---|
| 128 | } | 
|---|
| 129 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 130 | libc_hidden_def (xdr_int) | 
|---|
| 131 | #else | 
|---|
| 132 | libc_hidden_nolink_sunrpc (xdr_int, GLIBC_2_0) | 
|---|
| 133 | #endif | 
|---|
| 134 |  | 
|---|
| 135 | /* | 
|---|
| 136 | * XDR unsigned integers | 
|---|
| 137 | */ | 
|---|
| 138 | bool_t | 
|---|
| 139 | xdr_u_int (XDR *xdrs, u_int *up) | 
|---|
| 140 | { | 
|---|
| 141 | #if UINT_MAX < ULONG_MAX | 
|---|
| 142 | long l; | 
|---|
| 143 |  | 
|---|
| 144 | switch (xdrs->x_op) | 
|---|
| 145 | { | 
|---|
| 146 | case XDR_ENCODE: | 
|---|
| 147 | l = (u_long) * up; | 
|---|
| 148 | return XDR_PUTLONG (xdrs, &l); | 
|---|
| 149 |  | 
|---|
| 150 | case XDR_DECODE: | 
|---|
| 151 | if (!XDR_GETLONG (xdrs, &l)) | 
|---|
| 152 | { | 
|---|
| 153 | return FALSE; | 
|---|
| 154 | } | 
|---|
| 155 | *up = (u_int) (u_long) l; | 
|---|
| 156 | /* Fall through.  */ | 
|---|
| 157 | case XDR_FREE: | 
|---|
| 158 | return TRUE; | 
|---|
| 159 | } | 
|---|
| 160 | return FALSE; | 
|---|
| 161 | #elif UINT_MAX == ULONG_MAX | 
|---|
| 162 | return xdr_u_long (xdrs, (u_long *) up); | 
|---|
| 163 | #elif UINT_MAX == USHRT_MAX | 
|---|
| 164 | return xdr_short (xdrs, (short *) up); | 
|---|
| 165 | #else | 
|---|
| 166 | #error unexpected integer sizes in_xdr_u_int() | 
|---|
| 167 | #endif | 
|---|
| 168 | } | 
|---|
| 169 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 170 | libc_hidden_def (xdr_u_int) | 
|---|
| 171 | #else | 
|---|
| 172 | libc_hidden_nolink_sunrpc (xdr_u_int, GLIBC_2_0) | 
|---|
| 173 | #endif | 
|---|
| 174 |  | 
|---|
| 175 | /* | 
|---|
| 176 | * XDR long integers | 
|---|
| 177 | * The definition of xdr_long() is kept for backward | 
|---|
| 178 | * compatibility. Instead xdr_int() should be used. | 
|---|
| 179 | */ | 
|---|
| 180 | bool_t | 
|---|
| 181 | xdr_long (XDR *xdrs, long *lp) | 
|---|
| 182 | { | 
|---|
| 183 |  | 
|---|
| 184 | if (xdrs->x_op == XDR_ENCODE | 
|---|
| 185 | && (sizeof (int32_t) == sizeof (long) | 
|---|
| 186 | || (int32_t) *lp == *lp)) | 
|---|
| 187 | return XDR_PUTLONG (xdrs, lp); | 
|---|
| 188 |  | 
|---|
| 189 | if (xdrs->x_op == XDR_DECODE) | 
|---|
| 190 | return XDR_GETLONG (xdrs, lp); | 
|---|
| 191 |  | 
|---|
| 192 | if (xdrs->x_op == XDR_FREE) | 
|---|
| 193 | return TRUE; | 
|---|
| 194 |  | 
|---|
| 195 | return FALSE; | 
|---|
| 196 | } | 
|---|
| 197 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 198 | libc_hidden_def (xdr_long) | 
|---|
| 199 | #else | 
|---|
| 200 | libc_hidden_nolink_sunrpc (xdr_long, GLIBC_2_0) | 
|---|
| 201 | #endif | 
|---|
| 202 |  | 
|---|
| 203 | /* | 
|---|
| 204 | * XDR unsigned long integers | 
|---|
| 205 | * The definition of xdr_u_long() is kept for backward | 
|---|
| 206 | * compatibility. Instead xdr_u_int() should be used. | 
|---|
| 207 | */ | 
|---|
| 208 | bool_t | 
|---|
| 209 | xdr_u_long (XDR *xdrs, u_long *ulp) | 
|---|
| 210 | { | 
|---|
| 211 | switch (xdrs->x_op) | 
|---|
| 212 | { | 
|---|
| 213 | case XDR_DECODE: | 
|---|
| 214 | { | 
|---|
| 215 | long int tmp; | 
|---|
| 216 |  | 
|---|
| 217 | if (XDR_GETLONG (xdrs, &tmp) == FALSE) | 
|---|
| 218 | return FALSE; | 
|---|
| 219 |  | 
|---|
| 220 | *ulp = (uint32_t) tmp; | 
|---|
| 221 | return TRUE; | 
|---|
| 222 | } | 
|---|
| 223 |  | 
|---|
| 224 | case XDR_ENCODE: | 
|---|
| 225 | if (sizeof (uint32_t) != sizeof (u_long) | 
|---|
| 226 | && (uint32_t) *ulp != *ulp) | 
|---|
| 227 | return FALSE; | 
|---|
| 228 |  | 
|---|
| 229 | return XDR_PUTLONG (xdrs, (long *) ulp); | 
|---|
| 230 |  | 
|---|
| 231 | case XDR_FREE: | 
|---|
| 232 | return TRUE; | 
|---|
| 233 | } | 
|---|
| 234 | return FALSE; | 
|---|
| 235 | } | 
|---|
| 236 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 237 | libc_hidden_def (xdr_u_long) | 
|---|
| 238 | #else | 
|---|
| 239 | libc_hidden_nolink_sunrpc (xdr_u_long, GLIBC_2_0) | 
|---|
| 240 | #endif | 
|---|
| 241 |  | 
|---|
| 242 | /* | 
|---|
| 243 | * XDR hyper integers | 
|---|
| 244 | * same as xdr_u_hyper - open coded to save a proc call! | 
|---|
| 245 | */ | 
|---|
| 246 | bool_t | 
|---|
| 247 | xdr_hyper (XDR *xdrs, quad_t *llp) | 
|---|
| 248 | { | 
|---|
| 249 | long int t1, t2; | 
|---|
| 250 |  | 
|---|
| 251 | if (xdrs->x_op == XDR_ENCODE) | 
|---|
| 252 | { | 
|---|
| 253 | t1 = (long) ((*llp) >> 32); | 
|---|
| 254 | t2 = (long) (*llp); | 
|---|
| 255 | return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2)); | 
|---|
| 256 | } | 
|---|
| 257 |  | 
|---|
| 258 | if (xdrs->x_op == XDR_DECODE) | 
|---|
| 259 | { | 
|---|
| 260 | if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2)) | 
|---|
| 261 | return FALSE; | 
|---|
| 262 | *llp = ((quad_t) t1) << 32; | 
|---|
| 263 | *llp |= (uint32_t) t2; | 
|---|
| 264 | return TRUE; | 
|---|
| 265 | } | 
|---|
| 266 |  | 
|---|
| 267 | if (xdrs->x_op == XDR_FREE) | 
|---|
| 268 | return TRUE; | 
|---|
| 269 |  | 
|---|
| 270 | return FALSE; | 
|---|
| 271 | } | 
|---|
| 272 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 273 | libc_hidden_def (xdr_hyper) | 
|---|
| 274 | #else | 
|---|
| 275 | libc_hidden_nolink_sunrpc (xdr_hyper, GLIBC_2_1_1) | 
|---|
| 276 | #endif | 
|---|
| 277 |  | 
|---|
| 278 | /* | 
|---|
| 279 | * XDR hyper integers | 
|---|
| 280 | * same as xdr_hyper - open coded to save a proc call! | 
|---|
| 281 | */ | 
|---|
| 282 | bool_t | 
|---|
| 283 | xdr_u_hyper (XDR *xdrs, u_quad_t *ullp) | 
|---|
| 284 | { | 
|---|
| 285 | long int t1, t2; | 
|---|
| 286 |  | 
|---|
| 287 | if (xdrs->x_op == XDR_ENCODE) | 
|---|
| 288 | { | 
|---|
| 289 | t1 = (unsigned long) ((*ullp) >> 32); | 
|---|
| 290 | t2 = (unsigned long) (*ullp); | 
|---|
| 291 | return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2)); | 
|---|
| 292 | } | 
|---|
| 293 |  | 
|---|
| 294 | if (xdrs->x_op == XDR_DECODE) | 
|---|
| 295 | { | 
|---|
| 296 | if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2)) | 
|---|
| 297 | return FALSE; | 
|---|
| 298 | *ullp = ((u_quad_t) t1) << 32; | 
|---|
| 299 | *ullp |= (uint32_t) t2; | 
|---|
| 300 | return TRUE; | 
|---|
| 301 | } | 
|---|
| 302 |  | 
|---|
| 303 | if (xdrs->x_op == XDR_FREE) | 
|---|
| 304 | return TRUE; | 
|---|
| 305 |  | 
|---|
| 306 | return FALSE; | 
|---|
| 307 | } | 
|---|
| 308 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 309 | libc_hidden_def (xdr_u_hyper) | 
|---|
| 310 | #else | 
|---|
| 311 | libc_hidden_nolink_sunrpc (xdr_u_hyper, GLIBC_2_1_1) | 
|---|
| 312 | #endif | 
|---|
| 313 |  | 
|---|
| 314 | bool_t | 
|---|
| 315 | xdr_longlong_t (XDR *xdrs, quad_t *llp) | 
|---|
| 316 | { | 
|---|
| 317 | return xdr_hyper (xdrs, llp); | 
|---|
| 318 | } | 
|---|
| 319 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 320 | libc_hidden_def (xdr_longlong_t) | 
|---|
| 321 | #else | 
|---|
| 322 | libc_hidden_nolink_sunrpc (xdr_longlong_t, GLIBC_2_1_1) | 
|---|
| 323 | #endif | 
|---|
| 324 |  | 
|---|
| 325 | bool_t | 
|---|
| 326 | xdr_u_longlong_t (XDR *xdrs, u_quad_t *ullp) | 
|---|
| 327 | { | 
|---|
| 328 | return xdr_u_hyper (xdrs, ullp); | 
|---|
| 329 | } | 
|---|
| 330 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 331 | libc_hidden_def (xdr_u_longlong_t) | 
|---|
| 332 | #else | 
|---|
| 333 | libc_hidden_nolink_sunrpc (xdr_u_longlong_t, GLIBC_2_1_1) | 
|---|
| 334 | #endif | 
|---|
| 335 |  | 
|---|
| 336 | /* | 
|---|
| 337 | * XDR short integers | 
|---|
| 338 | */ | 
|---|
| 339 | bool_t | 
|---|
| 340 | xdr_short (XDR *xdrs, short *sp) | 
|---|
| 341 | { | 
|---|
| 342 | long l; | 
|---|
| 343 |  | 
|---|
| 344 | switch (xdrs->x_op) | 
|---|
| 345 | { | 
|---|
| 346 | case XDR_ENCODE: | 
|---|
| 347 | l = (long) *sp; | 
|---|
| 348 | return XDR_PUTLONG (xdrs, &l); | 
|---|
| 349 |  | 
|---|
| 350 | case XDR_DECODE: | 
|---|
| 351 | if (!XDR_GETLONG (xdrs, &l)) | 
|---|
| 352 | { | 
|---|
| 353 | return FALSE; | 
|---|
| 354 | } | 
|---|
| 355 | *sp = (short) l; | 
|---|
| 356 | return TRUE; | 
|---|
| 357 |  | 
|---|
| 358 | case XDR_FREE: | 
|---|
| 359 | return TRUE; | 
|---|
| 360 | } | 
|---|
| 361 | return FALSE; | 
|---|
| 362 | } | 
|---|
| 363 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 364 | libc_hidden_def (xdr_short) | 
|---|
| 365 | #else | 
|---|
| 366 | libc_hidden_nolink_sunrpc (xdr_short, GLIBC_2_0) | 
|---|
| 367 | #endif | 
|---|
| 368 |  | 
|---|
| 369 | /* | 
|---|
| 370 | * XDR unsigned short integers | 
|---|
| 371 | */ | 
|---|
| 372 | bool_t | 
|---|
| 373 | xdr_u_short (XDR *xdrs, u_short *usp) | 
|---|
| 374 | { | 
|---|
| 375 | long l; | 
|---|
| 376 |  | 
|---|
| 377 | switch (xdrs->x_op) | 
|---|
| 378 | { | 
|---|
| 379 | case XDR_ENCODE: | 
|---|
| 380 | l = (u_long) * usp; | 
|---|
| 381 | return XDR_PUTLONG (xdrs, &l); | 
|---|
| 382 |  | 
|---|
| 383 | case XDR_DECODE: | 
|---|
| 384 | if (!XDR_GETLONG (xdrs, &l)) | 
|---|
| 385 | { | 
|---|
| 386 | return FALSE; | 
|---|
| 387 | } | 
|---|
| 388 | *usp = (u_short) (u_long) l; | 
|---|
| 389 | return TRUE; | 
|---|
| 390 |  | 
|---|
| 391 | case XDR_FREE: | 
|---|
| 392 | return TRUE; | 
|---|
| 393 | } | 
|---|
| 394 | return FALSE; | 
|---|
| 395 | } | 
|---|
| 396 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 397 | libc_hidden_def (xdr_u_short) | 
|---|
| 398 | #else | 
|---|
| 399 | libc_hidden_nolink_sunrpc (xdr_u_short, GLIBC_2_0) | 
|---|
| 400 | #endif | 
|---|
| 401 |  | 
|---|
| 402 |  | 
|---|
| 403 | /* | 
|---|
| 404 | * XDR a char | 
|---|
| 405 | */ | 
|---|
| 406 | bool_t | 
|---|
| 407 | xdr_char (XDR *xdrs, char *cp) | 
|---|
| 408 | { | 
|---|
| 409 | int i; | 
|---|
| 410 |  | 
|---|
| 411 | i = (*cp); | 
|---|
| 412 | if (!xdr_int (xdrs, &i)) | 
|---|
| 413 | { | 
|---|
| 414 | return FALSE; | 
|---|
| 415 | } | 
|---|
| 416 | *cp = i; | 
|---|
| 417 | return TRUE; | 
|---|
| 418 | } | 
|---|
| 419 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 420 | libc_hidden_def (xdr_char) | 
|---|
| 421 | #else | 
|---|
| 422 | libc_hidden_nolink_sunrpc (xdr_char, GLIBC_2_0) | 
|---|
| 423 | #endif | 
|---|
| 424 |  | 
|---|
| 425 | /* | 
|---|
| 426 | * XDR an unsigned char | 
|---|
| 427 | */ | 
|---|
| 428 | bool_t | 
|---|
| 429 | xdr_u_char (XDR *xdrs, u_char *cp) | 
|---|
| 430 | { | 
|---|
| 431 | u_int u; | 
|---|
| 432 |  | 
|---|
| 433 | u = (*cp); | 
|---|
| 434 | if (!xdr_u_int (xdrs, &u)) | 
|---|
| 435 | { | 
|---|
| 436 | return FALSE; | 
|---|
| 437 | } | 
|---|
| 438 | *cp = u; | 
|---|
| 439 | return TRUE; | 
|---|
| 440 | } | 
|---|
| 441 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 442 | libc_hidden_def (xdr_u_char) | 
|---|
| 443 | #else | 
|---|
| 444 | libc_hidden_nolink_sunrpc (xdr_u_char, GLIBC_2_0) | 
|---|
| 445 | #endif | 
|---|
| 446 |  | 
|---|
| 447 | /* | 
|---|
| 448 | * XDR booleans | 
|---|
| 449 | */ | 
|---|
| 450 | bool_t | 
|---|
| 451 | xdr_bool (XDR *xdrs, bool_t *bp) | 
|---|
| 452 | { | 
|---|
| 453 | long lb; | 
|---|
| 454 |  | 
|---|
| 455 | switch (xdrs->x_op) | 
|---|
| 456 | { | 
|---|
| 457 | case XDR_ENCODE: | 
|---|
| 458 | lb = *bp ? XDR_TRUE : XDR_FALSE; | 
|---|
| 459 | return XDR_PUTLONG (xdrs, &lb); | 
|---|
| 460 |  | 
|---|
| 461 | case XDR_DECODE: | 
|---|
| 462 | if (!XDR_GETLONG (xdrs, &lb)) | 
|---|
| 463 | { | 
|---|
| 464 | return FALSE; | 
|---|
| 465 | } | 
|---|
| 466 | *bp = (lb == XDR_FALSE) ? FALSE : TRUE; | 
|---|
| 467 | return TRUE; | 
|---|
| 468 |  | 
|---|
| 469 | case XDR_FREE: | 
|---|
| 470 | return TRUE; | 
|---|
| 471 | } | 
|---|
| 472 | return FALSE; | 
|---|
| 473 | } | 
|---|
| 474 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 475 | libc_hidden_def (xdr_bool) | 
|---|
| 476 | #else | 
|---|
| 477 | libc_hidden_nolink_sunrpc (xdr_bool, GLIBC_2_0) | 
|---|
| 478 | #endif | 
|---|
| 479 |  | 
|---|
| 480 | /* | 
|---|
| 481 | * XDR enumerations | 
|---|
| 482 | */ | 
|---|
| 483 | bool_t | 
|---|
| 484 | xdr_enum (XDR *xdrs, enum_t *ep) | 
|---|
| 485 | { | 
|---|
| 486 | enum sizecheck | 
|---|
| 487 | { | 
|---|
| 488 | SIZEVAL | 
|---|
| 489 | };				/* used to find the size of an enum */ | 
|---|
| 490 |  | 
|---|
| 491 | /* | 
|---|
| 492 | * enums are treated as ints | 
|---|
| 493 | */ | 
|---|
| 494 | if (sizeof (enum sizecheck) == 4) | 
|---|
| 495 | { | 
|---|
| 496 | #if INT_MAX < LONG_MAX | 
|---|
| 497 | long l; | 
|---|
| 498 |  | 
|---|
| 499 | switch (xdrs->x_op) | 
|---|
| 500 | { | 
|---|
| 501 | case XDR_ENCODE: | 
|---|
| 502 | l = *ep; | 
|---|
| 503 | return XDR_PUTLONG (xdrs, &l); | 
|---|
| 504 |  | 
|---|
| 505 | case XDR_DECODE: | 
|---|
| 506 | if (!XDR_GETLONG (xdrs, &l)) | 
|---|
| 507 | { | 
|---|
| 508 | return FALSE; | 
|---|
| 509 | } | 
|---|
| 510 | *ep = l; | 
|---|
| 511 | /* Fall through.  */ | 
|---|
| 512 | case XDR_FREE: | 
|---|
| 513 | return TRUE; | 
|---|
| 514 |  | 
|---|
| 515 | } | 
|---|
| 516 | return FALSE; | 
|---|
| 517 | #else | 
|---|
| 518 | return xdr_long (xdrs, (long *) ep); | 
|---|
| 519 | #endif | 
|---|
| 520 | } | 
|---|
| 521 | else if (sizeof (enum sizecheck) == sizeof (short)) | 
|---|
| 522 | { | 
|---|
| 523 | return xdr_short (xdrs, (short *) ep); | 
|---|
| 524 | } | 
|---|
| 525 | else | 
|---|
| 526 | { | 
|---|
| 527 | return FALSE; | 
|---|
| 528 | } | 
|---|
| 529 | } | 
|---|
| 530 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 531 | libc_hidden_def (xdr_enum) | 
|---|
| 532 | #else | 
|---|
| 533 | libc_hidden_nolink_sunrpc (xdr_enum, GLIBC_2_0) | 
|---|
| 534 | #endif | 
|---|
| 535 |  | 
|---|
| 536 | /* | 
|---|
| 537 | * XDR opaque data | 
|---|
| 538 | * Allows the specification of a fixed size sequence of opaque bytes. | 
|---|
| 539 | * cp points to the opaque object and cnt gives the byte length. | 
|---|
| 540 | */ | 
|---|
| 541 | bool_t | 
|---|
| 542 | xdr_opaque (XDR *xdrs, caddr_t cp, u_int cnt) | 
|---|
| 543 | { | 
|---|
| 544 | u_int rndup; | 
|---|
| 545 | static char crud[BYTES_PER_XDR_UNIT]; | 
|---|
| 546 |  | 
|---|
| 547 | /* | 
|---|
| 548 | * if no data we are done | 
|---|
| 549 | */ | 
|---|
| 550 | if (cnt == 0) | 
|---|
| 551 | return TRUE; | 
|---|
| 552 |  | 
|---|
| 553 | /* | 
|---|
| 554 | * round byte count to full xdr units | 
|---|
| 555 | */ | 
|---|
| 556 | rndup = cnt % BYTES_PER_XDR_UNIT; | 
|---|
| 557 | if (rndup > 0) | 
|---|
| 558 | rndup = BYTES_PER_XDR_UNIT - rndup; | 
|---|
| 559 |  | 
|---|
| 560 | switch (xdrs->x_op) | 
|---|
| 561 | { | 
|---|
| 562 | case XDR_DECODE: | 
|---|
| 563 | if (!XDR_GETBYTES (xdrs, cp, cnt)) | 
|---|
| 564 | { | 
|---|
| 565 | return FALSE; | 
|---|
| 566 | } | 
|---|
| 567 | if (rndup == 0) | 
|---|
| 568 | return TRUE; | 
|---|
| 569 | return XDR_GETBYTES (xdrs, (caddr_t)crud, rndup); | 
|---|
| 570 |  | 
|---|
| 571 | case XDR_ENCODE: | 
|---|
| 572 | if (!XDR_PUTBYTES (xdrs, cp, cnt)) | 
|---|
| 573 | { | 
|---|
| 574 | return FALSE; | 
|---|
| 575 | } | 
|---|
| 576 | if (rndup == 0) | 
|---|
| 577 | return TRUE; | 
|---|
| 578 | return XDR_PUTBYTES (xdrs, xdr_zero, rndup); | 
|---|
| 579 |  | 
|---|
| 580 | case XDR_FREE: | 
|---|
| 581 | return TRUE; | 
|---|
| 582 | } | 
|---|
| 583 | return FALSE; | 
|---|
| 584 | } | 
|---|
| 585 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 586 | libc_hidden_def (xdr_opaque) | 
|---|
| 587 | #else | 
|---|
| 588 | libc_hidden_nolink_sunrpc (xdr_opaque, GLIBC_2_0) | 
|---|
| 589 | #endif | 
|---|
| 590 |  | 
|---|
| 591 | /* | 
|---|
| 592 | * XDR counted bytes | 
|---|
| 593 | * *cpp is a pointer to the bytes, *sizep is the count. | 
|---|
| 594 | * If *cpp is NULL maxsize bytes are allocated | 
|---|
| 595 | */ | 
|---|
| 596 | bool_t | 
|---|
| 597 | xdr_bytes (XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) | 
|---|
| 598 | { | 
|---|
| 599 | char *sp = *cpp;	/* sp is the actual string pointer */ | 
|---|
| 600 | u_int nodesize; | 
|---|
| 601 |  | 
|---|
| 602 | /* | 
|---|
| 603 | * first deal with the length since xdr bytes are counted | 
|---|
| 604 | */ | 
|---|
| 605 | if (!xdr_u_int (xdrs, sizep)) | 
|---|
| 606 | { | 
|---|
| 607 | return FALSE; | 
|---|
| 608 | } | 
|---|
| 609 | nodesize = *sizep; | 
|---|
| 610 | if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) | 
|---|
| 611 | { | 
|---|
| 612 | return FALSE; | 
|---|
| 613 | } | 
|---|
| 614 |  | 
|---|
| 615 | /* | 
|---|
| 616 | * now deal with the actual bytes | 
|---|
| 617 | */ | 
|---|
| 618 | switch (xdrs->x_op) | 
|---|
| 619 | { | 
|---|
| 620 | case XDR_DECODE: | 
|---|
| 621 | if (nodesize == 0) | 
|---|
| 622 | { | 
|---|
| 623 | return TRUE; | 
|---|
| 624 | } | 
|---|
| 625 | if (sp == NULL) | 
|---|
| 626 | { | 
|---|
| 627 | *cpp = sp = (char *) mem_alloc (nodesize); | 
|---|
| 628 | } | 
|---|
| 629 | if (sp == NULL) | 
|---|
| 630 | { | 
|---|
| 631 | (void) __fxprintf (NULL, "%s: %s", __func__, _( "out of memory\n")); | 
|---|
| 632 | return FALSE; | 
|---|
| 633 | } | 
|---|
| 634 | /* Fall through.  */ | 
|---|
| 635 |  | 
|---|
| 636 | case XDR_ENCODE: | 
|---|
| 637 | return xdr_opaque (xdrs, sp, nodesize); | 
|---|
| 638 |  | 
|---|
| 639 | case XDR_FREE: | 
|---|
| 640 | if (sp != NULL) | 
|---|
| 641 | { | 
|---|
| 642 | mem_free (sp, nodesize); | 
|---|
| 643 | *cpp = NULL; | 
|---|
| 644 | } | 
|---|
| 645 | return TRUE; | 
|---|
| 646 | } | 
|---|
| 647 | return FALSE; | 
|---|
| 648 | } | 
|---|
| 649 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 650 | libc_hidden_def (xdr_bytes) | 
|---|
| 651 | #else | 
|---|
| 652 | libc_hidden_nolink_sunrpc (xdr_bytes, GLIBC_2_0) | 
|---|
| 653 | #endif | 
|---|
| 654 |  | 
|---|
| 655 | /* | 
|---|
| 656 | * Implemented here due to commonality of the object. | 
|---|
| 657 | */ | 
|---|
| 658 | bool_t | 
|---|
| 659 | xdr_netobj (XDR *xdrs, struct netobj *np) | 
|---|
| 660 | { | 
|---|
| 661 |  | 
|---|
| 662 | return xdr_bytes (xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ); | 
|---|
| 663 | } | 
|---|
| 664 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 665 | libc_hidden_def (xdr_netobj) | 
|---|
| 666 | #else | 
|---|
| 667 | libc_hidden_nolink_sunrpc (xdr_netobj, GLIBC_2_0) | 
|---|
| 668 | #endif | 
|---|
| 669 |  | 
|---|
| 670 | /* | 
|---|
| 671 | * XDR a discriminated union | 
|---|
| 672 | * Support routine for discriminated unions. | 
|---|
| 673 | * You create an array of xdrdiscrim structures, terminated with | 
|---|
| 674 | * an entry with a null procedure pointer.  The routine gets | 
|---|
| 675 | * the discriminant value and then searches the array of xdrdiscrims | 
|---|
| 676 | * looking for that value.  It calls the procedure given in the xdrdiscrim | 
|---|
| 677 | * to handle the discriminant.  If there is no specific routine a default | 
|---|
| 678 | * routine may be called. | 
|---|
| 679 | * If there is no specific or default routine an error is returned. | 
|---|
| 680 | */ | 
|---|
| 681 | bool_t | 
|---|
| 682 | xdr_union (XDR *xdrs, | 
|---|
| 683 | /* enum to decide which arm to work on */ | 
|---|
| 684 | enum_t *dscmp, | 
|---|
| 685 | /* the union itself */ | 
|---|
| 686 | char *unp, | 
|---|
| 687 | /* [value, xdr proc] for each arm */ | 
|---|
| 688 | const struct xdr_discrim *choices, | 
|---|
| 689 | /* default xdr routine */ | 
|---|
| 690 | xdrproc_t dfault) | 
|---|
| 691 | { | 
|---|
| 692 | enum_t dscm; | 
|---|
| 693 |  | 
|---|
| 694 | /* | 
|---|
| 695 | * we deal with the discriminator;  it's an enum | 
|---|
| 696 | */ | 
|---|
| 697 | if (!xdr_enum (xdrs, dscmp)) | 
|---|
| 698 | { | 
|---|
| 699 | return FALSE; | 
|---|
| 700 | } | 
|---|
| 701 | dscm = *dscmp; | 
|---|
| 702 |  | 
|---|
| 703 | /* | 
|---|
| 704 | * search choices for a value that matches the discriminator. | 
|---|
| 705 | * if we find one, execute the xdr routine for that value. | 
|---|
| 706 | */ | 
|---|
| 707 | for (; choices->proc != NULL_xdrproc_t; choices++) | 
|---|
| 708 | { | 
|---|
| 709 | if (choices->value == dscm) | 
|---|
| 710 | return (*(choices->proc)) (xdrs, unp, LASTUNSIGNED); | 
|---|
| 711 | } | 
|---|
| 712 |  | 
|---|
| 713 | /* | 
|---|
| 714 | * no match - execute the default xdr routine if there is one | 
|---|
| 715 | */ | 
|---|
| 716 | return ((dfault == NULL_xdrproc_t) ? FALSE : | 
|---|
| 717 | (*dfault) (xdrs, unp, LASTUNSIGNED)); | 
|---|
| 718 | } | 
|---|
| 719 | libc_hidden_nolink_sunrpc (xdr_union, GLIBC_2_0) | 
|---|
| 720 |  | 
|---|
| 721 |  | 
|---|
| 722 | /* | 
|---|
| 723 | * Non-portable xdr primitives. | 
|---|
| 724 | * Care should be taken when moving these routines to new architectures. | 
|---|
| 725 | */ | 
|---|
| 726 |  | 
|---|
| 727 |  | 
|---|
| 728 | /* | 
|---|
| 729 | * XDR null terminated ASCII strings | 
|---|
| 730 | * xdr_string deals with "C strings" - arrays of bytes that are | 
|---|
| 731 | * terminated by a NULL character.  The parameter cpp references a | 
|---|
| 732 | * pointer to storage; If the pointer is null, then the necessary | 
|---|
| 733 | * storage is allocated.  The last parameter is the max allowed length | 
|---|
| 734 | * of the string as specified by a protocol. | 
|---|
| 735 | */ | 
|---|
| 736 | bool_t | 
|---|
| 737 | xdr_string (XDR *xdrs, char **cpp, u_int maxsize) | 
|---|
| 738 | { | 
|---|
| 739 | char *sp = *cpp;	/* sp is the actual string pointer */ | 
|---|
| 740 | /* Initialize to silence the compiler.  It is not really needed because SIZE | 
|---|
| 741 | never actually gets used without being initialized.  */ | 
|---|
| 742 | u_int size = 0; | 
|---|
| 743 | u_int nodesize; | 
|---|
| 744 |  | 
|---|
| 745 | /* | 
|---|
| 746 | * first deal with the length since xdr strings are counted-strings | 
|---|
| 747 | */ | 
|---|
| 748 | switch (xdrs->x_op) | 
|---|
| 749 | { | 
|---|
| 750 | case XDR_FREE: | 
|---|
| 751 | if (sp == NULL) | 
|---|
| 752 | { | 
|---|
| 753 | return TRUE;		/* already free */ | 
|---|
| 754 | } | 
|---|
| 755 | /* fall through... */ | 
|---|
| 756 | case XDR_ENCODE: | 
|---|
| 757 | if (sp == NULL) | 
|---|
| 758 | return FALSE; | 
|---|
| 759 | size = strlen (sp); | 
|---|
| 760 | break; | 
|---|
| 761 | case XDR_DECODE: | 
|---|
| 762 | break; | 
|---|
| 763 | } | 
|---|
| 764 | if (!xdr_u_int (xdrs, &size)) | 
|---|
| 765 | { | 
|---|
| 766 | return FALSE; | 
|---|
| 767 | } | 
|---|
| 768 | if (size > maxsize) | 
|---|
| 769 | { | 
|---|
| 770 | return FALSE; | 
|---|
| 771 | } | 
|---|
| 772 | nodesize = size + 1; | 
|---|
| 773 | if (nodesize == 0) | 
|---|
| 774 | { | 
|---|
| 775 | /* This means an overflow.  It a bug in the caller which | 
|---|
| 776 | provided a too large maxsize but nevertheless catch it | 
|---|
| 777 | here.  */ | 
|---|
| 778 | return FALSE; | 
|---|
| 779 | } | 
|---|
| 780 |  | 
|---|
| 781 | /* | 
|---|
| 782 | * now deal with the actual bytes | 
|---|
| 783 | */ | 
|---|
| 784 | switch (xdrs->x_op) | 
|---|
| 785 | { | 
|---|
| 786 | case XDR_DECODE: | 
|---|
| 787 | if (sp == NULL) | 
|---|
| 788 | *cpp = sp = (char *) mem_alloc (nodesize); | 
|---|
| 789 | if (sp == NULL) | 
|---|
| 790 | { | 
|---|
| 791 | (void) __fxprintf (NULL, "%s: %s", __func__, _( "out of memory\n")); | 
|---|
| 792 | return FALSE; | 
|---|
| 793 | } | 
|---|
| 794 | sp[size] = 0; | 
|---|
| 795 | /* Fall through.  */ | 
|---|
| 796 |  | 
|---|
| 797 | case XDR_ENCODE: | 
|---|
| 798 | return xdr_opaque (xdrs, sp, size); | 
|---|
| 799 |  | 
|---|
| 800 | case XDR_FREE: | 
|---|
| 801 | mem_free (sp, nodesize); | 
|---|
| 802 | *cpp = NULL; | 
|---|
| 803 | return TRUE; | 
|---|
| 804 | } | 
|---|
| 805 | return FALSE; | 
|---|
| 806 | } | 
|---|
| 807 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 808 | libc_hidden_def (xdr_string) | 
|---|
| 809 | #else | 
|---|
| 810 | libc_hidden_nolink_sunrpc (xdr_string, GLIBC_2_0) | 
|---|
| 811 | #endif | 
|---|
| 812 |  | 
|---|
| 813 | /* | 
|---|
| 814 | * Wrapper for xdr_string that can be called directly from | 
|---|
| 815 | * routines like clnt_call | 
|---|
| 816 | */ | 
|---|
| 817 | bool_t | 
|---|
| 818 | xdr_wrapstring (XDR *xdrs, char **cpp) | 
|---|
| 819 | { | 
|---|
| 820 | if (xdr_string (xdrs, cpp, LASTUNSIGNED)) | 
|---|
| 821 | { | 
|---|
| 822 | return TRUE; | 
|---|
| 823 | } | 
|---|
| 824 | return FALSE; | 
|---|
| 825 | } | 
|---|
| 826 | #ifdef EXPORT_RPC_SYMBOLS | 
|---|
| 827 | libc_hidden_def (xdr_wrapstring) | 
|---|
| 828 | #else | 
|---|
| 829 | libc_hidden_nolink_sunrpc (xdr_wrapstring, GLIBC_2_0) | 
|---|
| 830 | #endif | 
|---|
| 831 |  | 
|---|