xdr.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:13k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* xdr.c - generic XDR routines implementation */
  2. /* Copyright 1984-2000 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (C) 1984, Sun Microsystems, Inc.
  6.  *
  7.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  8.  * unrestricted use provided that this legend is included on all tape
  9.  * media and as a part of the software program in whole or part.  Users
  10.  * may copy or modify Sun RPC without charge, but are not authorized
  11.  * to license or distribute it to anyone else except as part of a product or
  12.  * program developed by the user.
  13.  *
  14.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  15.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  16.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  17.  *
  18.  * Sun RPC is provided with no support and without any obligation on the
  19.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  20.  * modification or enhancement.
  21.  *
  22.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  23.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  24.  * OR ANY PART THEREOF.
  25.  *
  26.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  27.  * or profits or other special, indirect and consequential damages, even if
  28.  * Sun has been advised of the possibility of such damages.
  29.  *
  30.  * Sun Microsystems, Inc.
  31.  * 2550 Garcia Avenue
  32.  * Mountain View, California  94043
  33.  */
  34. /*
  35. modification history
  36. --------------------
  37. 01k,18apr00,ham  fixed compilation warnings.
  38. 01j,29jan96,mem  replaced test of CPU_FAMILY with test of _BYTE_ORDER
  39. 01i,09jun93,hdn  added support for I80X86
  40. 01i,17oct94,ism  fixed xdr_u_char() to match header fix (SPR#2675)
  41. 01h,26may92,rrr  the tree shuffle
  42. 01g,04oct91,rrr  passed through the ansification filter
  43.   -changed includes to have absolute path from h/
  44.   -fixed #else and #endif
  45.   -changed copyright notice
  46. 01f,05aug91,del   moved include "vxWorks.h", added ixdr_get_long function
  47.   for I960 version only.
  48. 01e,10may90,dnw   changed xdr_bytes to not mem_alloc/mem_free if count=0 bytes
  49. 01d,27oct89,hjb   upgraded to 4.0
  50. 01c,05apr88,gae   changed fprintf() to printErr().
  51. 01b,11nov87,jlf   added wrs copyright, title, mod history, etc.
  52. 01a,01nov87,rdc   first VxWorks version
  53. */
  54. #ifndef lint
  55. /* static char sccsid[] = "@(#)xdr.c 1.1 86/02/03 Copyr 1984 Sun Micro"; */
  56. #endif
  57. /*
  58.  * xdr.c, Generic XDR routines implementation.
  59.  *
  60.  * These are the "generic" xdr routines used to serialize and de-serialize
  61.  * most common data items.  See xdr.h for more info on the interface to
  62.  * xdr.
  63.  */
  64. #include "rpc/rpctypes.h"
  65. #include "vxWorks.h"
  66. #include "rpc/xdr.h"
  67. #include "memLib.h"
  68. #include "netinet/in.h"
  69. #include "private/funcBindP.h"
  70. #include "stdlib.h"
  71. #include "string.h"
  72. #define PRINTERR if (_func_printErr != NULL) _func_printErr
  73. /*
  74.  * constants specific to the xdr "protocol"
  75.  */
  76. #define XDR_FALSE ((long) 0)
  77. #define XDR_TRUE ((long) 1)
  78. #define LASTUNSIGNED ((u_int) 0-1)
  79. #define BUFSIZ 1024
  80. /*
  81.  * for unit alignment
  82.  */
  83. static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
  84. /**************************************************************************
  85. *
  86. * xdr_free - free a data structure using XDR
  87. *
  88. * Not a filter, but a convenient utility nonetheless
  89. */
  90. void xdr_free (proc, objp) /* 4.0 */
  91.     xdrproc_t proc; /* 4.0 */
  92.     char *objp; /* 4.0 */
  93.     { /* 4.0 */
  94.     XDR x; /* 4.0 */
  95.     x.x_op = XDR_FREE; /* 4.0 */
  96.     (*proc) (&x, objp); /* 4.0 */
  97.     } /* 4.0 */
  98. /*
  99.  * XDR nothing
  100.  */
  101. bool_t
  102. xdr_void(/* xdrs, addr */)
  103. /* XDR *xdrs; */
  104. /* caddr_t addr; */
  105. {
  106. return (TRUE);
  107. }
  108. /*
  109.  * XDR integers
  110.  */
  111. bool_t
  112. xdr_int(xdrs, ip)
  113. XDR *xdrs;
  114. int *ip;
  115. {
  116. #ifdef lint
  117. (void) (xdr_short(xdrs, (short *)ip));
  118. return (xdr_long(xdrs, (long *)ip));
  119. #else
  120. if (sizeof (int) == sizeof (long)) {
  121. return (xdr_long(xdrs, (long *)ip));
  122. } else {
  123. return (xdr_short(xdrs, (short *)ip));
  124. }
  125. #endif
  126. }
  127. /*
  128.  * XDR unsigned integers
  129.  */
  130. bool_t
  131. xdr_u_int(xdrs, up)
  132. XDR *xdrs;
  133. u_int *up;
  134. {
  135. #ifdef lint
  136. (void) (xdr_short(xdrs, (short *)up));
  137. return (xdr_u_long(xdrs, (u_long *)up));
  138. #else
  139. if (sizeof (u_int) == sizeof (u_long)) {
  140. return (xdr_u_long(xdrs, (u_long *)up));
  141. } else {
  142. return (xdr_short(xdrs, (short *)up));
  143. }
  144. #endif
  145. }
  146. /*
  147.  * XDR long integers
  148.  * same as xdr_u_long - open coded to save a proc call!
  149.  */
  150. bool_t
  151. xdr_long(xdrs, lp)
  152. register XDR *xdrs;
  153. long *lp;
  154. {
  155. if (xdrs->x_op == XDR_ENCODE)
  156. return (XDR_PUTLONG(xdrs, lp));
  157. if (xdrs->x_op == XDR_DECODE)
  158. return (XDR_GETLONG(xdrs, lp));
  159. if (xdrs->x_op == XDR_FREE)
  160. return (TRUE);
  161. return (FALSE);
  162. }
  163. /*
  164.  * XDR unsigned long integers
  165.  * same as xdr_long - open coded to save a proc call!
  166.  */
  167. bool_t
  168. xdr_u_long(xdrs, ulp)
  169. register XDR *xdrs;
  170. u_long *ulp;
  171. {
  172. if (xdrs->x_op == XDR_DECODE)
  173. return (XDR_GETLONG(xdrs, (long *)ulp));
  174. if (xdrs->x_op == XDR_ENCODE)
  175. return (XDR_PUTLONG(xdrs, (long *)ulp));
  176. if (xdrs->x_op == XDR_FREE)
  177. return (TRUE);
  178. return (FALSE);
  179. }
  180. /*
  181.  * XDR short integers
  182.  */
  183. bool_t
  184. xdr_short(xdrs, sp)
  185. register XDR *xdrs;
  186. short *sp;
  187. {
  188. long l;
  189. switch (xdrs->x_op) {
  190. case XDR_ENCODE:
  191. l = (long) *sp;
  192. return (XDR_PUTLONG(xdrs, &l));
  193. case XDR_DECODE:
  194. if (!XDR_GETLONG(xdrs, &l)) {
  195. return (FALSE);
  196. }
  197. *sp = (short) l;
  198. return (TRUE);
  199. case XDR_FREE:
  200. return (TRUE);
  201. }
  202. return (FALSE);
  203. }
  204. /*
  205.  * XDR unsigned short integers
  206.  */
  207. bool_t
  208. xdr_u_short(xdrs, usp)
  209. register XDR *xdrs;
  210. u_short *usp;
  211. {
  212. u_long l;
  213. switch (xdrs->x_op) {
  214. case XDR_ENCODE:
  215. l = (u_long) *usp;
  216. return (XDR_PUTLONG(xdrs, &l));
  217. case XDR_DECODE:
  218. if (!XDR_GETLONG(xdrs, &l)) {
  219. return (FALSE);
  220. }
  221. *usp = (u_short) l;
  222. return (TRUE);
  223. case XDR_FREE:
  224. return (TRUE);
  225. }
  226. return (FALSE);
  227. }
  228. /*
  229.  * XDR a char
  230.  */
  231. bool_t /* 4.0 */
  232. xdr_char(xdrs, cp) /* 4.0 */
  233. XDR *xdrs; /* 4.0 */
  234. char *cp; /* 4.0 */
  235. { /* 4.0 */
  236. int i; /* 4.0 */
  237. i = (*cp); /* 4.0 */
  238. if (!xdr_int(xdrs, &i)) { /* 4.0 */
  239. return (FALSE); /* 4.0 */
  240. } /* 4.0 */
  241. *cp = i; /* 4.0 */
  242. return (TRUE); /* 4.0 */
  243. } /* 4.0 */
  244. /*
  245.  * XDR an unsigned char
  246.  */
  247. bool_t /* 4.0 */
  248. xdr_u_char(xdrs, ucp) /* 4.0 */
  249. XDR *xdrs; /* 4.0 */
  250. u_char *ucp; /* 4.0 */
  251. { /* 4.0 */
  252. u_int u; /* 4.0 */
  253. u = (*ucp); /* 4.0 */
  254. if (!xdr_u_int(xdrs, &u)) { /* 4.0 */
  255. return (FALSE); /* 4.0 */
  256. } /* 4.0 */
  257. *ucp = u; /* 4.0 */
  258. return (TRUE); /* 4.0 */
  259. } /* 4.0 */
  260. /*
  261.  * XDR booleans
  262.  */
  263. bool_t
  264. xdr_bool(xdrs, bp)
  265. register XDR *xdrs;
  266. bool_t *bp;
  267. {
  268. long lb;
  269. switch (xdrs->x_op) {
  270. case XDR_ENCODE:
  271. lb = *bp ? XDR_TRUE : XDR_FALSE;
  272. return (XDR_PUTLONG(xdrs, &lb));
  273. case XDR_DECODE:
  274. if (!XDR_GETLONG(xdrs, &lb)) {
  275. return (FALSE);
  276. }
  277. *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
  278. return (TRUE);
  279. case XDR_FREE:
  280. return (TRUE);
  281. }
  282. return (FALSE);
  283. }
  284. /*
  285.  * XDR enumerations
  286.  */
  287. bool_t
  288. xdr_enum(xdrs, ep)
  289. XDR *xdrs;
  290. enum_t *ep;
  291. {
  292. #ifndef lint /* 4.0 */
  293. enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
  294. /*
  295.  * enums are treated as ints
  296.  */
  297. if (sizeof (enum sizecheck) == sizeof (long)) {
  298. return (xdr_long(xdrs, (long *)ep));
  299. } else if (sizeof (enum sizecheck) == sizeof (short)) {
  300. return (xdr_short(xdrs, (short *)ep));
  301. } else {
  302. return (FALSE);
  303. }
  304. #else
  305. (void) (xdr_short(xdrs, (short *)ep));
  306. return (xdr_long(xdrs, (long *)ep));
  307. #endif
  308. }
  309. /*
  310.  * XDR opaque data
  311.  * Allows the specification of a fixed size sequence of opaque bytes.
  312.  * cp points to the opaque object and cnt gives the byte length.
  313.  */
  314. bool_t
  315. xdr_opaque(xdrs, cp, cnt)
  316. register XDR *xdrs;
  317. caddr_t cp;
  318. register u_int cnt;
  319. {
  320. register u_int rndup;
  321. static int crud[BYTES_PER_XDR_UNIT];
  322. /*
  323.  * if no data we are done
  324.  */
  325. if (cnt == 0)
  326. return (TRUE);
  327. /*
  328.  * round byte count to full xdr units
  329.  */
  330. rndup = cnt % BYTES_PER_XDR_UNIT;
  331. if (rndup > 0)
  332. rndup = BYTES_PER_XDR_UNIT - rndup;
  333. if (xdrs->x_op == XDR_DECODE) {
  334. if (!XDR_GETBYTES(xdrs, cp, cnt)) {
  335. return (FALSE);
  336. }
  337. if (rndup == 0)
  338. return (TRUE);
  339. return (XDR_GETBYTES(xdrs, crud, rndup));
  340. }
  341. if (xdrs->x_op == XDR_ENCODE) {
  342. if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
  343. return (FALSE);
  344. }
  345. if (rndup == 0)
  346. return (TRUE);
  347. return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
  348. }
  349. if (xdrs->x_op == XDR_FREE) {
  350. return (TRUE);
  351. }
  352. return (FALSE);
  353. }
  354. /*
  355.  * XDR counted bytes
  356.  * *cpp is a pointer to the bytes, *sizep is the count.
  357.  * If *cpp is NULL maxsize bytes are allocated
  358.  */
  359. bool_t
  360. xdr_bytes(xdrs, cpp, sizep, maxsize)
  361. register XDR *xdrs;
  362. char **cpp;
  363. register u_int *sizep;
  364. u_int maxsize;
  365. {
  366. register char *sp = *cpp;  /* sp is the actual string pointer */
  367. register u_int nodesize;
  368. /*
  369.  * first deal with the length since xdr bytes are counted
  370.  */
  371. if (! xdr_u_int(xdrs, sizep)) {
  372. return (FALSE);
  373. }
  374. nodesize = *sizep;
  375. /* if zero length, then return immediately.
  376.  * this avoids mem_alloc/mem_free of 0 bytes.
  377.  */
  378. if (nodesize == 0) {
  379. return (TRUE);
  380. }
  381. if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
  382. return (FALSE);
  383. }
  384. /*
  385.  * now deal with the actual bytes
  386.  */
  387. switch (xdrs->x_op) {
  388. case XDR_DECODE:
  389. if (sp == NULL) {
  390. *cpp = sp = (char *)mem_alloc(nodesize);
  391. }
  392. if (sp == NULL) {
  393. PRINTERR ("xdr_bytes: out of memoryn");
  394. return (FALSE);
  395. }
  396. /* fall into ... */
  397. case XDR_ENCODE:
  398. return (xdr_opaque(xdrs, sp, nodesize));
  399. case XDR_FREE:
  400. if (sp != NULL) {
  401. mem_free(sp, nodesize);
  402. *cpp = NULL;
  403. }
  404. return (TRUE);
  405. }
  406. return (FALSE);
  407. }
  408. /*
  409.  * Implemented here due to commanlity of the object.
  410.  */
  411. bool_t /* 4.0 */
  412. xdr_netobj (xdrs, np) /* 4.0 */
  413.     XDR *xdrs; /* 4.0 */
  414.     struct netobj *np; /* 4.0 */
  415.     { /* 4.0 */
  416.     return (xdr_bytes (xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));/* 4.0 */
  417.     } /* 4.0 */
  418. /*
  419.  * XDR a descriminated union
  420.  * Support routine for discriminated unions.
  421.  * You create an array of xdrdiscrim structures, terminated with
  422.  * an entry with a null procedure pointer.  The routine gets
  423.  * the discriminant value and then searches the array of xdrdiscrims
  424.  * looking for that value.  It calls the procedure given in the xdrdiscrim
  425.  * to handle the discriminant.  If there is no specific routine a default
  426.  * routine may be called.
  427.  * If there is no specific or default routine an error is returned.
  428.  */
  429. bool_t
  430. xdr_union(xdrs, dscmp, unp, choices, dfault)
  431. register XDR *xdrs;
  432. enum_t *dscmp; /* enum to decide which arm to work on */
  433. caddr_t unp; /* the union itself */
  434. struct xdr_discrim *choices; /* [value, xdr proc] for each arm */
  435. xdrproc_t dfault; /* default xdr routine */
  436. {
  437. register enum_t dscm;
  438. /*
  439.  * we deal with the discriminator;  it's an enum
  440.  */
  441. if (! xdr_enum(xdrs, dscmp)) {
  442. return (FALSE);
  443. }
  444. dscm = *dscmp;
  445. /*
  446.  * search choices for a value that matches the discriminator.
  447.  * if we find one, execute the xdr routine for that value.
  448.  */
  449. for (; choices->proc != NULL_xdrproc_t; choices++) {
  450. if (choices->value == dscm)
  451. return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
  452. }
  453. /*
  454.  * no match - execute the default xdr routine if there is one
  455.  */
  456. return ((dfault == NULL_xdrproc_t) ? FALSE :
  457.     (*dfault)(xdrs, unp, LASTUNSIGNED));
  458. }
  459. /*
  460.  * Non-portable xdr primitives.
  461.  * Care should be taken when moving these routines to new architectures.
  462.  */
  463. /*
  464.  * XDR null terminated ASCII strings
  465.  * xdr_string deals with "C strings" - arrays of bytes that are
  466.  * terminated by a NULL character.  The parameter cpp references a
  467.  * pointer to storage; If the pointer is null, then the necessary
  468.  * storage is allocated.  The last parameter is the max allowed length
  469.  * of the string as specified by a protocol.
  470.  */
  471. bool_t
  472. xdr_string(xdrs, cpp, maxsize)
  473. register XDR *xdrs;
  474. char **cpp;
  475. u_int maxsize;
  476. {
  477. register char *sp = *cpp;  /* sp is the actual string pointer */
  478. u_int size;
  479. u_int nodesize;
  480. /*
  481.  * first deal with the length since xdr strings are counted-strings
  482.  */
  483. switch (xdrs->x_op) /* 4.0 */
  484.     { /* 4.0 */
  485.     case XDR_FREE: /* 4.0 */
  486. if (sp == NULL) /* already free */ /* 4.0 */
  487.     { /* 4.0 */
  488.     return (TRUE); /* 4.0 */
  489.     } /* 4.0 */
  490. /* fall through */ /* 4.0 */
  491.     case XDR_ENCODE: /* 4.0 */
  492. size = strlen (sp); /* 4.0 */
  493. break; /* 4.0 */
  494.     case XDR_DECODE: /* 4.0 */
  495. break; /* 4.0 */
  496.     } /* 4.0 */
  497. if (! xdr_u_int(xdrs, &size)) {
  498. return (FALSE);
  499. }
  500. if (size > maxsize) {
  501. return (FALSE);
  502. }
  503. nodesize = size + 1;
  504. /*
  505.  * now deal with the actual bytes
  506.  */
  507. switch (xdrs->x_op) {
  508. case XDR_DECODE:
  509. if (sp == NULL)
  510. *cpp = sp = (char *)mem_alloc(nodesize);
  511. if (sp == NULL) {
  512. PRINTERR ("xdr_string: out of memoryn");
  513. return (FALSE);
  514. }
  515. sp[size] = 0;
  516. /* fall into ... */
  517. case XDR_ENCODE:
  518. return (xdr_opaque(xdrs, sp, size));
  519. case XDR_FREE:
  520. mem_free(sp, nodesize); /* 4.0 */
  521. *cpp = NULL;
  522. return (TRUE);
  523. }
  524. return (FALSE);
  525. }
  526. /*
  527.  * Wrapper for xdr_string that can be called directly from
  528.  * routines like clnt_call
  529.  */
  530. bool_t
  531. xdr_wrapstring(xdrs, cpp)
  532. XDR *xdrs;
  533. char **cpp;
  534. {
  535. if (xdr_string(xdrs, cpp, BUFSIZ)) {
  536. return(TRUE);
  537. }
  538. return(FALSE);
  539. }
  540. #if (_BYTE_ORDER != _BIG_ENDIAN)
  541. /******************************************************************************
  542. *
  543. * idxdr_get_long - function replacement for IXDR_GET_LONG.
  544. *
  545. * this repleaces the IXDR_GET_LONG macro because macro expansion
  546. * of ntohl screws up the incrementing of buf.
  547. * Note: this is only for non-big endian versions.
  548. */
  549. u_long ixdr_get_long (buf)
  550.     u_long **buf;
  551.     {
  552.     u_long retval = ntohl (**buf); /* read data from buffer */
  553.     ++*buf; /* increment buffer pointer */
  554.     return (retval);
  555.     }
  556. #endif /* (_BYTE_ORDER != _BIG_ENDIAN) */