xdr.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. /* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */
  2. /*
  3. * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4. * unrestricted use provided that this legend is included on all tape
  5. * media and as a part of the software program in whole or part. Users
  6. * may copy or modify Sun RPC without charge, but are not authorized
  7. * to license or distribute it to anyone else except as part of a product or
  8. * program developed by the user.
  9. *
  10. * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11. * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12. * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13. *
  14. * Sun RPC is provided with no support and without any obligation on the
  15. * part of Sun Microsystems, Inc. to assist in its use, correction,
  16. * modification or enhancement.
  17. *
  18. * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19. * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20. * OR ANY PART THEREOF.
  21. *
  22. * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23. * or profits or other special, indirect and consequential damages, even if
  24. * Sun has been advised of the possibility of such damages.
  25. *
  26. * Sun Microsystems, Inc.
  27. * 2550 Garcia Avenue
  28. * Mountain View, California 94043
  29. */
  30. #if 0
  31. static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
  32. #endif
  33. /*
  34. * xdr.c, Generic XDR routines implementation.
  35. *
  36. * Copyright (C) 1986, Sun Microsystems, Inc.
  37. *
  38. * These are the "generic" xdr routines used to serialize and de-serialize
  39. * most common data items. See xdr.h for more info on the interface to
  40. * xdr.
  41. */
  42. #include <stdio.h>
  43. #include <limits.h>
  44. #include <string.h>
  45. #include <rpc/types.h>
  46. #include <rpc/xdr.h>
  47. #ifdef USE_IN_LIBIO
  48. # include <wchar.h>
  49. #endif
  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. * for unit alignment
  58. */
  59. static const char xdr_zero[BYTES_PER_XDR_UNIT] = {0, 0, 0, 0};
  60. /*
  61. * Free a data structure using XDR
  62. * Not a filter, but a convenient utility nonetheless
  63. */
  64. void
  65. xdr_free (xdrproc_t proc, char *objp)
  66. {
  67. XDR x;
  68. x.x_op = XDR_FREE;
  69. (*proc) (&x, objp);
  70. }
  71. /*
  72. * XDR nothing
  73. */
  74. bool_t
  75. xdr_void (void)
  76. {
  77. return TRUE;
  78. }
  79. libc_hidden_def(xdr_void)
  80. /*
  81. * XDR long integers
  82. * The definition of xdr_long() is kept for backward
  83. * compatibility. Instead xdr_int() should be used.
  84. */
  85. bool_t
  86. xdr_long (XDR *xdrs, long *lp)
  87. {
  88. if (xdrs->x_op == XDR_ENCODE
  89. && (sizeof (int32_t) == sizeof (long)
  90. || (int32_t) *lp == *lp))
  91. return XDR_PUTLONG (xdrs, lp);
  92. if (xdrs->x_op == XDR_DECODE)
  93. return XDR_GETLONG (xdrs, lp);
  94. if (xdrs->x_op == XDR_FREE)
  95. return TRUE;
  96. return FALSE;
  97. }
  98. libc_hidden_def(xdr_long)
  99. /*
  100. * XDR short integers
  101. */
  102. bool_t
  103. xdr_short (XDR *xdrs, short *sp)
  104. {
  105. long l;
  106. switch (xdrs->x_op)
  107. {
  108. case XDR_ENCODE:
  109. l = (long) *sp;
  110. return XDR_PUTLONG (xdrs, &l);
  111. case XDR_DECODE:
  112. if (!XDR_GETLONG (xdrs, &l))
  113. {
  114. return FALSE;
  115. }
  116. *sp = (short) l;
  117. return TRUE;
  118. case XDR_FREE:
  119. return TRUE;
  120. }
  121. return FALSE;
  122. }
  123. libc_hidden_def(xdr_short)
  124. /*
  125. * XDR integers
  126. */
  127. bool_t
  128. xdr_int (XDR *xdrs, int *ip)
  129. {
  130. #if INT_MAX < LONG_MAX
  131. long l;
  132. switch (xdrs->x_op)
  133. {
  134. case XDR_ENCODE:
  135. l = (long) *ip;
  136. return XDR_PUTLONG (xdrs, &l);
  137. case XDR_DECODE:
  138. if (!XDR_GETLONG (xdrs, &l))
  139. {
  140. return FALSE;
  141. }
  142. *ip = (int) l;
  143. case XDR_FREE:
  144. return TRUE;
  145. }
  146. return FALSE;
  147. #elif INT_MAX == LONG_MAX
  148. return xdr_long (xdrs, (long *) ip);
  149. #elif INT_MAX == SHRT_MAX
  150. return xdr_short (xdrs, (short *) ip);
  151. #else
  152. #error unexpected integer sizes in xdr_int()
  153. #endif
  154. }
  155. libc_hidden_def(xdr_int)
  156. /*
  157. * XDR unsigned long integers
  158. * The definition of xdr_u_long() is kept for backward
  159. * compatibility. Instead xdr_u_int() should be used.
  160. */
  161. bool_t
  162. xdr_u_long (XDR *xdrs, u_long *ulp)
  163. {
  164. switch (xdrs->x_op)
  165. {
  166. case XDR_DECODE:
  167. {
  168. long int tmp;
  169. if (XDR_GETLONG (xdrs, &tmp) == FALSE)
  170. return FALSE;
  171. *ulp = (uint32_t) tmp;
  172. return TRUE;
  173. }
  174. case XDR_ENCODE:
  175. if (sizeof (uint32_t) != sizeof (u_long)
  176. && (uint32_t) *ulp != *ulp)
  177. return FALSE;
  178. return XDR_PUTLONG (xdrs, (long *) ulp);
  179. case XDR_FREE:
  180. return TRUE;
  181. }
  182. return FALSE;
  183. }
  184. libc_hidden_def(xdr_u_long)
  185. /*
  186. * XDR unsigned integers
  187. */
  188. bool_t
  189. xdr_u_int (XDR *xdrs, u_int *up)
  190. {
  191. #if UINT_MAX < ULONG_MAX
  192. u_long l;
  193. switch (xdrs->x_op)
  194. {
  195. case XDR_ENCODE:
  196. l = (u_long) * up;
  197. return XDR_PUTLONG (xdrs, (long *) &l);
  198. case XDR_DECODE:
  199. if (!XDR_GETLONG (xdrs, (long *) &l))
  200. {
  201. return FALSE;
  202. }
  203. *up = (u_int) l;
  204. case XDR_FREE:
  205. return TRUE;
  206. }
  207. return FALSE;
  208. #elif UINT_MAX == ULONG_MAX
  209. return xdr_u_long (xdrs, (u_long *) up);
  210. #elif UINT_MAX == USHRT_MAX
  211. return xdr_short (xdrs, (short *) up);
  212. #else
  213. #error unexpected integer sizes in xdr_u_int()
  214. #endif
  215. }
  216. libc_hidden_def(xdr_u_int)
  217. /*
  218. * XDR hyper integers
  219. * same as xdr_u_hyper - open coded to save a proc call!
  220. */
  221. bool_t
  222. xdr_hyper (XDR *xdrs, quad_t *llp)
  223. {
  224. long t1;
  225. unsigned long t2;
  226. if (xdrs->x_op == XDR_ENCODE)
  227. {
  228. t1 = (long) ((*llp) >> 32);
  229. t2 = (long) (*llp);
  230. return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, (long *) &t2));
  231. }
  232. if (xdrs->x_op == XDR_DECODE)
  233. {
  234. if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, (long *) &t2))
  235. return FALSE;
  236. /* t2 must be unsigned for this to work */
  237. *llp = ((quad_t) t1) << 32;
  238. *llp |= t2;
  239. return TRUE;
  240. }
  241. if (xdrs->x_op == XDR_FREE)
  242. return TRUE;
  243. return FALSE;
  244. }
  245. libc_hidden_def(xdr_hyper)
  246. /*
  247. * XDR hyper integers
  248. * same as xdr_hyper - open coded to save a proc call!
  249. */
  250. bool_t
  251. xdr_u_hyper (XDR *xdrs, u_quad_t *ullp)
  252. {
  253. unsigned long t1;
  254. unsigned long t2;
  255. if (xdrs->x_op == XDR_ENCODE)
  256. {
  257. t1 = (unsigned long) ((*ullp) >> 32);
  258. t2 = (unsigned long) (*ullp);
  259. return (XDR_PUTLONG(xdrs, (long *) &t1) && XDR_PUTLONG(xdrs, (long *) &t2));
  260. }
  261. if (xdrs->x_op == XDR_DECODE)
  262. {
  263. if (!XDR_GETLONG(xdrs, (long *) &t1) || !XDR_GETLONG(xdrs, (long *) &t2))
  264. return FALSE;
  265. *ullp = ((u_quad_t) t1) << 32;
  266. *ullp |= t2;
  267. return TRUE;
  268. }
  269. if (xdrs->x_op == XDR_FREE)
  270. return TRUE;
  271. return FALSE;
  272. }
  273. libc_hidden_def(xdr_u_hyper)
  274. bool_t
  275. xdr_longlong_t (XDR *xdrs, quad_t *llp)
  276. {
  277. return xdr_hyper (xdrs, llp);
  278. }
  279. bool_t
  280. xdr_u_longlong_t (XDR *xdrs, u_quad_t *ullp)
  281. {
  282. return xdr_u_hyper (xdrs, ullp);
  283. }
  284. /*
  285. * XDR unsigned short integers
  286. */
  287. bool_t
  288. xdr_u_short (XDR *xdrs, u_short *usp)
  289. {
  290. u_long l;
  291. switch (xdrs->x_op)
  292. {
  293. case XDR_ENCODE:
  294. l = (u_long) * usp;
  295. return XDR_PUTLONG (xdrs, (long *) &l);
  296. case XDR_DECODE:
  297. if (!XDR_GETLONG (xdrs, (long *) &l))
  298. {
  299. return FALSE;
  300. }
  301. *usp = (u_short) l;
  302. return TRUE;
  303. case XDR_FREE:
  304. return TRUE;
  305. }
  306. return FALSE;
  307. }
  308. libc_hidden_def(xdr_u_short)
  309. /*
  310. * XDR a char
  311. */
  312. bool_t
  313. xdr_char (XDR *xdrs, char *cp)
  314. {
  315. int i;
  316. i = (*cp);
  317. if (!xdr_int (xdrs, &i))
  318. {
  319. return FALSE;
  320. }
  321. *cp = i;
  322. return TRUE;
  323. }
  324. /*
  325. * XDR an unsigned char
  326. */
  327. bool_t
  328. xdr_u_char (XDR *xdrs, u_char *cp)
  329. {
  330. u_int u;
  331. u = (*cp);
  332. if (!xdr_u_int (xdrs, &u))
  333. {
  334. return FALSE;
  335. }
  336. *cp = u;
  337. return TRUE;
  338. }
  339. /*
  340. * XDR booleans
  341. */
  342. bool_t
  343. xdr_bool (XDR *xdrs, bool_t *bp)
  344. {
  345. long lb;
  346. switch (xdrs->x_op)
  347. {
  348. case XDR_ENCODE:
  349. lb = *bp ? XDR_TRUE : XDR_FALSE;
  350. return XDR_PUTLONG (xdrs, &lb);
  351. case XDR_DECODE:
  352. if (!XDR_GETLONG (xdrs, &lb))
  353. {
  354. return FALSE;
  355. }
  356. *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
  357. return TRUE;
  358. case XDR_FREE:
  359. return TRUE;
  360. }
  361. return FALSE;
  362. }
  363. libc_hidden_def(xdr_bool)
  364. /*
  365. * XDR enumerations
  366. */
  367. bool_t
  368. xdr_enum (XDR *xdrs, enum_t *ep)
  369. {
  370. enum sizecheck
  371. {
  372. SIZEVAL
  373. }; /* used to find the size of an enum */
  374. /*
  375. * enums are treated as ints
  376. */
  377. if (sizeof (enum sizecheck) == 4)
  378. {
  379. #if INT_MAX < LONG_MAX
  380. long l;
  381. switch (xdrs->x_op)
  382. {
  383. case XDR_ENCODE:
  384. l = *ep;
  385. return XDR_PUTLONG (xdrs, &l);
  386. case XDR_DECODE:
  387. if (!XDR_GETLONG (xdrs, &l))
  388. {
  389. return FALSE;
  390. }
  391. *ep = l;
  392. case XDR_FREE:
  393. return TRUE;
  394. }
  395. return FALSE;
  396. #else
  397. return xdr_long (xdrs, (long *) ep);
  398. #endif
  399. }
  400. else if (sizeof (enum sizecheck) == sizeof (short))
  401. {
  402. return xdr_short (xdrs, (short *) ep);
  403. }
  404. else
  405. {
  406. return FALSE;
  407. }
  408. }
  409. libc_hidden_def(xdr_enum)
  410. /*
  411. * XDR opaque data
  412. * Allows the specification of a fixed size sequence of opaque bytes.
  413. * cp points to the opaque object and cnt gives the byte length.
  414. */
  415. bool_t
  416. xdr_opaque (XDR *xdrs, caddr_t cp, u_int cnt)
  417. {
  418. u_int rndup;
  419. static char crud[BYTES_PER_XDR_UNIT];
  420. /*
  421. * if no data we are done
  422. */
  423. if (cnt == 0)
  424. return TRUE;
  425. /*
  426. * round byte count to full xdr units
  427. */
  428. rndup = cnt % BYTES_PER_XDR_UNIT;
  429. if (rndup > 0)
  430. rndup = BYTES_PER_XDR_UNIT - rndup;
  431. switch (xdrs->x_op)
  432. {
  433. case XDR_DECODE:
  434. if (!XDR_GETBYTES (xdrs, cp, cnt))
  435. {
  436. return FALSE;
  437. }
  438. if (rndup == 0)
  439. return TRUE;
  440. return XDR_GETBYTES (xdrs, (caddr_t)crud, rndup);
  441. case XDR_ENCODE:
  442. if (!XDR_PUTBYTES (xdrs, cp, cnt))
  443. {
  444. return FALSE;
  445. }
  446. if (rndup == 0)
  447. return TRUE;
  448. return XDR_PUTBYTES (xdrs, xdr_zero, rndup);
  449. case XDR_FREE:
  450. return TRUE;
  451. }
  452. return FALSE;
  453. }
  454. libc_hidden_def(xdr_opaque)
  455. /*
  456. * XDR counted bytes
  457. * *cpp is a pointer to the bytes, *sizep is the count.
  458. * If *cpp is NULL maxsize bytes are allocated
  459. */
  460. bool_t
  461. xdr_bytes (XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
  462. {
  463. char *sp = *cpp; /* sp is the actual string pointer */
  464. u_int nodesize;
  465. /*
  466. * first deal with the length since xdr bytes are counted
  467. */
  468. if (!xdr_u_int (xdrs, sizep))
  469. {
  470. return FALSE;
  471. }
  472. nodesize = *sizep;
  473. if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE))
  474. {
  475. return FALSE;
  476. }
  477. /*
  478. * now deal with the actual bytes
  479. */
  480. switch (xdrs->x_op)
  481. {
  482. case XDR_DECODE:
  483. if (nodesize == 0)
  484. {
  485. return TRUE;
  486. }
  487. if (sp == NULL)
  488. {
  489. *cpp = sp = (char *) mem_alloc (nodesize);
  490. }
  491. if (sp == NULL)
  492. {
  493. #ifdef USE_IN_LIBIO
  494. if (_IO_fwide (stderr, 0) > 0)
  495. (void) fwprintf (stderr, L"%s", _("xdr_bytes: out of memory\n"));
  496. else
  497. #endif
  498. (void) fputs (_("xdr_bytes: out of memory\n"), stderr);
  499. return FALSE;
  500. }
  501. /* fall into ... */
  502. case XDR_ENCODE:
  503. return xdr_opaque (xdrs, sp, nodesize);
  504. case XDR_FREE:
  505. if (sp != NULL)
  506. {
  507. mem_free (sp, nodesize);
  508. *cpp = NULL;
  509. }
  510. return TRUE;
  511. }
  512. return FALSE;
  513. }
  514. libc_hidden_def(xdr_bytes)
  515. /*
  516. * Implemented here due to commonality of the object.
  517. */
  518. bool_t
  519. xdr_netobj (XDR *xdrs, struct netobj *np)
  520. {
  521. return xdr_bytes (xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ);
  522. }
  523. /*
  524. * XDR a discriminated union
  525. * Support routine for discriminated unions.
  526. * You create an array of xdrdiscrim structures, terminated with
  527. * an entry with a null procedure pointer. The routine gets
  528. * the discriminant value and then searches the array of xdrdiscrims
  529. * looking for that value. It calls the procedure given in the xdrdiscrim
  530. * to handle the discriminant. If there is no specific routine a default
  531. * routine may be called.
  532. * If there is no specific or default routine an error is returned.
  533. */
  534. bool_t
  535. xdr_union (XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choices, xdrproc_t dfault)
  536. {
  537. enum_t dscm;
  538. /*
  539. * we deal with the discriminator; it's an enum
  540. */
  541. if (!xdr_enum (xdrs, dscmp))
  542. {
  543. return FALSE;
  544. }
  545. dscm = *dscmp;
  546. /*
  547. * search choices for a value that matches the discriminator.
  548. * if we find one, execute the xdr routine for that value.
  549. */
  550. for (; choices->proc != NULL_xdrproc_t; choices++)
  551. {
  552. if (choices->value == dscm)
  553. return (*(choices->proc)) (xdrs, unp, LASTUNSIGNED);
  554. }
  555. /*
  556. * no match - execute the default xdr routine if there is one
  557. */
  558. return ((dfault == NULL_xdrproc_t) ? FALSE :
  559. (*dfault) (xdrs, unp, LASTUNSIGNED));
  560. }
  561. libc_hidden_def(xdr_union)
  562. /*
  563. * Non-portable xdr primitives.
  564. * Care should be taken when moving these routines to new architectures.
  565. */
  566. /*
  567. * XDR null terminated ASCII strings
  568. * xdr_string deals with "C strings" - arrays of bytes that are
  569. * terminated by a NULL character. The parameter cpp references a
  570. * pointer to storage; If the pointer is null, then the necessary
  571. * storage is allocated. The last parameter is the max allowed length
  572. * of the string as specified by a protocol.
  573. */
  574. bool_t
  575. xdr_string (XDR *xdrs, char **cpp, u_int maxsize)
  576. {
  577. char *sp = *cpp; /* sp is the actual string pointer */
  578. u_int size;
  579. u_int nodesize;
  580. /*
  581. * first deal with the length since xdr strings are counted-strings
  582. */
  583. switch (xdrs->x_op)
  584. {
  585. case XDR_FREE:
  586. if (sp == NULL)
  587. {
  588. return TRUE; /* already free */
  589. }
  590. /* fall through... */
  591. case XDR_ENCODE:
  592. if (sp == NULL)
  593. return FALSE;
  594. size = strlen (sp);
  595. break;
  596. case XDR_DECODE:
  597. break;
  598. }
  599. if (!xdr_u_int (xdrs, &size))
  600. {
  601. return FALSE;
  602. }
  603. if (size > maxsize)
  604. {
  605. return FALSE;
  606. }
  607. nodesize = size + 1;
  608. /*
  609. * now deal with the actual bytes
  610. */
  611. switch (xdrs->x_op)
  612. {
  613. case XDR_DECODE:
  614. if (nodesize == 0)
  615. {
  616. return TRUE;
  617. }
  618. if (sp == NULL)
  619. *cpp = sp = (char *) mem_alloc (nodesize);
  620. if (sp == NULL)
  621. {
  622. #ifdef USE_IN_LIBIO
  623. if (_IO_fwide (stderr, 0) > 0)
  624. (void) fwprintf (stderr, L"%s",
  625. _("xdr_string: out of memory\n"));
  626. else
  627. #endif
  628. (void) fputs (_("xdr_string: out of memory\n"), stderr);
  629. return FALSE;
  630. }
  631. sp[size] = 0;
  632. /* fall into ... */
  633. case XDR_ENCODE:
  634. return xdr_opaque (xdrs, sp, size);
  635. case XDR_FREE:
  636. mem_free (sp, nodesize);
  637. *cpp = NULL;
  638. return TRUE;
  639. }
  640. return FALSE;
  641. }
  642. libc_hidden_def(xdr_string)
  643. /*
  644. * Wrapper for xdr_string that can be called directly from
  645. * routines like clnt_call
  646. */
  647. bool_t
  648. xdr_wrapstring (XDR *xdrs, char **cpp)
  649. {
  650. if (xdr_string (xdrs, cpp, LASTUNSIGNED))
  651. {
  652. return TRUE;
  653. }
  654. return FALSE;
  655. }