Fix typos.
[jlayton/glibc.git] / sunrpc / xdr_array.c
1 /*
2  * xdr_array.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 "non-trivial" xdr primitives used to serialize and
34  * de-serialize arrays.  See xdr.h for more info on the interface to xdr.
35  */
36
37 #include <stdio.h>
38 #include <string.h>
39 #include <rpc/types.h>
40 #include <rpc/xdr.h>
41 #include <libintl.h>
42 #include <limits.h>
43 #include <wchar.h>
44
45 #define LASTUNSIGNED    ((u_int)0-1)
46
47
48 /*
49  * XDR an array of arbitrary elements
50  * *addrp is a pointer to the array, *sizep is the number of elements.
51  * If addrp is NULL (*sizep * elsize) bytes are allocated.
52  * elsize is the size (in bytes) of each element, and elproc is the
53  * xdr procedure to call to handle each element of the array.
54  */
55 bool_t
56 xdr_array (xdrs, addrp, sizep, maxsize, elsize, elproc)
57      XDR *xdrs;
58      caddr_t *addrp;            /* array pointer */
59      u_int *sizep;              /* number of elements */
60      u_int maxsize;             /* max numberof elements */
61      u_int elsize;              /* size in bytes of each element */
62      xdrproc_t elproc;          /* xdr routine to handle each element */
63 {
64   u_int i;
65   caddr_t target = *addrp;
66   u_int c;              /* the actual element count */
67   bool_t stat = TRUE;
68
69   /* like strings, arrays are really counted arrays */
70   if (!xdr_u_int (xdrs, sizep))
71     {
72       return FALSE;
73     }
74   c = *sizep;
75   /*
76    * XXX: Let the overflow possibly happen with XDR_FREE because mem_free()
77    * doesn't actually use its second argument anyway.
78    */
79   if ((c > maxsize || c > UINT_MAX / elsize) && (xdrs->x_op != XDR_FREE))
80     {
81       return FALSE;
82     }
83
84   /*
85    * if we are deserializing, we may need to allocate an array.
86    * We also save time by checking for a null array if we are freeing.
87    */
88   if (target == NULL)
89     switch (xdrs->x_op)
90       {
91       case XDR_DECODE:
92         if (c == 0)
93           return TRUE;
94         *addrp = target = calloc (c, elsize);
95         if (target == NULL)
96           {
97             (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
98             return FALSE;
99           }
100         break;
101
102       case XDR_FREE:
103         return TRUE;
104       default:
105         break;
106       }
107
108   /*
109    * now we xdr each element of array
110    */
111   for (i = 0; (i < c) && stat; i++)
112     {
113       stat = (*elproc) (xdrs, target, LASTUNSIGNED);
114       target += elsize;
115     }
116
117   /*
118    * the array may need freeing
119    */
120   if (xdrs->x_op == XDR_FREE)
121     {
122       mem_free (*addrp, c * elsize);
123       *addrp = NULL;
124     }
125   return stat;
126 }
127 #ifdef EXPORT_RPC_SYMBOLS
128 libc_hidden_def (xdr_array)
129 #else
130 libc_hidden_nolink_sunrpc (xdr_array, GLIBC_2_0)
131 #endif
132
133 /*
134  * xdr_vector():
135  *
136  * XDR a fixed length array. Unlike variable-length arrays,
137  * the storage of fixed length arrays is static and unfreeable.
138  * > basep: base of the array
139  * > size: size of the array
140  * > elemsize: size of each element
141  * > xdr_elem: routine to XDR each element
142  */
143 bool_t
144 xdr_vector (xdrs, basep, nelem, elemsize, xdr_elem)
145      XDR *xdrs;
146      char *basep;
147      u_int nelem;
148      u_int elemsize;
149      xdrproc_t xdr_elem;
150 {
151   u_int i;
152   char *elptr;
153
154   elptr = basep;
155   for (i = 0; i < nelem; i++)
156     {
157       if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED))
158         {
159           return FALSE;
160         }
161       elptr += elemsize;
162     }
163   return TRUE;
164 }
165 libc_hidden_nolink_sunrpc (xdr_vector, GLIBC_2_0)