xref: /illumos-gate/usr/src/cmd/sendmail/db/db/db_conv.c (revision 7c478bd9)
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1996, 1997, 1998
5  *	Sleepycat Software.  All rights reserved.
6  */
7 /*
8  * Copyright (c) 1990, 1993, 1994, 1995, 1996
9  *	Keith Bostic.  All rights reserved.
10  */
11 /*
12  * Copyright (c) 1990, 1993, 1994, 1995
13  *	The Regents of the University of California.  All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. All advertising materials mentioning features or use of this software
24  *    must display the following acknowledgement:
25  *	This product includes software developed by the University of
26  *	California, Berkeley and its contributors.
27  * 4. Neither the name of the University nor the names of its contributors
28  *    may be used to endorse or promote products derived from this software
29  *    without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41  * SUCH DAMAGE.
42  */
43 
44 #include "config.h"
45 
46 #ifndef lint
47 static const char sccsid[] = "@(#)db_conv.c	10.13 (Sleepycat) 4/26/98";
48 #endif /* not lint */
49 
50 #ifndef NO_SYSTEM_INCLUDES
51 #include <sys/types.h>
52 
53 #include <errno.h>
54 #include <string.h>
55 #endif
56 
57 #include "db_int.h"
58 #include "db_page.h"
59 #include "db_swap.h"
60 #include "db_am.h"
61 
62 static int __db_convert __P((db_pgno_t, void *, size_t, int));
63 
64 /*
65  * __db_pgin --
66  *
67  * PUBLIC: int __db_pgin __P((db_pgno_t, size_t, void *));
68  */
69 int
__db_pgin(pg,pagesize,pp)70 __db_pgin(pg, pagesize, pp)
71 	db_pgno_t pg;
72 	size_t pagesize;
73 	void *pp;
74 {
75 	return (__db_convert(pg, pp, pagesize, 1));
76 }
77 
78 /*
79  * __db_pgout --
80  *
81  * PUBLIC: int __db_pgout __P((db_pgno_t, size_t, void *));
82  */
83 int
__db_pgout(pg,pagesize,pp)84 __db_pgout(pg, pagesize, pp)
85 	db_pgno_t pg;
86 	size_t pagesize;
87 	void *pp;
88 {
89 	return (__db_convert(pg, pp, pagesize, 0));
90 }
91 
92 /*
93  * __db_convert --
94  *	Actually convert a page.
95  */
96 static int
__db_convert(pg,pp,pagesize,pgin)97 __db_convert(pg, pp, pagesize, pgin)
98 	db_pgno_t pg;
99 	void *pp;
100 	size_t pagesize;
101 	int pgin;
102 {
103 	BINTERNAL *bi;
104 	BKEYDATA *bk;
105 	BOVERFLOW *bo;
106 	PAGE *h;
107 	RINTERNAL *ri;
108 	db_indx_t i, len, tmp;
109 	u_int8_t *p, *end;
110 
111 	COMPQUIET(pg, 0);
112 
113 	h = pp;
114 	if (pgin) {
115 		M_32_SWAP(h->lsn.file);
116 		M_32_SWAP(h->lsn.offset);
117 		M_32_SWAP(h->pgno);
118 		M_32_SWAP(h->prev_pgno);
119 		M_32_SWAP(h->next_pgno);
120 		M_16_SWAP(h->entries);
121 		M_16_SWAP(h->hf_offset);
122 	}
123 
124 	switch (h->type) {
125 	case P_HASH:
126 		for (i = 0; i < NUM_ENT(h); i++) {
127 			if (pgin)
128 				M_16_SWAP(h->inp[i]);
129 
130 			switch (HPAGE_TYPE(h, i)) {
131 			case H_KEYDATA:
132 				break;
133 			case H_DUPLICATE:
134 				len = LEN_HKEYDATA(h, pagesize, i);
135 				p = HKEYDATA_DATA(P_ENTRY(h, i));
136 				for (end = p + len; p < end;) {
137 					if (pgin) {
138 						P_16_SWAP(p);
139 						memcpy(&tmp,
140 						    p, sizeof(db_indx_t));
141 						p += sizeof(db_indx_t);
142 					} else {
143 						memcpy(&tmp,
144 						    p, sizeof(db_indx_t));
145 						SWAP16(p);
146 					}
147 					p += tmp;
148 					SWAP16(p);
149 				}
150 				break;
151 			case H_OFFDUP:
152 				p = HOFFPAGE_PGNO(P_ENTRY(h, i));
153 				SWAP32(p);			/* pgno */
154 				break;
155 			case H_OFFPAGE:
156 				p = HOFFPAGE_PGNO(P_ENTRY(h, i));
157 				SWAP32(p);			/* pgno */
158 				SWAP32(p);			/* tlen */
159 				break;
160 			}
161 
162 		}
163 
164 		/*
165 		 * The offsets in the inp array are used to determine
166 		 * the size of entries on a page; therefore they
167 		 * cannot be converted until we've done all the
168 		 * entries.
169 		 */
170 		if (!pgin)
171 			for (i = 0; i < NUM_ENT(h); i++)
172 				M_16_SWAP(h->inp[i]);
173 		break;
174 	case P_LBTREE:
175 	case P_LRECNO:
176 	case P_DUPLICATE:
177 		for (i = 0; i < NUM_ENT(h); i++) {
178 			if (pgin)
179 				M_16_SWAP(h->inp[i]);
180 
181 			bk = GET_BKEYDATA(h, i);
182 			switch (B_TYPE(bk->type)) {
183 			case B_KEYDATA:
184 				M_16_SWAP(bk->len);
185 				break;
186 			case B_DUPLICATE:
187 			case B_OVERFLOW:
188 				bo = (BOVERFLOW *)bk;
189 				M_32_SWAP(bo->pgno);
190 				M_32_SWAP(bo->tlen);
191 				break;
192 			}
193 
194 			if (!pgin)
195 				M_16_SWAP(h->inp[i]);
196 		}
197 		break;
198 	case P_IBTREE:
199 		for (i = 0; i < NUM_ENT(h); i++) {
200 			if (pgin)
201 				M_16_SWAP(h->inp[i]);
202 
203 			bi = GET_BINTERNAL(h, i);
204 			M_16_SWAP(bi->len);
205 			M_32_SWAP(bi->pgno);
206 			M_32_SWAP(bi->nrecs);
207 
208 			switch (B_TYPE(bi->type)) {
209 			case B_KEYDATA:
210 				break;
211 			case B_DUPLICATE:
212 			case B_OVERFLOW:
213 				bo = (BOVERFLOW *)bi->data;
214 				M_32_SWAP(bo->pgno);
215 				M_32_SWAP(bo->tlen);
216 				break;
217 			}
218 
219 			if (!pgin)
220 				M_16_SWAP(h->inp[i]);
221 		}
222 		break;
223 	case P_IRECNO:
224 		for (i = 0; i < NUM_ENT(h); i++) {
225 			if (pgin)
226 				M_16_SWAP(h->inp[i]);
227 
228 			ri = GET_RINTERNAL(h, i);
229 			M_32_SWAP(ri->pgno);
230 			M_32_SWAP(ri->nrecs);
231 
232 			if (!pgin)
233 				M_16_SWAP(h->inp[i]);
234 		}
235 		break;
236 	case P_OVERFLOW:
237 	case P_INVALID:
238 		/* Nothing to do. */
239 		break;
240 	default:
241 		return (EINVAL);
242 	}
243 
244 	if (!pgin) {
245 		/* Swap the header information. */
246 		M_32_SWAP(h->lsn.file);
247 		M_32_SWAP(h->lsn.offset);
248 		M_32_SWAP(h->pgno);
249 		M_32_SWAP(h->prev_pgno);
250 		M_32_SWAP(h->next_pgno);
251 		M_16_SWAP(h->entries);
252 		M_16_SWAP(h->hf_offset);
253 	}
254 	return (0);
255 }
256