xref: /illumos-gate/usr/src/cmd/sendmail/db/db/db_pr.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*-
2*7c478bd9Sstevel@tonic-gate  * See the file LICENSE for redistribution information.
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1996, 1997, 1998
5*7c478bd9Sstevel@tonic-gate  *	Sleepycat Software.  All rights reserved.
6*7c478bd9Sstevel@tonic-gate  */
7*7c478bd9Sstevel@tonic-gate 
8*7c478bd9Sstevel@tonic-gate #include "config.h"
9*7c478bd9Sstevel@tonic-gate 
10*7c478bd9Sstevel@tonic-gate #ifndef lint
11*7c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)db_pr.c	10.40 (Sleepycat) 11/22/98";
12*7c478bd9Sstevel@tonic-gate #endif /* not lint */
13*7c478bd9Sstevel@tonic-gate 
14*7c478bd9Sstevel@tonic-gate #ifndef NO_SYSTEM_INCLUDES
15*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #include <ctype.h>
18*7c478bd9Sstevel@tonic-gate #include <errno.h>
19*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
20*7c478bd9Sstevel@tonic-gate #include <string.h>
21*7c478bd9Sstevel@tonic-gate #include <unistd.h>
22*7c478bd9Sstevel@tonic-gate #endif
23*7c478bd9Sstevel@tonic-gate 
24*7c478bd9Sstevel@tonic-gate #include "db_int.h"
25*7c478bd9Sstevel@tonic-gate #include "db_page.h"
26*7c478bd9Sstevel@tonic-gate #include "btree.h"
27*7c478bd9Sstevel@tonic-gate #include "hash.h"
28*7c478bd9Sstevel@tonic-gate #include "db_am.h"
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate static void __db_proff __P((void *));
31*7c478bd9Sstevel@tonic-gate static void __db_psize __P((DB_MPOOLFILE *));
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  * __db_loadme --
35*7c478bd9Sstevel@tonic-gate  *	Force loading of this file.
36*7c478bd9Sstevel@tonic-gate  *
37*7c478bd9Sstevel@tonic-gate  * PUBLIC: void __db_loadme __P((void));
38*7c478bd9Sstevel@tonic-gate  */
39*7c478bd9Sstevel@tonic-gate void
__db_loadme()40*7c478bd9Sstevel@tonic-gate __db_loadme()
41*7c478bd9Sstevel@tonic-gate {
42*7c478bd9Sstevel@tonic-gate 	getpid();
43*7c478bd9Sstevel@tonic-gate }
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate static FILE *set_fp;
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate /*
48*7c478bd9Sstevel@tonic-gate  * 64K is the maximum page size, so by default we check for offsets
49*7c478bd9Sstevel@tonic-gate  * larger than that, and, where possible, we refine the test.
50*7c478bd9Sstevel@tonic-gate  */
51*7c478bd9Sstevel@tonic-gate #define	PSIZE_BOUNDARY	(64 * 1024 + 1)
52*7c478bd9Sstevel@tonic-gate static size_t set_psize = PSIZE_BOUNDARY;
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate /*
55*7c478bd9Sstevel@tonic-gate  * __db_prinit --
56*7c478bd9Sstevel@tonic-gate  *	Initialize tree printing routines.
57*7c478bd9Sstevel@tonic-gate  *
58*7c478bd9Sstevel@tonic-gate  * PUBLIC: FILE *__db_prinit __P((FILE *));
59*7c478bd9Sstevel@tonic-gate  */
60*7c478bd9Sstevel@tonic-gate FILE *
__db_prinit(fp)61*7c478bd9Sstevel@tonic-gate __db_prinit(fp)
62*7c478bd9Sstevel@tonic-gate 	FILE *fp;
63*7c478bd9Sstevel@tonic-gate {
64*7c478bd9Sstevel@tonic-gate 	if (set_fp == NULL)
65*7c478bd9Sstevel@tonic-gate 		set_fp = fp == NULL ? stdout : fp;
66*7c478bd9Sstevel@tonic-gate 	return (set_fp);
67*7c478bd9Sstevel@tonic-gate }
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate /*
70*7c478bd9Sstevel@tonic-gate  * __db_dump --
71*7c478bd9Sstevel@tonic-gate  *	Dump the tree to a file.
72*7c478bd9Sstevel@tonic-gate  *
73*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_dump __P((DB *, char *, int));
74*7c478bd9Sstevel@tonic-gate  */
75*7c478bd9Sstevel@tonic-gate int
__db_dump(dbp,name,all)76*7c478bd9Sstevel@tonic-gate __db_dump(dbp, name, all)
77*7c478bd9Sstevel@tonic-gate 	DB *dbp;
78*7c478bd9Sstevel@tonic-gate 	char *name;
79*7c478bd9Sstevel@tonic-gate 	int all;
80*7c478bd9Sstevel@tonic-gate {
81*7c478bd9Sstevel@tonic-gate 	FILE *fp, *save_fp;
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 	COMPQUIET(save_fp, NULL);
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 	if (set_psize == PSIZE_BOUNDARY)
86*7c478bd9Sstevel@tonic-gate 		__db_psize(dbp->mpf);
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate 	if (name != NULL) {
89*7c478bd9Sstevel@tonic-gate 		if ((fp = fopen(name, "w")) == NULL)
90*7c478bd9Sstevel@tonic-gate 			return (errno);
91*7c478bd9Sstevel@tonic-gate 		save_fp = set_fp;
92*7c478bd9Sstevel@tonic-gate 		set_fp = fp;
93*7c478bd9Sstevel@tonic-gate 	} else
94*7c478bd9Sstevel@tonic-gate 		fp = __db_prinit(NULL);
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	(void)__db_prdb(dbp);
97*7c478bd9Sstevel@tonic-gate 	if (dbp->type == DB_HASH)
98*7c478bd9Sstevel@tonic-gate 		(void)__db_prhash(dbp);
99*7c478bd9Sstevel@tonic-gate 	else
100*7c478bd9Sstevel@tonic-gate 		(void)__db_prbtree(dbp);
101*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "%s\n", DB_LINE);
102*7c478bd9Sstevel@tonic-gate 	__db_prtree(dbp->mpf, all);
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 	if (name != NULL) {
105*7c478bd9Sstevel@tonic-gate 		(void)fclose(fp);
106*7c478bd9Sstevel@tonic-gate 		set_fp = save_fp;
107*7c478bd9Sstevel@tonic-gate 	}
108*7c478bd9Sstevel@tonic-gate 	return (0);
109*7c478bd9Sstevel@tonic-gate }
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate /*
112*7c478bd9Sstevel@tonic-gate  * __db_prdb --
113*7c478bd9Sstevel@tonic-gate  *	Print out the DB structure information.
114*7c478bd9Sstevel@tonic-gate  *
115*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_prdb __P((DB *));
116*7c478bd9Sstevel@tonic-gate  */
117*7c478bd9Sstevel@tonic-gate int
__db_prdb(dbp)118*7c478bd9Sstevel@tonic-gate __db_prdb(dbp)
119*7c478bd9Sstevel@tonic-gate 	DB *dbp;
120*7c478bd9Sstevel@tonic-gate {
121*7c478bd9Sstevel@tonic-gate 	static const FN fn[] = {
122*7c478bd9Sstevel@tonic-gate 		{ DB_AM_DUP,		"duplicates" },
123*7c478bd9Sstevel@tonic-gate 		{ DB_AM_INMEM,		"in-memory" },
124*7c478bd9Sstevel@tonic-gate 		{ DB_AM_LOCKING,	"locking" },
125*7c478bd9Sstevel@tonic-gate 		{ DB_AM_LOGGING,	"logging" },
126*7c478bd9Sstevel@tonic-gate 		{ DB_AM_MLOCAL,		"local mpool" },
127*7c478bd9Sstevel@tonic-gate 		{ DB_AM_PGDEF,		"default page size" },
128*7c478bd9Sstevel@tonic-gate 		{ DB_AM_RDONLY,		"read-only" },
129*7c478bd9Sstevel@tonic-gate 		{ DB_AM_SWAP,		"needswap" },
130*7c478bd9Sstevel@tonic-gate 		{ DB_AM_THREAD,		"thread" },
131*7c478bd9Sstevel@tonic-gate 		{ DB_BT_RECNUM,		"btree:recnum" },
132*7c478bd9Sstevel@tonic-gate 		{ DB_DBM_ERROR,		"dbm/ndbm error" },
133*7c478bd9Sstevel@tonic-gate 		{ DB_RE_DELIMITER,	"recno:delimiter" },
134*7c478bd9Sstevel@tonic-gate 		{ DB_RE_FIXEDLEN,	"recno:fixed-length" },
135*7c478bd9Sstevel@tonic-gate 		{ DB_RE_PAD,		"recno:pad" },
136*7c478bd9Sstevel@tonic-gate 		{ DB_RE_RENUMBER,	"recno:renumber" },
137*7c478bd9Sstevel@tonic-gate 		{ DB_RE_SNAPSHOT,	"recno:snapshot" },
138*7c478bd9Sstevel@tonic-gate 		{ 0 },
139*7c478bd9Sstevel@tonic-gate 	};
140*7c478bd9Sstevel@tonic-gate 	FILE *fp;
141*7c478bd9Sstevel@tonic-gate 	const char *t;
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 	fp = __db_prinit(NULL);
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	switch (dbp->type) {
146*7c478bd9Sstevel@tonic-gate 	case DB_BTREE:
147*7c478bd9Sstevel@tonic-gate 		t = "btree";
148*7c478bd9Sstevel@tonic-gate 		break;
149*7c478bd9Sstevel@tonic-gate 	case DB_HASH:
150*7c478bd9Sstevel@tonic-gate 		t = "hash";
151*7c478bd9Sstevel@tonic-gate 		break;
152*7c478bd9Sstevel@tonic-gate 	case DB_RECNO:
153*7c478bd9Sstevel@tonic-gate 		t = "recno";
154*7c478bd9Sstevel@tonic-gate 		break;
155*7c478bd9Sstevel@tonic-gate 	default:
156*7c478bd9Sstevel@tonic-gate 		t = "UNKNOWN";
157*7c478bd9Sstevel@tonic-gate 		break;
158*7c478bd9Sstevel@tonic-gate 	}
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "%s ", t);
161*7c478bd9Sstevel@tonic-gate 	__db_prflags(dbp->flags, fn, fp);
162*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n");
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 	return (0);
165*7c478bd9Sstevel@tonic-gate }
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate /*
168*7c478bd9Sstevel@tonic-gate  * __db_prbtree --
169*7c478bd9Sstevel@tonic-gate  *	Print out the btree internal information.
170*7c478bd9Sstevel@tonic-gate  *
171*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_prbtree __P((DB *));
172*7c478bd9Sstevel@tonic-gate  */
173*7c478bd9Sstevel@tonic-gate int
__db_prbtree(dbp)174*7c478bd9Sstevel@tonic-gate __db_prbtree(dbp)
175*7c478bd9Sstevel@tonic-gate 	DB *dbp;
176*7c478bd9Sstevel@tonic-gate {
177*7c478bd9Sstevel@tonic-gate 	static const FN mfn[] = {
178*7c478bd9Sstevel@tonic-gate 		{ BTM_DUP,	"duplicates" },
179*7c478bd9Sstevel@tonic-gate 		{ BTM_RECNO,	"recno" },
180*7c478bd9Sstevel@tonic-gate 		{ BTM_RECNUM,	"btree:recnum" },
181*7c478bd9Sstevel@tonic-gate 		{ BTM_FIXEDLEN,	"recno:fixed-length" },
182*7c478bd9Sstevel@tonic-gate 		{ BTM_RENUMBER,	"recno:renumber" },
183*7c478bd9Sstevel@tonic-gate 		{ 0 },
184*7c478bd9Sstevel@tonic-gate 	};
185*7c478bd9Sstevel@tonic-gate 	DBC *dbc;
186*7c478bd9Sstevel@tonic-gate 	BTMETA *mp;
187*7c478bd9Sstevel@tonic-gate 	BTREE *t;
188*7c478bd9Sstevel@tonic-gate 	FILE *fp;
189*7c478bd9Sstevel@tonic-gate 	PAGE *h;
190*7c478bd9Sstevel@tonic-gate 	RECNO *rp;
191*7c478bd9Sstevel@tonic-gate 	db_pgno_t i;
192*7c478bd9Sstevel@tonic-gate 	int cnt, ret;
193*7c478bd9Sstevel@tonic-gate 	const char *sep;
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 	t = dbp->internal;
196*7c478bd9Sstevel@tonic-gate 	fp = __db_prinit(NULL);
197*7c478bd9Sstevel@tonic-gate 	if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
198*7c478bd9Sstevel@tonic-gate 		return (ret);
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "%s\nOn-page metadata:\n", DB_LINE);
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 	i = PGNO_METADATA;
203*7c478bd9Sstevel@tonic-gate 	if ((ret = memp_fget(dbp->mpf, &i, 0, (PAGE **)&mp)) != 0) {
204*7c478bd9Sstevel@tonic-gate 		(void)dbc->c_close(dbc);
205*7c478bd9Sstevel@tonic-gate 		return (ret);
206*7c478bd9Sstevel@tonic-gate 	}
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "lsn.file: %lu lsn.offset: %lu\n",
209*7c478bd9Sstevel@tonic-gate 	    (u_long)LSN(mp).file, (u_long)LSN(mp).offset);
210*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "magic %#lx\n", (u_long)mp->magic);
211*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "version %#lx\n", (u_long)mp->version);
212*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "pagesize %lu\n", (u_long)mp->pagesize);
213*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "maxkey: %lu minkey: %lu\n",
214*7c478bd9Sstevel@tonic-gate 	    (u_long)mp->maxkey, (u_long)mp->minkey);
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "free list: %lu", (u_long)mp->free);
217*7c478bd9Sstevel@tonic-gate 	for (i = mp->free, cnt = 0, sep = ", "; i != PGNO_INVALID;) {
218*7c478bd9Sstevel@tonic-gate 		if ((ret = memp_fget(dbp->mpf, &i, 0, &h)) != 0)
219*7c478bd9Sstevel@tonic-gate 			return (ret);
220*7c478bd9Sstevel@tonic-gate 		i = h->next_pgno;
221*7c478bd9Sstevel@tonic-gate 		(void)memp_fput(dbp->mpf, h, 0);
222*7c478bd9Sstevel@tonic-gate 		(void)fprintf(fp, "%s%lu", sep, (u_long)i);
223*7c478bd9Sstevel@tonic-gate 		if (++cnt % 10 == 0) {
224*7c478bd9Sstevel@tonic-gate 			(void)fprintf(fp, "\n");
225*7c478bd9Sstevel@tonic-gate 			cnt = 0;
226*7c478bd9Sstevel@tonic-gate 			sep = "";
227*7c478bd9Sstevel@tonic-gate 		} else
228*7c478bd9Sstevel@tonic-gate 			sep = ", ";
229*7c478bd9Sstevel@tonic-gate 	}
230*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "\n");
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "flags %#lx", (u_long)mp->flags);
233*7c478bd9Sstevel@tonic-gate 	__db_prflags(mp->flags, mfn, fp);
234*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "\n");
235*7c478bd9Sstevel@tonic-gate 	(void)memp_fput(dbp->mpf, mp, 0);
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "%s\nDB_INFO:\n", DB_LINE);
238*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "bt_maxkey: %lu bt_minkey: %lu\n",
239*7c478bd9Sstevel@tonic-gate 	    (u_long)t->bt_maxkey, (u_long)t->bt_minkey);
240*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "bt_compare: %#lx bt_prefix: %#lx\n",
241*7c478bd9Sstevel@tonic-gate 	    (u_long)t->bt_compare, (u_long)t->bt_prefix);
242*7c478bd9Sstevel@tonic-gate 	if ((rp = t->recno) != NULL) {
243*7c478bd9Sstevel@tonic-gate 		(void)fprintf(fp,
244*7c478bd9Sstevel@tonic-gate 		    "re_delim: %#lx re_pad: %#lx re_len: %lu re_source: %s\n",
245*7c478bd9Sstevel@tonic-gate 		    (u_long)rp->re_delim, (u_long)rp->re_pad,
246*7c478bd9Sstevel@tonic-gate 		    (u_long)rp->re_len,
247*7c478bd9Sstevel@tonic-gate 		    rp->re_source == NULL ? "" : rp->re_source);
248*7c478bd9Sstevel@tonic-gate 		(void)fprintf(fp,
249*7c478bd9Sstevel@tonic-gate 		    "cmap: %#lx smap: %#lx emap: %#lx msize: %lu\n",
250*7c478bd9Sstevel@tonic-gate 		    (u_long)rp->re_cmap, (u_long)rp->re_smap,
251*7c478bd9Sstevel@tonic-gate 		    (u_long)rp->re_emap, (u_long)rp->re_msize);
252*7c478bd9Sstevel@tonic-gate 	}
253*7c478bd9Sstevel@tonic-gate 	(void)fprintf(fp, "ovflsize: %lu\n", (u_long)t->bt_ovflsize);
254*7c478bd9Sstevel@tonic-gate 	(void)fflush(fp);
255*7c478bd9Sstevel@tonic-gate 	return (dbc->c_close(dbc));
256*7c478bd9Sstevel@tonic-gate }
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate /*
259*7c478bd9Sstevel@tonic-gate  * __db_prhash --
260*7c478bd9Sstevel@tonic-gate  *	Print out the hash internal information.
261*7c478bd9Sstevel@tonic-gate  *
262*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_prhash __P((DB *));
263*7c478bd9Sstevel@tonic-gate  */
264*7c478bd9Sstevel@tonic-gate int
__db_prhash(dbp)265*7c478bd9Sstevel@tonic-gate __db_prhash(dbp)
266*7c478bd9Sstevel@tonic-gate 	DB *dbp;
267*7c478bd9Sstevel@tonic-gate {
268*7c478bd9Sstevel@tonic-gate 	FILE *fp;
269*7c478bd9Sstevel@tonic-gate 	DBC *dbc;
270*7c478bd9Sstevel@tonic-gate 	HASH_CURSOR *hcp;
271*7c478bd9Sstevel@tonic-gate 	int i, put_page, ret;
272*7c478bd9Sstevel@tonic-gate 	db_pgno_t pgno;
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate 	fp = __db_prinit(NULL);
275*7c478bd9Sstevel@tonic-gate 	if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
276*7c478bd9Sstevel@tonic-gate 		return (ret);
277*7c478bd9Sstevel@tonic-gate 	hcp = (HASH_CURSOR *)dbc->internal;
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate 	/*
280*7c478bd9Sstevel@tonic-gate 	 * In this case,  hcp->hdr will never be null, if we decide
281*7c478bd9Sstevel@tonic-gate 	 * to pass dbc's to this routine instead, then it could be.
282*7c478bd9Sstevel@tonic-gate 	 */
283*7c478bd9Sstevel@tonic-gate 	if (hcp->hdr == NULL) {
284*7c478bd9Sstevel@tonic-gate 		pgno = PGNO_METADATA;
285*7c478bd9Sstevel@tonic-gate 		if ((ret = memp_fget(dbp->mpf, &pgno, 0, &hcp->hdr)) != 0)
286*7c478bd9Sstevel@tonic-gate 			return (ret);
287*7c478bd9Sstevel@tonic-gate 		put_page = 1;
288*7c478bd9Sstevel@tonic-gate 	} else
289*7c478bd9Sstevel@tonic-gate 		put_page = 0;
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tmagic      %#lx\n", (u_long)hcp->hdr->magic);
292*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tversion    %lu\n", (u_long)hcp->hdr->version);
293*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tpagesize   %lu\n", (u_long)hcp->hdr->pagesize);
294*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tovfl_point %lu\n", (u_long)hcp->hdr->ovfl_point);
295*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tlast_freed %lu\n", (u_long)hcp->hdr->last_freed);
296*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tmax_bucket %lu\n", (u_long)hcp->hdr->max_bucket);
297*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\thigh_mask  %#lx\n", (u_long)hcp->hdr->high_mask);
298*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tlow_mask   %#lx\n", (u_long)hcp->hdr->low_mask);
299*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tffactor    %lu\n", (u_long)hcp->hdr->ffactor);
300*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\tnelem      %lu\n", (u_long)hcp->hdr->nelem);
301*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\th_charkey  %#lx\n", (u_long)hcp->hdr->h_charkey);
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NCACHED; i++)
304*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "%lu ", (u_long)hcp->hdr->spares[i]);
305*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n");
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate 	(void)fflush(fp);
308*7c478bd9Sstevel@tonic-gate 	if (put_page) {
309*7c478bd9Sstevel@tonic-gate 		(void)memp_fput(dbp->mpf, (PAGE *)hcp->hdr, 0);
310*7c478bd9Sstevel@tonic-gate 		hcp->hdr = NULL;
311*7c478bd9Sstevel@tonic-gate 	}
312*7c478bd9Sstevel@tonic-gate 	return (dbc->c_close(dbc));
313*7c478bd9Sstevel@tonic-gate }
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate /*
316*7c478bd9Sstevel@tonic-gate  * __db_prtree --
317*7c478bd9Sstevel@tonic-gate  *	Print out the entire tree.
318*7c478bd9Sstevel@tonic-gate  *
319*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_prtree __P((DB_MPOOLFILE *, int));
320*7c478bd9Sstevel@tonic-gate  */
321*7c478bd9Sstevel@tonic-gate int
__db_prtree(mpf,all)322*7c478bd9Sstevel@tonic-gate __db_prtree(mpf, all)
323*7c478bd9Sstevel@tonic-gate 	DB_MPOOLFILE *mpf;
324*7c478bd9Sstevel@tonic-gate 	int all;
325*7c478bd9Sstevel@tonic-gate {
326*7c478bd9Sstevel@tonic-gate 	PAGE *h;
327*7c478bd9Sstevel@tonic-gate 	db_pgno_t i;
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate 	if (set_psize == PSIZE_BOUNDARY)
330*7c478bd9Sstevel@tonic-gate 		__db_psize(mpf);
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate 	for (i = PGNO_ROOT;; ++i) {
333*7c478bd9Sstevel@tonic-gate 		if (memp_fget(mpf, &i, 0, &h) != 0)
334*7c478bd9Sstevel@tonic-gate 			break;
335*7c478bd9Sstevel@tonic-gate 		(void)__db_prpage(h, all);
336*7c478bd9Sstevel@tonic-gate 		(void)memp_fput(mpf, h, 0);
337*7c478bd9Sstevel@tonic-gate 	}
338*7c478bd9Sstevel@tonic-gate 	(void)fflush(__db_prinit(NULL));
339*7c478bd9Sstevel@tonic-gate 	return (0);
340*7c478bd9Sstevel@tonic-gate }
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate /*
343*7c478bd9Sstevel@tonic-gate  * __db_prnpage
344*7c478bd9Sstevel@tonic-gate  *	-- Print out a specific page.
345*7c478bd9Sstevel@tonic-gate  *
346*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_prnpage __P((DB_MPOOLFILE *, db_pgno_t));
347*7c478bd9Sstevel@tonic-gate  */
348*7c478bd9Sstevel@tonic-gate int
__db_prnpage(mpf,pgno)349*7c478bd9Sstevel@tonic-gate __db_prnpage(mpf, pgno)
350*7c478bd9Sstevel@tonic-gate 	DB_MPOOLFILE *mpf;
351*7c478bd9Sstevel@tonic-gate 	db_pgno_t pgno;
352*7c478bd9Sstevel@tonic-gate {
353*7c478bd9Sstevel@tonic-gate 	PAGE *h;
354*7c478bd9Sstevel@tonic-gate 	int ret;
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 	if (set_psize == PSIZE_BOUNDARY)
357*7c478bd9Sstevel@tonic-gate 		__db_psize(mpf);
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate 	if ((ret = memp_fget(mpf, &pgno, 0, &h)) != 0)
360*7c478bd9Sstevel@tonic-gate 		return (ret);
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 	ret = __db_prpage(h, 1);
363*7c478bd9Sstevel@tonic-gate 	(void)fflush(__db_prinit(NULL));
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 	(void)memp_fput(mpf, h, 0);
366*7c478bd9Sstevel@tonic-gate 	return (ret);
367*7c478bd9Sstevel@tonic-gate }
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate /*
370*7c478bd9Sstevel@tonic-gate  * __db_prpage
371*7c478bd9Sstevel@tonic-gate  *	-- Print out a page.
372*7c478bd9Sstevel@tonic-gate  *
373*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_prpage __P((PAGE *, int));
374*7c478bd9Sstevel@tonic-gate  */
375*7c478bd9Sstevel@tonic-gate int
__db_prpage(h,all)376*7c478bd9Sstevel@tonic-gate __db_prpage(h, all)
377*7c478bd9Sstevel@tonic-gate 	PAGE *h;
378*7c478bd9Sstevel@tonic-gate 	int all;
379*7c478bd9Sstevel@tonic-gate {
380*7c478bd9Sstevel@tonic-gate 	BINTERNAL *bi;
381*7c478bd9Sstevel@tonic-gate 	BKEYDATA *bk;
382*7c478bd9Sstevel@tonic-gate 	HOFFPAGE a_hkd;
383*7c478bd9Sstevel@tonic-gate 	FILE *fp;
384*7c478bd9Sstevel@tonic-gate 	RINTERNAL *ri;
385*7c478bd9Sstevel@tonic-gate 	db_indx_t dlen, len, i;
386*7c478bd9Sstevel@tonic-gate 	db_pgno_t pgno;
387*7c478bd9Sstevel@tonic-gate 	int deleted, ret;
388*7c478bd9Sstevel@tonic-gate 	const char *s;
389*7c478bd9Sstevel@tonic-gate 	u_int8_t *ep, *hk, *p;
390*7c478bd9Sstevel@tonic-gate 	void *sp;
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate 	fp = __db_prinit(NULL);
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate 	switch (TYPE(h)) {
395*7c478bd9Sstevel@tonic-gate 	case P_DUPLICATE:
396*7c478bd9Sstevel@tonic-gate 		s = "duplicate";
397*7c478bd9Sstevel@tonic-gate 		break;
398*7c478bd9Sstevel@tonic-gate 	case P_HASH:
399*7c478bd9Sstevel@tonic-gate 		s = "hash";
400*7c478bd9Sstevel@tonic-gate 		break;
401*7c478bd9Sstevel@tonic-gate 	case P_IBTREE:
402*7c478bd9Sstevel@tonic-gate 		s = "btree internal";
403*7c478bd9Sstevel@tonic-gate 		break;
404*7c478bd9Sstevel@tonic-gate 	case P_INVALID:
405*7c478bd9Sstevel@tonic-gate 		s = "invalid";
406*7c478bd9Sstevel@tonic-gate 		break;
407*7c478bd9Sstevel@tonic-gate 	case P_IRECNO:
408*7c478bd9Sstevel@tonic-gate 		s = "recno internal";
409*7c478bd9Sstevel@tonic-gate 		break;
410*7c478bd9Sstevel@tonic-gate 	case P_LBTREE:
411*7c478bd9Sstevel@tonic-gate 		s = "btree leaf";
412*7c478bd9Sstevel@tonic-gate 		break;
413*7c478bd9Sstevel@tonic-gate 	case P_LRECNO:
414*7c478bd9Sstevel@tonic-gate 		s = "recno leaf";
415*7c478bd9Sstevel@tonic-gate 		break;
416*7c478bd9Sstevel@tonic-gate 	case P_OVERFLOW:
417*7c478bd9Sstevel@tonic-gate 		s = "overflow";
418*7c478bd9Sstevel@tonic-gate 		break;
419*7c478bd9Sstevel@tonic-gate 	default:
420*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "ILLEGAL PAGE TYPE: page: %lu type: %lu\n",
421*7c478bd9Sstevel@tonic-gate 		    (u_long)h->pgno, (u_long)TYPE(h));
422*7c478bd9Sstevel@tonic-gate 			return (1);
423*7c478bd9Sstevel@tonic-gate 	}
424*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "page %4lu: (%s)\n", (u_long)h->pgno, s);
425*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "    lsn.file: %lu lsn.offset: %lu",
426*7c478bd9Sstevel@tonic-gate 	    (u_long)LSN(h).file, (u_long)LSN(h).offset);
427*7c478bd9Sstevel@tonic-gate 	if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO ||
428*7c478bd9Sstevel@tonic-gate 	    (TYPE(h) == P_LRECNO && h->pgno == PGNO_ROOT))
429*7c478bd9Sstevel@tonic-gate 		fprintf(fp, " total records: %4lu", (u_long)RE_NREC(h));
430*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n");
431*7c478bd9Sstevel@tonic-gate 	if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO)
432*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "    prev: %4lu next: %4lu",
433*7c478bd9Sstevel@tonic-gate 		    (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h));
434*7c478bd9Sstevel@tonic-gate 	if (TYPE(h) == P_IBTREE || TYPE(h) == P_LBTREE)
435*7c478bd9Sstevel@tonic-gate 		fprintf(fp, " level: %2lu", (u_long)h->level);
436*7c478bd9Sstevel@tonic-gate 	if (TYPE(h) == P_OVERFLOW) {
437*7c478bd9Sstevel@tonic-gate 		fprintf(fp, " ref cnt: %4lu ", (u_long)OV_REF(h));
438*7c478bd9Sstevel@tonic-gate 		__db_pr((u_int8_t *)h + P_OVERHEAD, OV_LEN(h));
439*7c478bd9Sstevel@tonic-gate 		return (0);
440*7c478bd9Sstevel@tonic-gate 	}
441*7c478bd9Sstevel@tonic-gate 	fprintf(fp, " entries: %4lu", (u_long)NUM_ENT(h));
442*7c478bd9Sstevel@tonic-gate 	fprintf(fp, " offset: %4lu\n", (u_long)HOFFSET(h));
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate 	if (!all || TYPE(h) == P_INVALID)
445*7c478bd9Sstevel@tonic-gate 		return (0);
446*7c478bd9Sstevel@tonic-gate 
447*7c478bd9Sstevel@tonic-gate 	ret = 0;
448*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NUM_ENT(h); i++) {
449*7c478bd9Sstevel@tonic-gate 		if (P_ENTRY(h, i) - (u_int8_t *)h < P_OVERHEAD ||
450*7c478bd9Sstevel@tonic-gate 		    (size_t)(P_ENTRY(h, i) - (u_int8_t *)h) >= set_psize) {
451*7c478bd9Sstevel@tonic-gate 			fprintf(fp,
452*7c478bd9Sstevel@tonic-gate 			    "ILLEGAL PAGE OFFSET: indx: %lu of %lu\n",
453*7c478bd9Sstevel@tonic-gate 			    (u_long)i, (u_long)h->inp[i]);
454*7c478bd9Sstevel@tonic-gate 			ret = EINVAL;
455*7c478bd9Sstevel@tonic-gate 			continue;
456*7c478bd9Sstevel@tonic-gate 		}
457*7c478bd9Sstevel@tonic-gate 		deleted = 0;
458*7c478bd9Sstevel@tonic-gate 		switch (TYPE(h)) {
459*7c478bd9Sstevel@tonic-gate 		case P_HASH:
460*7c478bd9Sstevel@tonic-gate 		case P_IBTREE:
461*7c478bd9Sstevel@tonic-gate 		case P_IRECNO:
462*7c478bd9Sstevel@tonic-gate 			sp = P_ENTRY(h, i);
463*7c478bd9Sstevel@tonic-gate 			break;
464*7c478bd9Sstevel@tonic-gate 		case P_LBTREE:
465*7c478bd9Sstevel@tonic-gate 			sp = P_ENTRY(h, i);
466*7c478bd9Sstevel@tonic-gate 			deleted = i % 2 == 0 &&
467*7c478bd9Sstevel@tonic-gate 			    B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type);
468*7c478bd9Sstevel@tonic-gate 			break;
469*7c478bd9Sstevel@tonic-gate 		case P_LRECNO:
470*7c478bd9Sstevel@tonic-gate 		case P_DUPLICATE:
471*7c478bd9Sstevel@tonic-gate 			sp = P_ENTRY(h, i);
472*7c478bd9Sstevel@tonic-gate 			deleted = B_DISSET(GET_BKEYDATA(h, i)->type);
473*7c478bd9Sstevel@tonic-gate 			break;
474*7c478bd9Sstevel@tonic-gate 		default:
475*7c478bd9Sstevel@tonic-gate 			fprintf(fp,
476*7c478bd9Sstevel@tonic-gate 			    "ILLEGAL PAGE ITEM: %lu\n", (u_long)TYPE(h));
477*7c478bd9Sstevel@tonic-gate 			ret = EINVAL;
478*7c478bd9Sstevel@tonic-gate 			continue;
479*7c478bd9Sstevel@tonic-gate 		}
480*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "   %s[%03lu] %4lu ",
481*7c478bd9Sstevel@tonic-gate 		    deleted ? "D" : " ", (u_long)i, (u_long)h->inp[i]);
482*7c478bd9Sstevel@tonic-gate 		switch (TYPE(h)) {
483*7c478bd9Sstevel@tonic-gate 		case P_HASH:
484*7c478bd9Sstevel@tonic-gate 			hk = sp;
485*7c478bd9Sstevel@tonic-gate 			switch (HPAGE_PTYPE(hk)) {
486*7c478bd9Sstevel@tonic-gate 			case H_OFFDUP:
487*7c478bd9Sstevel@tonic-gate 				memcpy(&pgno,
488*7c478bd9Sstevel@tonic-gate 				    HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
489*7c478bd9Sstevel@tonic-gate 				fprintf(fp,
490*7c478bd9Sstevel@tonic-gate 				    "%4lu [offpage dups]\n", (u_long)pgno);
491*7c478bd9Sstevel@tonic-gate 				break;
492*7c478bd9Sstevel@tonic-gate 			case H_DUPLICATE:
493*7c478bd9Sstevel@tonic-gate 				/*
494*7c478bd9Sstevel@tonic-gate 				 * If this is the first item on a page, then
495*7c478bd9Sstevel@tonic-gate 				 * we cannot figure out how long it is, so
496*7c478bd9Sstevel@tonic-gate 				 * we only print the first one in the duplicate
497*7c478bd9Sstevel@tonic-gate 				 * set.
498*7c478bd9Sstevel@tonic-gate 				 */
499*7c478bd9Sstevel@tonic-gate 				if (i != 0)
500*7c478bd9Sstevel@tonic-gate 					len = LEN_HKEYDATA(h, 0, i);
501*7c478bd9Sstevel@tonic-gate 				else
502*7c478bd9Sstevel@tonic-gate 					len = 1;
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "Duplicates:\n");
505*7c478bd9Sstevel@tonic-gate 				for (p = HKEYDATA_DATA(hk),
506*7c478bd9Sstevel@tonic-gate 				    ep = p + len; p < ep;) {
507*7c478bd9Sstevel@tonic-gate 					memcpy(&dlen, p, sizeof(db_indx_t));
508*7c478bd9Sstevel@tonic-gate 					p += sizeof(db_indx_t);
509*7c478bd9Sstevel@tonic-gate 					fprintf(fp, "\t\t");
510*7c478bd9Sstevel@tonic-gate 					__db_pr(p, dlen);
511*7c478bd9Sstevel@tonic-gate 					p += sizeof(db_indx_t) + dlen;
512*7c478bd9Sstevel@tonic-gate 				}
513*7c478bd9Sstevel@tonic-gate 				break;
514*7c478bd9Sstevel@tonic-gate 			case H_KEYDATA:
515*7c478bd9Sstevel@tonic-gate 				if (i != 0)
516*7c478bd9Sstevel@tonic-gate 					__db_pr(HKEYDATA_DATA(hk),
517*7c478bd9Sstevel@tonic-gate 					    LEN_HKEYDATA(h, 0, i));
518*7c478bd9Sstevel@tonic-gate 				else
519*7c478bd9Sstevel@tonic-gate 					fprintf(fp, "%s\n", HKEYDATA_DATA(hk));
520*7c478bd9Sstevel@tonic-gate 				break;
521*7c478bd9Sstevel@tonic-gate 			case H_OFFPAGE:
522*7c478bd9Sstevel@tonic-gate 				memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
523*7c478bd9Sstevel@tonic-gate 				fprintf(fp,
524*7c478bd9Sstevel@tonic-gate 				    "overflow: total len: %4lu page: %4lu\n",
525*7c478bd9Sstevel@tonic-gate 				    (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
526*7c478bd9Sstevel@tonic-gate 				break;
527*7c478bd9Sstevel@tonic-gate 			}
528*7c478bd9Sstevel@tonic-gate 			break;
529*7c478bd9Sstevel@tonic-gate 		case P_IBTREE:
530*7c478bd9Sstevel@tonic-gate 			bi = sp;
531*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "count: %4lu pgno: %4lu ",
532*7c478bd9Sstevel@tonic-gate 			    (u_long)bi->nrecs, (u_long)bi->pgno);
533*7c478bd9Sstevel@tonic-gate 			switch (B_TYPE(bi->type)) {
534*7c478bd9Sstevel@tonic-gate 			case B_KEYDATA:
535*7c478bd9Sstevel@tonic-gate 				__db_pr(bi->data, bi->len);
536*7c478bd9Sstevel@tonic-gate 				break;
537*7c478bd9Sstevel@tonic-gate 			case B_DUPLICATE:
538*7c478bd9Sstevel@tonic-gate 			case B_OVERFLOW:
539*7c478bd9Sstevel@tonic-gate 				__db_proff(bi->data);
540*7c478bd9Sstevel@tonic-gate 				break;
541*7c478bd9Sstevel@tonic-gate 			default:
542*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "ILLEGAL BINTERNAL TYPE: %lu\n",
543*7c478bd9Sstevel@tonic-gate 				    (u_long)B_TYPE(bi->type));
544*7c478bd9Sstevel@tonic-gate 				ret = EINVAL;
545*7c478bd9Sstevel@tonic-gate 				break;
546*7c478bd9Sstevel@tonic-gate 			}
547*7c478bd9Sstevel@tonic-gate 			break;
548*7c478bd9Sstevel@tonic-gate 		case P_IRECNO:
549*7c478bd9Sstevel@tonic-gate 			ri = sp;
550*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "entries %4lu pgno %4lu\n",
551*7c478bd9Sstevel@tonic-gate 			    (u_long)ri->nrecs, (u_long)ri->pgno);
552*7c478bd9Sstevel@tonic-gate 			break;
553*7c478bd9Sstevel@tonic-gate 		case P_LBTREE:
554*7c478bd9Sstevel@tonic-gate 		case P_LRECNO:
555*7c478bd9Sstevel@tonic-gate 		case P_DUPLICATE:
556*7c478bd9Sstevel@tonic-gate 			bk = sp;
557*7c478bd9Sstevel@tonic-gate 			switch (B_TYPE(bk->type)) {
558*7c478bd9Sstevel@tonic-gate 			case B_KEYDATA:
559*7c478bd9Sstevel@tonic-gate 				__db_pr(bk->data, bk->len);
560*7c478bd9Sstevel@tonic-gate 				break;
561*7c478bd9Sstevel@tonic-gate 			case B_DUPLICATE:
562*7c478bd9Sstevel@tonic-gate 			case B_OVERFLOW:
563*7c478bd9Sstevel@tonic-gate 				__db_proff(bk);
564*7c478bd9Sstevel@tonic-gate 				break;
565*7c478bd9Sstevel@tonic-gate 			default:
566*7c478bd9Sstevel@tonic-gate 				fprintf(fp,
567*7c478bd9Sstevel@tonic-gate 			    "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu\n",
568*7c478bd9Sstevel@tonic-gate 				    (u_long)B_TYPE(bk->type));
569*7c478bd9Sstevel@tonic-gate 				ret = EINVAL;
570*7c478bd9Sstevel@tonic-gate 				break;
571*7c478bd9Sstevel@tonic-gate 			}
572*7c478bd9Sstevel@tonic-gate 			break;
573*7c478bd9Sstevel@tonic-gate 		}
574*7c478bd9Sstevel@tonic-gate 	}
575*7c478bd9Sstevel@tonic-gate 	(void)fflush(fp);
576*7c478bd9Sstevel@tonic-gate 	return (ret);
577*7c478bd9Sstevel@tonic-gate }
578*7c478bd9Sstevel@tonic-gate 
579*7c478bd9Sstevel@tonic-gate /*
580*7c478bd9Sstevel@tonic-gate  * __db_isbad
581*7c478bd9Sstevel@tonic-gate  *	-- Decide if a page is corrupted.
582*7c478bd9Sstevel@tonic-gate  *
583*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_isbad __P((PAGE *, int));
584*7c478bd9Sstevel@tonic-gate  */
585*7c478bd9Sstevel@tonic-gate int
__db_isbad(h,die)586*7c478bd9Sstevel@tonic-gate __db_isbad(h, die)
587*7c478bd9Sstevel@tonic-gate 	PAGE *h;
588*7c478bd9Sstevel@tonic-gate 	int die;
589*7c478bd9Sstevel@tonic-gate {
590*7c478bd9Sstevel@tonic-gate 	BINTERNAL *bi;
591*7c478bd9Sstevel@tonic-gate 	BKEYDATA *bk;
592*7c478bd9Sstevel@tonic-gate 	FILE *fp;
593*7c478bd9Sstevel@tonic-gate 	db_indx_t i;
594*7c478bd9Sstevel@tonic-gate 	u_int type;
595*7c478bd9Sstevel@tonic-gate 
596*7c478bd9Sstevel@tonic-gate 	fp = __db_prinit(NULL);
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate 	switch (TYPE(h)) {
599*7c478bd9Sstevel@tonic-gate 	case P_DUPLICATE:
600*7c478bd9Sstevel@tonic-gate 	case P_HASH:
601*7c478bd9Sstevel@tonic-gate 	case P_IBTREE:
602*7c478bd9Sstevel@tonic-gate 	case P_INVALID:
603*7c478bd9Sstevel@tonic-gate 	case P_IRECNO:
604*7c478bd9Sstevel@tonic-gate 	case P_LBTREE:
605*7c478bd9Sstevel@tonic-gate 	case P_LRECNO:
606*7c478bd9Sstevel@tonic-gate 	case P_OVERFLOW:
607*7c478bd9Sstevel@tonic-gate 		break;
608*7c478bd9Sstevel@tonic-gate 	default:
609*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "ILLEGAL PAGE TYPE: page: %lu type: %lu\n",
610*7c478bd9Sstevel@tonic-gate 		    (u_long)h->pgno, (u_long)TYPE(h));
611*7c478bd9Sstevel@tonic-gate 		goto bad;
612*7c478bd9Sstevel@tonic-gate 	}
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NUM_ENT(h); i++) {
615*7c478bd9Sstevel@tonic-gate 		if (P_ENTRY(h, i) - (u_int8_t *)h < P_OVERHEAD ||
616*7c478bd9Sstevel@tonic-gate 		    (size_t)(P_ENTRY(h, i) - (u_int8_t *)h) >= set_psize) {
617*7c478bd9Sstevel@tonic-gate 			fprintf(fp,
618*7c478bd9Sstevel@tonic-gate 			    "ILLEGAL PAGE OFFSET: indx: %lu of %lu\n",
619*7c478bd9Sstevel@tonic-gate 			    (u_long)i, (u_long)h->inp[i]);
620*7c478bd9Sstevel@tonic-gate 			goto bad;
621*7c478bd9Sstevel@tonic-gate 		}
622*7c478bd9Sstevel@tonic-gate 		switch (TYPE(h)) {
623*7c478bd9Sstevel@tonic-gate 		case P_HASH:
624*7c478bd9Sstevel@tonic-gate 			type = HPAGE_TYPE(h, i);
625*7c478bd9Sstevel@tonic-gate 			if (type != H_OFFDUP &&
626*7c478bd9Sstevel@tonic-gate 			    type != H_DUPLICATE &&
627*7c478bd9Sstevel@tonic-gate 			    type != H_KEYDATA &&
628*7c478bd9Sstevel@tonic-gate 			    type != H_OFFPAGE) {
629*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "ILLEGAL HASH TYPE: %lu\n",
630*7c478bd9Sstevel@tonic-gate 				    (u_long)type);
631*7c478bd9Sstevel@tonic-gate 				goto bad;
632*7c478bd9Sstevel@tonic-gate 			}
633*7c478bd9Sstevel@tonic-gate 			break;
634*7c478bd9Sstevel@tonic-gate 		case P_IBTREE:
635*7c478bd9Sstevel@tonic-gate 			bi = GET_BINTERNAL(h, i);
636*7c478bd9Sstevel@tonic-gate 			if (B_TYPE(bi->type) != B_KEYDATA &&
637*7c478bd9Sstevel@tonic-gate 			    B_TYPE(bi->type) != B_DUPLICATE &&
638*7c478bd9Sstevel@tonic-gate 			    B_TYPE(bi->type) != B_OVERFLOW) {
639*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "ILLEGAL BINTERNAL TYPE: %lu\n",
640*7c478bd9Sstevel@tonic-gate 				    (u_long)B_TYPE(bi->type));
641*7c478bd9Sstevel@tonic-gate 				goto bad;
642*7c478bd9Sstevel@tonic-gate 			}
643*7c478bd9Sstevel@tonic-gate 			break;
644*7c478bd9Sstevel@tonic-gate 		case P_IRECNO:
645*7c478bd9Sstevel@tonic-gate 		case P_LBTREE:
646*7c478bd9Sstevel@tonic-gate 		case P_LRECNO:
647*7c478bd9Sstevel@tonic-gate 			break;
648*7c478bd9Sstevel@tonic-gate 		case P_DUPLICATE:
649*7c478bd9Sstevel@tonic-gate 			bk = GET_BKEYDATA(h, i);
650*7c478bd9Sstevel@tonic-gate 			if (B_TYPE(bk->type) != B_KEYDATA &&
651*7c478bd9Sstevel@tonic-gate 			    B_TYPE(bk->type) != B_DUPLICATE &&
652*7c478bd9Sstevel@tonic-gate 			    B_TYPE(bk->type) != B_OVERFLOW) {
653*7c478bd9Sstevel@tonic-gate 				fprintf(fp,
654*7c478bd9Sstevel@tonic-gate 			    "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu\n",
655*7c478bd9Sstevel@tonic-gate 				    (u_long)B_TYPE(bk->type));
656*7c478bd9Sstevel@tonic-gate 				goto bad;
657*7c478bd9Sstevel@tonic-gate 			}
658*7c478bd9Sstevel@tonic-gate 			break;
659*7c478bd9Sstevel@tonic-gate 		default:
660*7c478bd9Sstevel@tonic-gate 			fprintf(fp,
661*7c478bd9Sstevel@tonic-gate 			    "ILLEGAL PAGE ITEM: %lu\n", (u_long)TYPE(h));
662*7c478bd9Sstevel@tonic-gate 			goto bad;
663*7c478bd9Sstevel@tonic-gate 		}
664*7c478bd9Sstevel@tonic-gate 	}
665*7c478bd9Sstevel@tonic-gate 	return (0);
666*7c478bd9Sstevel@tonic-gate 
667*7c478bd9Sstevel@tonic-gate bad:	if (die) {
668*7c478bd9Sstevel@tonic-gate 		abort();
669*7c478bd9Sstevel@tonic-gate 		/* NOTREACHED */
670*7c478bd9Sstevel@tonic-gate 	}
671*7c478bd9Sstevel@tonic-gate 	return (1);
672*7c478bd9Sstevel@tonic-gate }
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate /*
675*7c478bd9Sstevel@tonic-gate  * __db_pr --
676*7c478bd9Sstevel@tonic-gate  *	Print out a data element.
677*7c478bd9Sstevel@tonic-gate  *
678*7c478bd9Sstevel@tonic-gate  * PUBLIC: void __db_pr __P((u_int8_t *, u_int32_t));
679*7c478bd9Sstevel@tonic-gate  */
680*7c478bd9Sstevel@tonic-gate void
__db_pr(p,len)681*7c478bd9Sstevel@tonic-gate __db_pr(p, len)
682*7c478bd9Sstevel@tonic-gate 	u_int8_t *p;
683*7c478bd9Sstevel@tonic-gate 	u_int32_t len;
684*7c478bd9Sstevel@tonic-gate {
685*7c478bd9Sstevel@tonic-gate 	FILE *fp;
686*7c478bd9Sstevel@tonic-gate 	u_int lastch;
687*7c478bd9Sstevel@tonic-gate 	int i;
688*7c478bd9Sstevel@tonic-gate 
689*7c478bd9Sstevel@tonic-gate 	fp = __db_prinit(NULL);
690*7c478bd9Sstevel@tonic-gate 
691*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "len: %3lu", (u_long)len);
692*7c478bd9Sstevel@tonic-gate 	lastch = '.';
693*7c478bd9Sstevel@tonic-gate 	if (len != 0) {
694*7c478bd9Sstevel@tonic-gate 		fprintf(fp, " data: ");
695*7c478bd9Sstevel@tonic-gate 		for (i = len <= 20 ? len : 20; i > 0; --i, ++p) {
696*7c478bd9Sstevel@tonic-gate 			lastch = *p;
697*7c478bd9Sstevel@tonic-gate 			if (isprint(*p) || *p == '\n')
698*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "%c", *p);
699*7c478bd9Sstevel@tonic-gate 			else
700*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "0x%.2x", (u_int)*p);
701*7c478bd9Sstevel@tonic-gate 		}
702*7c478bd9Sstevel@tonic-gate 		if (len > 20) {
703*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "...");
704*7c478bd9Sstevel@tonic-gate 			lastch = '.';
705*7c478bd9Sstevel@tonic-gate 		}
706*7c478bd9Sstevel@tonic-gate 	}
707*7c478bd9Sstevel@tonic-gate 	if (lastch != '\n')
708*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n");
709*7c478bd9Sstevel@tonic-gate }
710*7c478bd9Sstevel@tonic-gate 
711*7c478bd9Sstevel@tonic-gate /*
712*7c478bd9Sstevel@tonic-gate  * __db_prdbt --
713*7c478bd9Sstevel@tonic-gate  *	Print out a DBT data element.
714*7c478bd9Sstevel@tonic-gate  *
715*7c478bd9Sstevel@tonic-gate  * PUBLIC: int __db_prdbt __P((DBT *, int, FILE *));
716*7c478bd9Sstevel@tonic-gate  */
717*7c478bd9Sstevel@tonic-gate int
__db_prdbt(dbtp,checkprint,fp)718*7c478bd9Sstevel@tonic-gate __db_prdbt(dbtp, checkprint, fp)
719*7c478bd9Sstevel@tonic-gate 	DBT *dbtp;
720*7c478bd9Sstevel@tonic-gate 	int checkprint;
721*7c478bd9Sstevel@tonic-gate 	FILE *fp;
722*7c478bd9Sstevel@tonic-gate {
723*7c478bd9Sstevel@tonic-gate 	static const char hex[] = "0123456789abcdef";
724*7c478bd9Sstevel@tonic-gate 	u_int8_t *p;
725*7c478bd9Sstevel@tonic-gate 	u_int32_t len;
726*7c478bd9Sstevel@tonic-gate 
727*7c478bd9Sstevel@tonic-gate 	/*
728*7c478bd9Sstevel@tonic-gate 	 * !!!
729*7c478bd9Sstevel@tonic-gate 	 * This routine is the routine that dumps out items in the format
730*7c478bd9Sstevel@tonic-gate 	 * used by db_dump(1) and db_load(1).  This means that the format
731*7c478bd9Sstevel@tonic-gate 	 * cannot change.
732*7c478bd9Sstevel@tonic-gate 	 */
733*7c478bd9Sstevel@tonic-gate 	if (checkprint) {
734*7c478bd9Sstevel@tonic-gate 		for (len = dbtp->size, p = dbtp->data; len--; ++p)
735*7c478bd9Sstevel@tonic-gate 			if (isprint(*p)) {
736*7c478bd9Sstevel@tonic-gate 				if (*p == '\\' && fprintf(fp, "\\") != 1)
737*7c478bd9Sstevel@tonic-gate 					return (EIO);
738*7c478bd9Sstevel@tonic-gate 				if (fprintf(fp, "%c", *p) != 1)
739*7c478bd9Sstevel@tonic-gate 					return (EIO);
740*7c478bd9Sstevel@tonic-gate 			} else
741*7c478bd9Sstevel@tonic-gate 				if (fprintf(fp, "\\%c%c",
742*7c478bd9Sstevel@tonic-gate 				    hex[(u_int8_t)(*p & 0xf0) >> 4],
743*7c478bd9Sstevel@tonic-gate 				    hex[*p & 0x0f]) != 3)
744*7c478bd9Sstevel@tonic-gate 					return (EIO);
745*7c478bd9Sstevel@tonic-gate 	} else
746*7c478bd9Sstevel@tonic-gate 		for (len = dbtp->size, p = dbtp->data; len--; ++p)
747*7c478bd9Sstevel@tonic-gate 			if (fprintf(fp, "%c%c",
748*7c478bd9Sstevel@tonic-gate 			    hex[(u_int8_t)(*p & 0xf0) >> 4],
749*7c478bd9Sstevel@tonic-gate 			    hex[*p & 0x0f]) != 2)
750*7c478bd9Sstevel@tonic-gate 				return (EIO);
751*7c478bd9Sstevel@tonic-gate 
752*7c478bd9Sstevel@tonic-gate 	return (fprintf(fp, "\n") == 1 ? 0 : EIO);
753*7c478bd9Sstevel@tonic-gate }
754*7c478bd9Sstevel@tonic-gate 
755*7c478bd9Sstevel@tonic-gate /*
756*7c478bd9Sstevel@tonic-gate  * __db_proff --
757*7c478bd9Sstevel@tonic-gate  *	Print out an off-page element.
758*7c478bd9Sstevel@tonic-gate  */
759*7c478bd9Sstevel@tonic-gate static void
__db_proff(vp)760*7c478bd9Sstevel@tonic-gate __db_proff(vp)
761*7c478bd9Sstevel@tonic-gate 	void *vp;
762*7c478bd9Sstevel@tonic-gate {
763*7c478bd9Sstevel@tonic-gate 	FILE *fp;
764*7c478bd9Sstevel@tonic-gate 	BOVERFLOW *bo;
765*7c478bd9Sstevel@tonic-gate 
766*7c478bd9Sstevel@tonic-gate 	fp = __db_prinit(NULL);
767*7c478bd9Sstevel@tonic-gate 
768*7c478bd9Sstevel@tonic-gate 	bo = vp;
769*7c478bd9Sstevel@tonic-gate 	switch (B_TYPE(bo->type)) {
770*7c478bd9Sstevel@tonic-gate 	case B_OVERFLOW:
771*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "overflow: total len: %4lu page: %4lu\n",
772*7c478bd9Sstevel@tonic-gate 		    (u_long)bo->tlen, (u_long)bo->pgno);
773*7c478bd9Sstevel@tonic-gate 		break;
774*7c478bd9Sstevel@tonic-gate 	case B_DUPLICATE:
775*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "duplicate: page: %4lu\n", (u_long)bo->pgno);
776*7c478bd9Sstevel@tonic-gate 		break;
777*7c478bd9Sstevel@tonic-gate 	}
778*7c478bd9Sstevel@tonic-gate }
779*7c478bd9Sstevel@tonic-gate 
780*7c478bd9Sstevel@tonic-gate /*
781*7c478bd9Sstevel@tonic-gate  * __db_prflags --
782*7c478bd9Sstevel@tonic-gate  *	Print out flags values.
783*7c478bd9Sstevel@tonic-gate  *
784*7c478bd9Sstevel@tonic-gate  * PUBLIC: void __db_prflags __P((u_int32_t, const FN *, FILE *));
785*7c478bd9Sstevel@tonic-gate  */
786*7c478bd9Sstevel@tonic-gate void
__db_prflags(flags,fn,fp)787*7c478bd9Sstevel@tonic-gate __db_prflags(flags, fn, fp)
788*7c478bd9Sstevel@tonic-gate 	u_int32_t flags;
789*7c478bd9Sstevel@tonic-gate 	FN const *fn;
790*7c478bd9Sstevel@tonic-gate 	FILE *fp;
791*7c478bd9Sstevel@tonic-gate {
792*7c478bd9Sstevel@tonic-gate 	const FN *fnp;
793*7c478bd9Sstevel@tonic-gate 	int found;
794*7c478bd9Sstevel@tonic-gate 	const char *sep;
795*7c478bd9Sstevel@tonic-gate 
796*7c478bd9Sstevel@tonic-gate 	sep = " (";
797*7c478bd9Sstevel@tonic-gate 	for (found = 0, fnp = fn; fnp->mask != 0; ++fnp)
798*7c478bd9Sstevel@tonic-gate 		if (LF_ISSET(fnp->mask)) {
799*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "%s%s", sep, fnp->name);
800*7c478bd9Sstevel@tonic-gate 			sep = ", ";
801*7c478bd9Sstevel@tonic-gate 			found = 1;
802*7c478bd9Sstevel@tonic-gate 		}
803*7c478bd9Sstevel@tonic-gate 	if (found)
804*7c478bd9Sstevel@tonic-gate 		fprintf(fp, ")");
805*7c478bd9Sstevel@tonic-gate }
806*7c478bd9Sstevel@tonic-gate 
807*7c478bd9Sstevel@tonic-gate /*
808*7c478bd9Sstevel@tonic-gate  * __db_psize --
809*7c478bd9Sstevel@tonic-gate  *	Get the page size.
810*7c478bd9Sstevel@tonic-gate  */
811*7c478bd9Sstevel@tonic-gate static void
__db_psize(mpf)812*7c478bd9Sstevel@tonic-gate __db_psize(mpf)
813*7c478bd9Sstevel@tonic-gate 	DB_MPOOLFILE *mpf;
814*7c478bd9Sstevel@tonic-gate {
815*7c478bd9Sstevel@tonic-gate 	BTMETA *mp;
816*7c478bd9Sstevel@tonic-gate 	db_pgno_t pgno;
817*7c478bd9Sstevel@tonic-gate 
818*7c478bd9Sstevel@tonic-gate 	set_psize = PSIZE_BOUNDARY - 1;
819*7c478bd9Sstevel@tonic-gate 
820*7c478bd9Sstevel@tonic-gate 	pgno = PGNO_METADATA;
821*7c478bd9Sstevel@tonic-gate 	if (memp_fget(mpf, &pgno, 0, &mp) != 0)
822*7c478bd9Sstevel@tonic-gate 		return;
823*7c478bd9Sstevel@tonic-gate 
824*7c478bd9Sstevel@tonic-gate 	switch (mp->magic) {
825*7c478bd9Sstevel@tonic-gate 	case DB_BTREEMAGIC:
826*7c478bd9Sstevel@tonic-gate 	case DB_HASHMAGIC:
827*7c478bd9Sstevel@tonic-gate 		set_psize = mp->pagesize;
828*7c478bd9Sstevel@tonic-gate 		break;
829*7c478bd9Sstevel@tonic-gate 	}
830*7c478bd9Sstevel@tonic-gate 	(void)memp_fput(mpf, mp, 0);
831*7c478bd9Sstevel@tonic-gate }
832