1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2015 Gary Mills
25  */
26 
27 /*
28  * This is a non-recursive version of XDR routine used for db_index_entry
29  * type.
30  */
31 
32 #include <sys/types.h>
33 #include <sys/syslog.h>
34 #include <stdio.h>
35 #include <rpc/types.h>
36 #include <rpc/xdr.h>
37 #include <memory.h>
38 #include "db_index_entry_c.h"
39 #include "db_table_c.h"
40 #include "xdr_nullptr.h"
41 
42 bool_t
xdr_db_index_entry(XDR * xdrs,db_index_entry * objp)43 xdr_db_index_entry(XDR *xdrs, db_index_entry *objp)
44 {
45 	bool_t	more_data;
46 	db_index_entry *ep = objp;
47 	db_index_entry *loc;
48 	db_index_entry *freeptr = NULL;
49 
50 	for (;;) {
51 		if (!xdr_u_long(xdrs, &ep->hashval))
52 			return (FALSE);
53 		if (!xdr_pointer(xdrs, (char **)&ep->key, sizeof (item),
54 		    (xdrproc_t)xdr_item))
55 			return (FALSE);
56 		if (!xdr_entryp(xdrs, &ep->location))
57 			return (FALSE);
58 		if (!xdr_nullptr(xdrs, &ep->next_result))
59 			return (FALSE);
60 
61 		/*
62 		 * The following code replaces the call to
63 		 * xdr_pointer(
64 		 *	xdrs,
65 		 *	(char **)&ep->next,
66 		 *	sizeof (db_index_entry),
67 		 *	(xdrproc_t) xdr_db_index_entry))
68 		 *
69 		 * It's a modified version of xdr_refer.c from the rpc library:
70 		 *	@(#)xdr_refer.c		1.8	92/07/20 SMI
71 		 */
72 
73 
74 		/*
75 		 * the following assignment to more_data is only useful when
76 		 * encoding and freeing.  When decoding, more_data will be
77 		 * filled by the xdr_bool() routine.
78 		 */
79 		more_data = (ep->next != NULL);
80 		if (! xdr_bool(xdrs, &more_data))
81 			return (FALSE);
82 		if (! more_data) {
83 			ep->next = NULL;
84 			break;
85 		}
86 
87 		loc = ep->next;
88 
89 
90 		switch (xdrs->x_op) {
91 		case XDR_DECODE:
92 			if (loc == NULL) {
93 				ep->next = loc = (db_index_entry *)
94 				    mem_alloc(sizeof (db_index_entry));
95 				if (loc == NULL) {
96 					syslog(LOG_ERR,
97 				"xdr_db_index_entry: mem_alloc failed");
98 					return (FALSE);
99 				}
100 				memset(loc, 0, sizeof (db_index_entry));
101 			}
102 			break;
103 		case XDR_FREE:
104 			if (freeptr != NULL) {
105 				mem_free(freeptr, sizeof (db_index_entry));
106 			} else
107 				ep->next = NULL;
108 			freeptr = loc;
109 			break;
110 		}
111 
112 		if (loc == NULL)
113 			break;
114 		ep = loc;
115 	}	/* for loop */
116 
117 	if ((freeptr != NULL) && (xdrs->x_op == XDR_FREE)) {
118 		mem_free(freeptr, sizeof (db_index_entry));
119 	}
120 
121 	return (TRUE);
122 }
123 
124 
125 bool_t
xdr_db_index_entry_p(XDR * xdrs,db_index_entry_p * objp)126 xdr_db_index_entry_p(XDR *xdrs, db_index_entry_p *objp)
127 {
128 
129 	if (!xdr_pointer(xdrs, (char **)objp, sizeof (db_index_entry),
130 	    (xdrproc_t)xdr_db_index_entry))
131 		return (FALSE);
132 	return (TRUE);
133 }
134 
135 
136 
137 bool_t
xdr_db_free_entry(XDR * xdrs,db_free_entry * objp)138 xdr_db_free_entry(XDR *xdrs, db_free_entry *objp)
139 {
140 	bool_t	more_data;
141 	db_free_entry *ep = objp;
142 	db_free_entry *loc;
143 	db_free_entry *freeptr = NULL;
144 
145 	for (;;) {
146 		if (!xdr_entryp(xdrs, &ep->where))
147 			return (FALSE);
148 
149 		/*
150 		 * The following code replaces the call to
151 		 * xdr_pointer(
152 		 *	xdrs,
153 		 *	(char **)&ep->next,
154 		 *	sizeof (db_free_entry),
155 		 *	(xdrproc_t) xdr_db_free_entry))
156 		 *
157 		 * It's a modified version of xdr_refer.c from the rpc library:
158 		 *	@(#)xdr_refer.c		1.8	92/07/20 SMI
159 		 */
160 
161 
162 		/*
163 		 * the following assignment to more_data is only useful when
164 		 * encoding and freeing.  When decoding, more_data will be
165 		 * filled by the xdr_bool() routine.
166 		 */
167 		more_data = (ep->next != NULL);
168 		if (! xdr_bool(xdrs, &more_data))
169 			return (FALSE);
170 		if (! more_data) {
171 			ep->next = NULL;
172 			break;
173 		}
174 
175 		loc = ep->next;
176 
177 
178 		switch (xdrs->x_op) {
179 		case XDR_DECODE:
180 			if (loc == NULL) {
181 				ep->next = loc = (db_free_entry *)
182 				    mem_alloc(sizeof (db_free_entry));
183 				if (loc == NULL) {
184 					syslog(LOG_ERR,
185 				"db_free_entry: mem_alloc failed");
186 					return (FALSE);
187 				}
188 				memset(loc, 0, sizeof (db_free_entry));
189 			}
190 			break;
191 		case XDR_FREE:
192 			if (freeptr != NULL) {
193 				mem_free(freeptr, sizeof (db_free_entry));
194 			} else
195 				ep->next = NULL;
196 			freeptr = loc;
197 			break;
198 		}
199 
200 		if (loc == NULL)
201 			break;
202 		ep = loc;
203 	}	/* for loop */
204 
205 	if ((freeptr != NULL) && (xdrs->x_op == XDR_FREE)) {
206 		mem_free(freeptr, sizeof (db_free_entry));
207 	}
208 	return (TRUE);
209 }
210