1 /* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */
2 /*
3 * Copyright (c) 2010, Oracle America, Inc.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * * Neither the name of the "Oracle America, Inc." nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34 #if !defined(lint) && defined(SCCSIDS)
35 static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI";
36 #endif
37
38 /*
39 * xdr_reference.c, Generic XDR routines impelmentation.
40 *
41 * These are the "non-trivial" xdr primitives used to serialize and de-serialize
42 * "pointers". See xdr.h for more info on the interface to xdr.
43 */
44
45 #include <stdio.h>
46 #include <string.h>
47 #include <gssrpc/types.h>
48 #include <gssrpc/xdr.h>
49
50 #define LASTUNSIGNED ((u_int)0-1)
51
52 /*
53 * XDR an indirect pointer
54 * xdr_reference is for recursively translating a structure that is
55 * referenced by a pointer inside the structure that is currently being
56 * translated. pp references a pointer to storage. If *pp is null
57 * the necessary storage is allocated.
58 * size is the sizeof the referenced structure.
59 * proc is the routine to handle the referenced structure.
60 */
61 bool_t
xdr_reference(XDR * xdrs,caddr_t * pp,u_int size,xdrproc_t proc)62 xdr_reference(
63 XDR *xdrs,
64 caddr_t *pp, /* the pointer to work on */
65 u_int size, /* size of the object pointed to */
66 xdrproc_t proc /* xdr routine to handle the object */
67 )
68 {
69 caddr_t loc = *pp;
70 bool_t stat;
71
72 if (loc == NULL)
73 switch (xdrs->x_op) {
74 case XDR_FREE:
75 return (TRUE);
76
77 case XDR_DECODE:
78 *pp = loc = (caddr_t) mem_alloc(size);
79 if (loc == NULL) {
80 (void) fprintf(stderr,
81 "xdr_reference: out of memory\n");
82 return (FALSE);
83 }
84 memset(loc, 0, size);
85 break;
86
87 case XDR_ENCODE:
88 break;
89 }
90
91 stat = (*proc)(xdrs, loc, LASTUNSIGNED);
92
93 if (xdrs->x_op == XDR_FREE) {
94 mem_free(loc, size);
95 *pp = NULL;
96 }
97 return (stat);
98 }
99
100
101 /*
102 * xdr_pointer():
103 *
104 * XDR a pointer to a possibly recursive data structure. This
105 * differs with xdr_reference in that it can serialize/deserialiaze
106 * trees correctly.
107 *
108 * What's sent is actually a union:
109 *
110 * union object_pointer switch (boolean b) {
111 * case TRUE: object_data data;
112 * case FALSE: void nothing;
113 * }
114 *
115 * > objpp: Pointer to the pointer to the object.
116 * > obj_size: size of the object.
117 * > xdr_obj: routine to XDR an object.
118 *
119 */
120 bool_t
xdr_pointer(XDR * xdrs,char ** objpp,u_int obj_size,xdrproc_t xdr_obj)121 xdr_pointer(
122 XDR *xdrs,
123 char **objpp,
124 u_int obj_size,
125 xdrproc_t xdr_obj)
126 {
127
128 bool_t more_data;
129
130 more_data = (*objpp != NULL);
131 if (! xdr_bool(xdrs,&more_data)) {
132 return (FALSE);
133 }
134 if (! more_data) {
135 *objpp = NULL;
136 return (TRUE);
137 }
138 return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
139 }
140