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