00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014
00015 #include <ctype.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #endif
00019
00020 #include "db_int.h"
00021 #include "dbinc/db_page.h"
00022 #include "dbinc/db_shash.h"
00023 #include "dbinc/btree.h"
00024 #include "dbinc/hash.h"
00025 #include "dbinc/mp.h"
00026 #include "dbinc/qam.h"
00027 #include "dbinc/db_verify.h"
00028
00029
00030
00031
00032
00033
00034
00035 void
00036 __db_loadme()
00037 {
00038 pid_t pid;
00039 db_threadid_t tid;
00040
00041 __os_id(NULL, &pid, &tid);
00042 }
00043
00044 #ifdef HAVE_STATISTICS
00045 static int __db_bmeta __P((DB *, BTMETA *, u_int32_t));
00046 static int __db_hmeta __P((DB *, HMETA *, u_int32_t));
00047 static void __db_meta __P((DB *, DBMETA *, FN const *, u_int32_t));
00048 static const char *__db_pagetype_to_string __P((u_int32_t));
00049 static void __db_prdb __P((DB *, u_int32_t));
00050 static void __db_proff __P((DB_ENV *, DB_MSGBUF *, void *));
00051 static int __db_prtree __P((DB *, u_int32_t));
00052 static int __db_qmeta __P((DB *, QMETA *, u_int32_t));
00053
00054
00055
00056
00057
00058
00059
00060 int
00061 __db_dumptree(dbp, op, name)
00062 DB *dbp;
00063 char *op, *name;
00064 {
00065 DB_ENV *dbenv;
00066 FILE *fp, *orig_fp;
00067 u_int32_t flags;
00068 int ret;
00069
00070 dbenv = dbp->dbenv;
00071
00072 for (flags = 0; *op != '\0'; ++op)
00073 switch (*op) {
00074 case 'a':
00075 LF_SET(DB_PR_PAGE);
00076 break;
00077 case 'h':
00078 break;
00079 case 'r':
00080 LF_SET(DB_PR_RECOVERYTEST);
00081 break;
00082 default:
00083 return (EINVAL);
00084 }
00085
00086 if (name != NULL) {
00087 if ((fp = fopen(name, "w")) == NULL)
00088 return (__os_get_errno());
00089
00090 orig_fp = dbenv->db_msgfile;
00091 dbenv->db_msgfile = fp;
00092 } else
00093 fp = orig_fp = NULL;
00094
00095 __db_prdb(dbp, flags);
00096
00097 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00098
00099 ret = __db_prtree(dbp, flags);
00100
00101 if (fp != NULL) {
00102 (void)fclose(fp);
00103 dbenv->db_msgfile = orig_fp;
00104 }
00105
00106 return (ret);
00107 }
00108
00109 static const FN __db_flags_fn[] = {
00110 { DB_AM_CHKSUM, "checksumming" },
00111 { DB_AM_CL_WRITER, "client replica writer" },
00112 { DB_AM_COMPENSATE, "created by compensating transaction" },
00113 { DB_AM_CREATED, "database created" },
00114 { DB_AM_CREATED_MSTR, "encompassing file created" },
00115 { DB_AM_DBM_ERROR, "dbm/ndbm error" },
00116 { DB_AM_DELIMITER, "variable length" },
00117 { DB_AM_DISCARD, "discard cached pages" },
00118 { DB_AM_DUP, "duplicates" },
00119 { DB_AM_DUPSORT, "sorted duplicates" },
00120 { DB_AM_ENCRYPT, "encrypted" },
00121 { DB_AM_FIXEDLEN, "fixed-length records" },
00122 { DB_AM_INMEM, "in-memory" },
00123 { DB_AM_IN_RENAME, "file is being renamed" },
00124 { DB_AM_NOT_DURABLE, "changes not logged" },
00125 { DB_AM_OPEN_CALLED, "open called" },
00126 { DB_AM_PAD, "pad value" },
00127 { DB_AM_PGDEF, "default page size" },
00128 { DB_AM_RDONLY, "read-only" },
00129 { DB_AM_READ_UNCOMMITTED, "read-uncommitted" },
00130 { DB_AM_RECNUM, "Btree record numbers" },
00131 { DB_AM_RECOVER, "opened for recovery" },
00132 { DB_AM_RENUMBER, "renumber" },
00133 { DB_AM_REVSPLITOFF, "no reverse splits" },
00134 { DB_AM_SECONDARY, "secondary" },
00135 { DB_AM_SNAPSHOT, "load on open" },
00136 { DB_AM_SUBDB, "subdatabases" },
00137 { DB_AM_SWAP, "needswap" },
00138 { DB_AM_TXN, "transactional" },
00139 { DB_AM_VERIFYING, "verifier" },
00140 { 0, NULL }
00141 };
00142
00143
00144
00145
00146
00147
00148
00149 const FN *
00150 __db_get_flags_fn()
00151 {
00152 return (__db_flags_fn);
00153 }
00154
00155
00156
00157
00158
00159 static void
00160 __db_prdb(dbp, flags)
00161 DB *dbp;
00162 u_int32_t flags;
00163 {
00164 DB_MSGBUF mb;
00165 DB_ENV *dbenv;
00166 BTREE *bt;
00167 HASH *h;
00168 QUEUE *q;
00169
00170 dbenv = dbp->dbenv;
00171
00172 DB_MSGBUF_INIT(&mb);
00173 __db_msg(dbenv, "In-memory DB structure:");
00174 __db_msgadd(dbenv, &mb, "%s: %#lx",
00175 __db_dbtype_to_string(dbp->type), (u_long)dbp->flags);
00176 __db_prflags(dbenv, &mb, dbp->flags, __db_flags_fn, " (", ")");
00177 DB_MSGBUF_FLUSH(dbenv, &mb);
00178
00179 switch (dbp->type) {
00180 case DB_BTREE:
00181 case DB_RECNO:
00182 bt = dbp->bt_internal;
00183 __db_msg(dbenv, "bt_meta: %lu bt_root: %lu",
00184 (u_long)bt->bt_meta, (u_long)bt->bt_root);
00185 __db_msg(dbenv, "bt_minkey: %lu", (u_long)bt->bt_minkey);
00186 if (!LF_ISSET(DB_PR_RECOVERYTEST))
00187 __db_msg(dbenv, "bt_compare: %#lx bt_prefix: %#lx",
00188 P_TO_ULONG(bt->bt_compare),
00189 P_TO_ULONG(bt->bt_prefix));
00190 __db_msg(dbenv, "bt_lpgno: %lu", (u_long)bt->bt_lpgno);
00191 if (dbp->type == DB_RECNO) {
00192 __db_msg(dbenv,
00193 "re_pad: %#lx re_delim: %#lx re_len: %lu re_source: %s",
00194 (u_long)bt->re_pad, (u_long)bt->re_delim,
00195 (u_long)bt->re_len,
00196 bt->re_source == NULL ? "" : bt->re_source);
00197 __db_msg(dbenv,
00198 "re_modified: %d re_eof: %d re_last: %lu",
00199 bt->re_modified, bt->re_eof, (u_long)bt->re_last);
00200 }
00201 break;
00202 case DB_HASH:
00203 h = dbp->h_internal;
00204 __db_msg(dbenv, "meta_pgno: %lu", (u_long)h->meta_pgno);
00205 __db_msg(dbenv, "h_ffactor: %lu", (u_long)h->h_ffactor);
00206 __db_msg(dbenv, "h_nelem: %lu", (u_long)h->h_nelem);
00207 if (!LF_ISSET(DB_PR_RECOVERYTEST))
00208 __db_msg(dbenv, "h_hash: %#lx", P_TO_ULONG(h->h_hash));
00209 break;
00210 case DB_QUEUE:
00211 q = dbp->q_internal;
00212 __db_msg(dbenv, "q_meta: %lu", (u_long)q->q_meta);
00213 __db_msg(dbenv, "q_root: %lu", (u_long)q->q_root);
00214 __db_msg(dbenv, "re_pad: %#lx re_len: %lu",
00215 (u_long)q->re_pad, (u_long)q->re_len);
00216 __db_msg(dbenv, "rec_page: %lu", (u_long)q->rec_page);
00217 __db_msg(dbenv, "page_ext: %lu", (u_long)q->page_ext);
00218 break;
00219 case DB_UNKNOWN:
00220 default:
00221 break;
00222 }
00223 }
00224
00225
00226
00227
00228
00229 static int
00230 __db_prtree(dbp, flags)
00231 DB *dbp;
00232 u_int32_t flags;
00233 {
00234 DB_MPOOLFILE *mpf;
00235 PAGE *h;
00236 db_pgno_t i, last;
00237 int ret;
00238
00239 mpf = dbp->mpf;
00240
00241 if (dbp->type == DB_QUEUE)
00242 return (__db_prqueue(dbp, flags));
00243
00244
00245
00246
00247
00248 if ((ret = __memp_last_pgno(mpf, &last)) != 0)
00249 return (ret);
00250 for (i = 0; i <= last; ++i) {
00251 if ((ret = __memp_fget(mpf, &i, 0, &h)) != 0)
00252 return (ret);
00253 (void)__db_prpage(dbp, h, flags);
00254 if ((ret = __memp_fput(mpf, h, 0)) != 0)
00255 return (ret);
00256 }
00257
00258 return (0);
00259 }
00260
00261
00262
00263
00264
00265 static void
00266 __db_meta(dbp, dbmeta, fn, flags)
00267 DB *dbp;
00268 DBMETA *dbmeta;
00269 FN const *fn;
00270 u_int32_t flags;
00271 {
00272 DB_MSGBUF mb;
00273 DB_ENV *dbenv;
00274 DB_MPOOLFILE *mpf;
00275 PAGE *h;
00276 db_pgno_t pgno;
00277 u_int8_t *p;
00278 int cnt, ret;
00279 const char *sep;
00280
00281 dbenv = dbp->dbenv;
00282 mpf = dbp->mpf;
00283 DB_MSGBUF_INIT(&mb);
00284
00285 __db_msg(dbenv, "\tmagic: %#lx", (u_long)dbmeta->magic);
00286 __db_msg(dbenv, "\tversion: %lu", (u_long)dbmeta->version);
00287 __db_msg(dbenv, "\tpagesize: %lu", (u_long)dbmeta->pagesize);
00288 __db_msg(dbenv, "\ttype: %lu", (u_long)dbmeta->type);
00289 __db_msg(dbenv, "\tkeys: %lu\trecords: %lu",
00290 (u_long)dbmeta->key_count, (u_long)dbmeta->record_count);
00291
00292
00293
00294
00295
00296 if (!LF_ISSET(DB_PR_RECOVERYTEST)) {
00297 __db_msgadd(
00298 dbenv, &mb, "\tfree list: %lu", (u_long)dbmeta->free);
00299 for (pgno = dbmeta->free,
00300 cnt = 0, sep = ", "; pgno != PGNO_INVALID;) {
00301 if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) {
00302 DB_MSGBUF_FLUSH(dbenv, &mb);
00303 __db_msg(dbenv,
00304 "Unable to retrieve free-list page: %lu: %s",
00305 (u_long)pgno, db_strerror(ret));
00306 break;
00307 }
00308 pgno = h->next_pgno;
00309 (void)__memp_fput(mpf, h, 0);
00310 __db_msgadd(dbenv, &mb, "%s%lu", sep, (u_long)pgno);
00311 if (++cnt % 10 == 0) {
00312 DB_MSGBUF_FLUSH(dbenv, &mb);
00313 cnt = 0;
00314 sep = "\t";
00315 } else
00316 sep = ", ";
00317 }
00318 DB_MSGBUF_FLUSH(dbenv, &mb);
00319 __db_msg(dbenv, "\tlast_pgno: %lu", (u_long)dbmeta->last_pgno);
00320 }
00321
00322 if (fn != NULL) {
00323 DB_MSGBUF_FLUSH(dbenv, &mb);
00324 __db_msgadd(dbenv, &mb, "\tflags: %#lx", (u_long)dbmeta->flags);
00325 __db_prflags(dbenv, &mb, dbmeta->flags, fn, " (", ")");
00326 }
00327
00328 DB_MSGBUF_FLUSH(dbenv, &mb);
00329 __db_msgadd(dbenv, &mb, "\tuid: ");
00330 for (p = (u_int8_t *)dbmeta->uid,
00331 cnt = 0; cnt < DB_FILE_ID_LEN; ++cnt) {
00332 __db_msgadd(dbenv, &mb, "%x", *p++);
00333 if (cnt < DB_FILE_ID_LEN - 1)
00334 __db_msgadd(dbenv, &mb, " ");
00335 }
00336 DB_MSGBUF_FLUSH(dbenv, &mb);
00337 }
00338
00339
00340
00341
00342
00343 static int
00344 __db_bmeta(dbp, h, flags)
00345 DB *dbp;
00346 BTMETA *h;
00347 u_int32_t flags;
00348 {
00349 static const FN fn[] = {
00350 { BTM_DUP, "duplicates" },
00351 { BTM_RECNO, "recno" },
00352 { BTM_RECNUM, "btree:recnum" },
00353 { BTM_FIXEDLEN, "recno:fixed-length" },
00354 { BTM_RENUMBER, "recno:renumber" },
00355 { BTM_SUBDB, "multiple-databases" },
00356 { BTM_DUPSORT, "sorted duplicates" },
00357 { 0, NULL }
00358 };
00359 DB_ENV *dbenv;
00360
00361 dbenv = dbp->dbenv;
00362
00363 __db_meta(dbp, (DBMETA *)h, fn, flags);
00364
00365 __db_msg(dbenv, "\tminkey: %lu", (u_long)h->minkey);
00366 if (dbp->type == DB_RECNO)
00367 __db_msg(dbenv, "\tre_len: %#lx re_pad: %#lx",
00368 (u_long)h->re_len, (u_long)h->re_pad);
00369 __db_msg(dbenv, "\troot: %lu", (u_long)h->root);
00370
00371 return (0);
00372 }
00373
00374
00375
00376
00377
00378 static int
00379 __db_hmeta(dbp, h, flags)
00380 DB *dbp;
00381 HMETA *h;
00382 u_int32_t flags;
00383 {
00384 DB_MSGBUF mb;
00385 static const FN fn[] = {
00386 { DB_HASH_DUP, "duplicates" },
00387 { DB_HASH_SUBDB, "multiple-databases" },
00388 { DB_HASH_DUPSORT, "sorted duplicates" },
00389 { 0, NULL }
00390 };
00391 DB_ENV *dbenv;
00392 int i;
00393
00394 dbenv = dbp->dbenv;
00395 DB_MSGBUF_INIT(&mb);
00396
00397 __db_meta(dbp, (DBMETA *)h, fn, flags);
00398
00399 __db_msg(dbenv, "\tmax_bucket: %lu", (u_long)h->max_bucket);
00400 __db_msg(dbenv, "\thigh_mask: %#lx", (u_long)h->high_mask);
00401 __db_msg(dbenv, "\tlow_mask: %#lx", (u_long)h->low_mask);
00402 __db_msg(dbenv, "\tffactor: %lu", (u_long)h->ffactor);
00403 __db_msg(dbenv, "\tnelem: %lu", (u_long)h->nelem);
00404 __db_msg(dbenv, "\th_charkey: %#lx", (u_long)h->h_charkey);
00405 __db_msgadd(dbenv, &mb, "\tspare points: ");
00406 for (i = 0; i < NCACHED; i++)
00407 __db_msgadd(dbenv, &mb, "%lu ", (u_long)h->spares[i]);
00408 DB_MSGBUF_FLUSH(dbenv, &mb);
00409
00410 return (0);
00411 }
00412
00413
00414
00415
00416
00417 static int
00418 __db_qmeta(dbp, h, flags)
00419 DB *dbp;
00420 QMETA *h;
00421 u_int32_t flags;
00422 {
00423 DB_ENV *dbenv;
00424
00425 dbenv = dbp->dbenv;
00426
00427 __db_meta(dbp, (DBMETA *)h, NULL, flags);
00428
00429 __db_msg(dbenv, "\tfirst_recno: %lu", (u_long)h->first_recno);
00430 __db_msg(dbenv, "\tcur_recno: %lu", (u_long)h->cur_recno);
00431 __db_msg(dbenv, "\tre_len: %#lx re_pad: %lu",
00432 (u_long)h->re_len, (u_long)h->re_pad);
00433 __db_msg(dbenv, "\trec_page: %lu", (u_long)h->rec_page);
00434 __db_msg(dbenv, "\tpage_ext: %lu", (u_long)h->page_ext);
00435
00436 return (0);
00437 }
00438
00439
00440
00441
00442
00443
00444
00445 int
00446 __db_prnpage(dbp, pgno)
00447 DB *dbp;
00448 db_pgno_t pgno;
00449 {
00450 DB_MPOOLFILE *mpf;
00451 PAGE *h;
00452 int ret, t_ret;
00453
00454 mpf = dbp->mpf;
00455
00456 if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
00457 return (ret);
00458
00459 ret = __db_prpage(dbp, h, DB_PR_PAGE);
00460
00461 if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
00462 ret = t_ret;
00463
00464 return (ret);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473 int
00474 __db_prpage(dbp, h, flags)
00475 DB *dbp;
00476 PAGE *h;
00477 u_int32_t flags;
00478 {
00479 BINTERNAL *bi;
00480 BKEYDATA *bk;
00481 DB_ENV *dbenv;
00482 DB_MSGBUF mb;
00483 HOFFPAGE a_hkd;
00484 QAMDATA *qp, *qep;
00485 RINTERNAL *ri;
00486 db_indx_t dlen, len, i, *inp;
00487 db_pgno_t pgno;
00488 db_recno_t recno;
00489 u_int32_t pagesize, qlen;
00490 u_int8_t *ep, *hk, *p;
00491 int deleted, ret;
00492 const char *s;
00493 void *sp;
00494
00495 dbenv = dbp->dbenv;
00496 DB_MSGBUF_INIT(&mb);
00497
00498
00499
00500
00501
00502 if (LF_ISSET(DB_PR_RECOVERYTEST) && TYPE(h) == P_INVALID)
00503 return (0);
00504
00505 if ((s = __db_pagetype_to_string(TYPE(h))) == NULL) {
00506 __db_msg(dbenv, "ILLEGAL PAGE TYPE: page: %lu type: %lu",
00507 (u_long)h->pgno, (u_long)TYPE(h));
00508 return (1);
00509 }
00510
00511
00512
00513
00514
00515
00516
00517 pagesize = (u_int32_t)dbp->mpf->mfp->stat.st_pagesize;
00518
00519
00520 __db_msgadd(dbenv, &mb, "page %lu: %s:", (u_long)h->pgno, s);
00521
00522
00523
00524
00525
00526 if (!LF_ISSET(DB_PR_RECOVERYTEST) ||
00527 (TYPE(h) != P_BTREEMETA && TYPE(h) != P_HASHMETA &&
00528 TYPE(h) != P_QAMMETA && TYPE(h) != P_QAMDATA))
00529 __db_msgadd(dbenv, &mb, " LSN [%lu][%lu]:",
00530 (u_long)LSN(h).file, (u_long)LSN(h).offset);
00531
00532
00533
00534
00535
00536 __db_msgadd(dbenv, &mb, " level %lu", (u_long)h->level);
00537
00538
00539 if (TYPE(h) == P_IBTREE ||
00540 TYPE(h) == P_IRECNO || (TYPE(h) == P_LRECNO &&
00541 h->pgno == ((BTREE *)dbp->bt_internal)->bt_root))
00542 __db_msgadd(dbenv, &mb, " records: %lu", (u_long)RE_NREC(h));
00543 DB_MSGBUF_FLUSH(dbenv, &mb);
00544
00545 switch (TYPE(h)) {
00546 case P_BTREEMETA:
00547 return (__db_bmeta(dbp, (BTMETA *)h, flags));
00548 case P_HASHMETA:
00549 return (__db_hmeta(dbp, (HMETA *)h, flags));
00550 case P_QAMMETA:
00551 return (__db_qmeta(dbp, (QMETA *)h, flags));
00552 case P_QAMDATA:
00553 if (!LF_ISSET(DB_PR_PAGE))
00554 return (0);
00555
00556 qlen = ((QUEUE *)dbp->q_internal)->re_len;
00557 recno = (h->pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1;
00558 i = 0;
00559 qep = (QAMDATA *)((u_int8_t *)h + pagesize - qlen);
00560 for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep;
00561 recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) {
00562 if (!F_ISSET(qp, QAM_SET))
00563 continue;
00564
00565 __db_msgadd(dbenv, &mb, "%s",
00566 F_ISSET(qp, QAM_VALID) ? "\t" : " D");
00567 __db_msgadd(dbenv, &mb, "[%03lu] %4lu ", (u_long)recno,
00568 (u_long)((u_int8_t *)qp - (u_int8_t *)h));
00569 __db_pr(dbenv, &mb, qp->data, qlen);
00570 }
00571 return (0);
00572 default:
00573 break;
00574 }
00575
00576 s = "\t";
00577 if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) {
00578 __db_msgadd(dbenv, &mb, "%sprev: %4lu next: %4lu",
00579 s, (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h));
00580 s = " ";
00581 }
00582 if (TYPE(h) == P_OVERFLOW) {
00583 __db_msgadd(dbenv, &mb,
00584 "%sref cnt: %4lu ", s, (u_long)OV_REF(h));
00585 __db_pr(dbenv, &mb, (u_int8_t *)h + P_OVERHEAD(dbp), OV_LEN(h));
00586 return (0);
00587 }
00588 __db_msgadd(dbenv, &mb, "%sentries: %4lu", s, (u_long)NUM_ENT(h));
00589 __db_msgadd(dbenv, &mb, " offset: %4lu", (u_long)HOFFSET(h));
00590 DB_MSGBUF_FLUSH(dbenv, &mb);
00591
00592 if (TYPE(h) == P_INVALID || !LF_ISSET(DB_PR_PAGE))
00593 return (0);
00594
00595 ret = 0;
00596 inp = P_INP(dbp, h);
00597 for (i = 0; i < NUM_ENT(h); i++) {
00598 if ((uintptr_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) <
00599 (uintptr_t)(P_OVERHEAD(dbp)) ||
00600 (size_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) >= pagesize) {
00601 __db_msg(dbenv,
00602 "ILLEGAL PAGE OFFSET: indx: %lu of %lu",
00603 (u_long)i, (u_long)inp[i]);
00604 ret = EINVAL;
00605 continue;
00606 }
00607 deleted = 0;
00608 switch (TYPE(h)) {
00609 case P_HASH:
00610 case P_IBTREE:
00611 case P_IRECNO:
00612 sp = P_ENTRY(dbp, h, i);
00613 break;
00614 case P_LBTREE:
00615 sp = P_ENTRY(dbp, h, i);
00616 deleted = i % 2 == 0 &&
00617 B_DISSET(GET_BKEYDATA(dbp, h, i + O_INDX)->type);
00618 break;
00619 case P_LDUP:
00620 case P_LRECNO:
00621 sp = P_ENTRY(dbp, h, i);
00622 deleted = B_DISSET(GET_BKEYDATA(dbp, h, i)->type);
00623 break;
00624 default:
00625 goto type_err;
00626 }
00627 __db_msgadd(dbenv, &mb, "%s", deleted ? " D" : "\t");
00628 __db_msgadd(
00629 dbenv, &mb, "[%03lu] %4lu ", (u_long)i, (u_long)inp[i]);
00630 switch (TYPE(h)) {
00631 case P_HASH:
00632 hk = sp;
00633 switch (HPAGE_PTYPE(hk)) {
00634 case H_OFFDUP:
00635 memcpy(&pgno,
00636 HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
00637 __db_msgadd(dbenv, &mb,
00638 "%4lu [offpage dups]", (u_long)pgno);
00639 DB_MSGBUF_FLUSH(dbenv, &mb);
00640 break;
00641 case H_DUPLICATE:
00642
00643
00644
00645
00646
00647
00648 if (i != 0)
00649 len = LEN_HKEYDATA(dbp, h, 0, i);
00650 else
00651 len = 1;
00652
00653 __db_msgadd(dbenv, &mb, "Duplicates:");
00654 DB_MSGBUF_FLUSH(dbenv, &mb);
00655 for (p = HKEYDATA_DATA(hk),
00656 ep = p + len; p < ep;) {
00657 memcpy(&dlen, p, sizeof(db_indx_t));
00658 p += sizeof(db_indx_t);
00659 __db_msgadd(dbenv, &mb, "\t\t");
00660 __db_pr(dbenv, &mb, p, dlen);
00661 p += sizeof(db_indx_t) + dlen;
00662 }
00663 break;
00664 case H_KEYDATA:
00665 __db_pr(dbenv, &mb, HKEYDATA_DATA(hk),
00666 LEN_HKEYDATA(dbp, h, i == 0 ?
00667 pagesize : 0, i));
00668 break;
00669 case H_OFFPAGE:
00670 memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
00671 __db_msgadd(dbenv, &mb,
00672 "overflow: total len: %4lu page: %4lu",
00673 (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
00674 DB_MSGBUF_FLUSH(dbenv, &mb);
00675 break;
00676 default:
00677 DB_MSGBUF_FLUSH(dbenv, &mb);
00678 __db_msg(dbenv, "ILLEGAL HASH PAGE TYPE: %lu",
00679 (u_long)HPAGE_PTYPE(hk));
00680 ret = EINVAL;
00681 break;
00682 }
00683 break;
00684 case P_IBTREE:
00685 bi = sp;
00686 __db_msgadd(dbenv, &mb,
00687 "count: %4lu pgno: %4lu type: %lu ",
00688 (u_long)bi->nrecs, (u_long)bi->pgno,
00689 (u_long)bi->type);
00690 switch (B_TYPE(bi->type)) {
00691 case B_KEYDATA:
00692 __db_pr(dbenv, &mb, bi->data, bi->len);
00693 break;
00694 case B_DUPLICATE:
00695 case B_OVERFLOW:
00696 __db_proff(dbenv, &mb, bi->data);
00697 break;
00698 default:
00699 DB_MSGBUF_FLUSH(dbenv, &mb);
00700 __db_msg(dbenv, "ILLEGAL BINTERNAL TYPE: %lu",
00701 (u_long)B_TYPE(bi->type));
00702 ret = EINVAL;
00703 break;
00704 }
00705 break;
00706 case P_IRECNO:
00707 ri = sp;
00708 __db_msgadd(dbenv, &mb, "entries %4lu pgno %4lu",
00709 (u_long)ri->nrecs, (u_long)ri->pgno);
00710 DB_MSGBUF_FLUSH(dbenv, &mb);
00711 break;
00712 case P_LBTREE:
00713 case P_LDUP:
00714 case P_LRECNO:
00715 bk = sp;
00716 switch (B_TYPE(bk->type)) {
00717 case B_KEYDATA:
00718 __db_pr(dbenv, &mb, bk->data, bk->len);
00719 break;
00720 case B_DUPLICATE:
00721 case B_OVERFLOW:
00722 __db_proff(dbenv, &mb, bk);
00723 break;
00724 default:
00725 DB_MSGBUF_FLUSH(dbenv, &mb);
00726 __db_msg(dbenv,
00727 "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu",
00728 (u_long)B_TYPE(bk->type));
00729 ret = EINVAL;
00730 break;
00731 }
00732 break;
00733 default:
00734 type_err: DB_MSGBUF_FLUSH(dbenv, &mb);
00735 __db_msg(dbenv,
00736 "ILLEGAL PAGE TYPE: %lu", (u_long)TYPE(h));
00737 ret = EINVAL;
00738 continue;
00739 }
00740 }
00741 return (ret);
00742 }
00743
00744
00745
00746
00747
00748
00749
00750 void
00751 __db_pr(dbenv, mbp, p, len)
00752 DB_ENV *dbenv;
00753 DB_MSGBUF *mbp;
00754 u_int8_t *p;
00755 u_int32_t len;
00756 {
00757 u_int32_t i;
00758
00759 __db_msgadd(dbenv, mbp, "len: %3lu", (u_long)len);
00760 if (len != 0) {
00761 __db_msgadd(dbenv, mbp, " data: ");
00762 for (i = len <= 20 ? len : 20; i > 0; --i, ++p) {
00763 if (isprint((int)*p) || *p == '\n')
00764 __db_msgadd(dbenv, mbp, "%c", *p);
00765 else
00766 __db_msgadd(dbenv, mbp, "%#.2x", (u_int)*p);
00767 }
00768 if (len > 20)
00769 __db_msgadd(dbenv, mbp, "...");
00770 }
00771 DB_MSGBUF_FLUSH(dbenv, mbp);
00772 }
00773
00774
00775
00776
00777
00778 static void
00779 __db_proff(dbenv, mbp, vp)
00780 DB_ENV *dbenv;
00781 DB_MSGBUF *mbp;
00782 void *vp;
00783 {
00784 BOVERFLOW *bo;
00785
00786 bo = vp;
00787 switch (B_TYPE(bo->type)) {
00788 case B_OVERFLOW:
00789 __db_msgadd(dbenv, mbp, "overflow: total len: %4lu page: %4lu",
00790 (u_long)bo->tlen, (u_long)bo->pgno);
00791 break;
00792 case B_DUPLICATE:
00793 __db_msgadd(
00794 dbenv, mbp, "duplicate: page: %4lu", (u_long)bo->pgno);
00795 break;
00796 default:
00797
00798 break;
00799 }
00800 DB_MSGBUF_FLUSH(dbenv, mbp);
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810 void
00811 __db_prflags(dbenv, mbp, flags, fn, prefix, suffix)
00812 DB_ENV *dbenv;
00813 DB_MSGBUF *mbp;
00814 u_int32_t flags;
00815 FN const *fn;
00816 const char *prefix, *suffix;
00817 {
00818 DB_MSGBUF mb;
00819 const FN *fnp;
00820 int found, standalone;
00821 const char *sep;
00822
00823
00824
00825
00826
00827
00828 if (mbp == NULL) {
00829 standalone = 1;
00830 mbp = &mb;
00831 DB_MSGBUF_INIT(mbp);
00832 } else
00833 standalone = 0;
00834
00835 sep = prefix == NULL ? "" : prefix;
00836 for (found = 0, fnp = fn; fnp->mask != 0; ++fnp)
00837 if (LF_ISSET(fnp->mask)) {
00838 __db_msgadd(dbenv, mbp, "%s%s", sep, fnp->name);
00839 sep = ", ";
00840 found = 1;
00841 }
00842
00843 if ((standalone || found) && suffix != NULL)
00844 __db_msgadd(dbenv, mbp, "%s", suffix);
00845 if (standalone)
00846 DB_MSGBUF_FLUSH(dbenv, mbp);
00847 }
00848
00849
00850
00851
00852
00853
00854
00855 const char *
00856 __db_lockmode_to_string(mode)
00857 db_lockmode_t mode;
00858 {
00859 switch (mode) {
00860 case DB_LOCK_NG:
00861 return ("Not granted");
00862 case DB_LOCK_READ:
00863 return ("Shared/read");
00864 case DB_LOCK_WRITE:
00865 return ("Exclusive/write");
00866 case DB_LOCK_WAIT:
00867 return ("Wait for event");
00868 case DB_LOCK_IWRITE:
00869 return ("Intent exclusive/write");
00870 case DB_LOCK_IREAD:
00871 return ("Intent shared/read");
00872 case DB_LOCK_IWR:
00873 return ("Intent to read/write");
00874 case DB_LOCK_READ_UNCOMMITTED:
00875 return ("Read uncommitted");
00876 case DB_LOCK_WWRITE:
00877 return ("Was written");
00878 default:
00879 break;
00880 }
00881 return ("UNKNOWN LOCK MODE");
00882 }
00883
00884
00885
00886
00887
00888 static const char *
00889 __db_pagetype_to_string(type)
00890 u_int32_t type;
00891 {
00892 char *s;
00893
00894 s = NULL;
00895 switch (type) {
00896 case P_BTREEMETA:
00897 s = "btree metadata";
00898 break;
00899 case P_LDUP:
00900 s = "duplicate";
00901 break;
00902 case P_HASH:
00903 s = "hash";
00904 break;
00905 case P_HASHMETA:
00906 s = "hash metadata";
00907 break;
00908 case P_IBTREE:
00909 s = "btree internal";
00910 break;
00911 case P_INVALID:
00912 s = "invalid";
00913 break;
00914 case P_IRECNO:
00915 s = "recno internal";
00916 break;
00917 case P_LBTREE:
00918 s = "btree leaf";
00919 break;
00920 case P_LRECNO:
00921 s = "recno leaf";
00922 break;
00923 case P_OVERFLOW:
00924 s = "overflow";
00925 break;
00926 case P_QAMMETA:
00927 s = "queue metadata";
00928 break;
00929 case P_QAMDATA:
00930 s = "queue";
00931 break;
00932 default:
00933
00934 break;
00935 }
00936 return (s);
00937 }
00938
00939 #else
00940
00941
00942
00943
00944
00945
00946
00947 int
00948 __db_dumptree(dbp, op, name)
00949 DB *dbp;
00950 char *op, *name;
00951 {
00952 COMPQUIET(op, NULL);
00953 COMPQUIET(name, NULL);
00954
00955 return (__db_stat_not_built(dbp->dbenv));
00956 }
00957
00958
00959
00960
00961
00962
00963
00964 const FN *
00965 __db_get_flags_fn()
00966 {
00967 static const FN __db_flags_fn[] = {
00968 { 0, NULL }
00969 };
00970
00971
00972
00973
00974
00975 return (__db_flags_fn);
00976 }
00977 #endif
00978
00979
00980
00981
00982
00983
00984
00985
00986 int
00987 __db_dump_pp(dbp, subname, callback, handle, pflag, keyflag)
00988 DB *dbp;
00989 const char *subname;
00990 int (*callback) __P((void *, const void *));
00991 void *handle;
00992 int pflag, keyflag;
00993 {
00994 DB_ENV *dbenv;
00995 DB_THREAD_INFO *ip;
00996 int handle_check, ret, t_ret;
00997
00998 dbenv = dbp->dbenv;
00999
01000 PANIC_CHECK(dbenv);
01001 DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->dump");
01002
01003 ENV_ENTER(dbenv, ip);
01004
01005
01006 handle_check = IS_ENV_REPLICATED(dbenv);
01007 if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 1)) != 0) {
01008 handle_check = 0;
01009 goto err;
01010 }
01011
01012 ret = __db_dump(dbp, subname, callback, handle, pflag, keyflag);
01013
01014
01015 if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
01016 ret = t_ret;
01017
01018 err: ENV_LEAVE(dbenv, ip);
01019 return (ret);
01020 }
01021
01022
01023
01024
01025
01026
01027
01028
01029 int
01030 __db_dump(dbp, subname, callback, handle, pflag, keyflag)
01031 DB *dbp;
01032 const char *subname;
01033 int (*callback) __P((void *, const void *));
01034 void *handle;
01035 int pflag, keyflag;
01036 {
01037 DB_ENV *dbenv;
01038 DBC *dbcp;
01039 DBT key, data;
01040 DBT keyret, dataret;
01041 db_recno_t recno;
01042 int is_recno, ret, t_ret;
01043 void *pointer;
01044
01045 dbenv = dbp->dbenv;
01046
01047 if ((ret = __db_prheader(
01048 dbp, subname, pflag, keyflag, handle, callback, NULL, 0)) != 0)
01049 return (ret);
01050
01051
01052
01053
01054
01055 if ((ret = __db_cursor(dbp, NULL, &dbcp, 0)) != 0)
01056 return (ret);
01057
01058 memset(&key, 0, sizeof(key));
01059 memset(&data, 0, sizeof(data));
01060 if ((ret = __os_malloc(dbenv, 1024 * 1024, &data.data)) != 0)
01061 goto err;
01062 data.ulen = 1024 * 1024;
01063 data.flags = DB_DBT_USERMEM;
01064 is_recno = (dbp->type == DB_RECNO || dbp->type == DB_QUEUE);
01065 keyflag = is_recno ? keyflag : 1;
01066 if (is_recno) {
01067 keyret.data = &recno;
01068 keyret.size = sizeof(recno);
01069 }
01070
01071 retry: while ((ret =
01072 __db_c_get(dbcp, &key, &data, DB_NEXT | DB_MULTIPLE_KEY)) == 0) {
01073 DB_MULTIPLE_INIT(pointer, &data);
01074 for (;;) {
01075 if (is_recno)
01076 DB_MULTIPLE_RECNO_NEXT(pointer, &data,
01077 recno, dataret.data, dataret.size);
01078 else
01079 DB_MULTIPLE_KEY_NEXT(pointer,
01080 &data, keyret.data,
01081 keyret.size, dataret.data, dataret.size);
01082
01083 if (dataret.data == NULL)
01084 break;
01085
01086 if ((keyflag &&
01087 (ret = __db_prdbt(&keyret, pflag, " ",
01088 handle, callback, is_recno)) != 0) ||
01089 (ret = __db_prdbt(&dataret, pflag, " ",
01090 handle, callback, 0)) != 0)
01091 goto err;
01092 }
01093 }
01094 if (ret == DB_BUFFER_SMALL) {
01095 data.size = (u_int32_t)DB_ALIGN(data.size, 1024);
01096 if ((ret = __os_realloc(dbenv, data.size, &data.data)) != 0)
01097 goto err;
01098 data.ulen = data.size;
01099 goto retry;
01100 }
01101 if (ret == DB_NOTFOUND)
01102 ret = 0;
01103
01104 if ((t_ret = __db_prfooter(handle, callback)) != 0 && ret == 0)
01105 ret = t_ret;
01106
01107 err: if ((t_ret = __db_c_close(dbcp)) != 0 && ret == 0)
01108 ret = t_ret;
01109 if (data.data != NULL)
01110 __os_free(dbenv, data.data);
01111
01112 return (ret);
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122 int
01123 __db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno)
01124 DBT *dbtp;
01125 int checkprint;
01126 const char *prefix;
01127 void *handle;
01128 int (*callback) __P((void *, const void *));
01129 int is_recno;
01130 {
01131 static const u_char hex[] = "0123456789abcdef";
01132 db_recno_t recno;
01133 size_t len;
01134 int ret;
01135 #define DBTBUFLEN 100
01136 u_int8_t *p, *hp;
01137 char buf[DBTBUFLEN], hbuf[DBTBUFLEN];
01138
01139
01140
01141
01142
01143
01144
01145 if (prefix != NULL && (ret = callback(handle, prefix)) != 0)
01146 return (ret);
01147 if (is_recno) {
01148
01149
01150
01151
01152
01153 (void)__ua_memcpy(&recno, dbtp->data, sizeof(recno));
01154 snprintf(buf, DBTBUFLEN, "%lu", (u_long)recno);
01155
01156
01157 if (!checkprint) {
01158 for (len = strlen(buf), p = (u_int8_t *)buf,
01159 hp = (u_int8_t *)hbuf; len-- > 0; ++p) {
01160 *hp++ = hex[(u_int8_t)(*p & 0xf0) >> 4];
01161 *hp++ = hex[*p & 0x0f];
01162 }
01163 *hp = '\0';
01164 ret = callback(handle, hbuf);
01165 } else
01166 ret = callback(handle, buf);
01167
01168 if (ret != 0)
01169 return (ret);
01170 } else if (checkprint) {
01171 for (len = dbtp->size, p = dbtp->data; len--; ++p)
01172 if (isprint((int)*p)) {
01173 if (*p == '\\' &&
01174 (ret = callback(handle, "\\")) != 0)
01175 return (ret);
01176 snprintf(buf, DBTBUFLEN, "%c", *p);
01177 if ((ret = callback(handle, buf)) != 0)
01178 return (ret);
01179 } else {
01180 snprintf(buf, DBTBUFLEN, "\\%c%c",
01181 hex[(u_int8_t)(*p & 0xf0) >> 4],
01182 hex[*p & 0x0f]);
01183 if ((ret = callback(handle, buf)) != 0)
01184 return (ret);
01185 }
01186 } else
01187 for (len = dbtp->size, p = dbtp->data; len--; ++p) {
01188 snprintf(buf, DBTBUFLEN, "%c%c",
01189 hex[(u_int8_t)(*p & 0xf0) >> 4],
01190 hex[*p & 0x0f]);
01191 if ((ret = callback(handle, buf)) != 0)
01192 return (ret);
01193 }
01194
01195 return (callback(handle, "\n"));
01196 }
01197
01198
01199
01200
01201
01202
01203
01204
01205 int
01206 __db_prheader(dbp, subname, pflag, keyflag, handle, callback, vdp, meta_pgno)
01207 DB *dbp;
01208 const char *subname;
01209 int pflag, keyflag;
01210 void *handle;
01211 int (*callback) __P((void *, const void *));
01212 VRFY_DBINFO *vdp;
01213 db_pgno_t meta_pgno;
01214 {
01215 DBT dbt;
01216 DB_ENV *dbenv;
01217 DBTYPE dbtype;
01218 VRFY_PAGEINFO *pip;
01219 u_int32_t flags, tmp_u_int32;
01220 size_t buflen;
01221 char *buf;
01222 int using_vdp, ret, t_ret, tmp_int;
01223
01224 ret = 0;
01225 buf = NULL;
01226 COMPQUIET(buflen, 0);
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236 DB_ASSERT(dbp != NULL || vdp != NULL);
01237
01238 if (dbp == NULL)
01239 dbenv = NULL;
01240 else
01241 dbenv = dbp->dbenv;
01242
01243
01244
01245
01246
01247
01248
01249
01250 if (vdp != NULL) {
01251 if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0)
01252 return (ret);
01253
01254 if (F_ISSET(vdp, SALVAGE_PRINTABLE))
01255 pflag = 1;
01256 using_vdp = 1;
01257 } else {
01258 pip = NULL;
01259 using_vdp = 0;
01260 }
01261
01262
01263
01264
01265
01266 if (dbp == NULL)
01267 dbtype = DB_BTREE;
01268 else if (using_vdp)
01269 switch (pip->type) {
01270 case P_BTREEMETA:
01271 if (F_ISSET(pip, VRFY_IS_RECNO))
01272 dbtype = DB_RECNO;
01273 else
01274 dbtype = DB_BTREE;
01275 break;
01276 case P_HASHMETA:
01277 dbtype = DB_HASH;
01278 break;
01279 case P_QAMMETA:
01280 dbtype = DB_QUEUE;
01281 break;
01282 default:
01283
01284
01285
01286
01287
01288
01289 DB_ASSERT(F_ISSET(dbp, DB_AM_VERIFYING));
01290 dbtype = DB_BTREE;
01291 break;
01292 }
01293 else
01294 dbtype = dbp->type;
01295
01296 if ((ret = callback(handle, "VERSION=3\n")) != 0)
01297 goto err;
01298 if (pflag) {
01299 if ((ret = callback(handle, "format=print\n")) != 0)
01300 goto err;
01301 } else if ((ret = callback(handle, "format=bytevalue\n")) != 0)
01302 goto err;
01303
01304
01305
01306
01307
01308
01309 buflen = 64;
01310 if ((ret = __os_malloc(dbenv, buflen, &buf)) != 0)
01311 goto err;
01312 if (subname != NULL) {
01313 snprintf(buf, buflen, "database=");
01314 if ((ret = callback(handle, buf)) != 0)
01315 goto err;
01316 memset(&dbt, 0, sizeof(dbt));
01317 dbt.data = (char *)subname;
01318 dbt.size = (u_int32_t)strlen(subname);
01319 if ((ret = __db_prdbt(&dbt, 1, NULL, handle, callback, 0)) != 0)
01320 goto err;
01321 }
01322 switch (dbtype) {
01323 case DB_BTREE:
01324 if ((ret = callback(handle, "type=btree\n")) != 0)
01325 goto err;
01326 if (using_vdp)
01327 tmp_int = F_ISSET(pip, VRFY_HAS_RECNUMS) ? 1 : 0;
01328 else {
01329 if ((ret = __db_get_flags(dbp, &flags)) != 0) {
01330 __db_err(dbenv,
01331 "DB->get_flags: %s", db_strerror(ret));
01332 goto err;
01333 }
01334 tmp_int = F_ISSET(dbp, DB_AM_RECNUM) ? 1 : 0;
01335 }
01336 if (tmp_int && (ret = callback(handle, "recnum=1\n")) != 0)
01337 goto err;
01338
01339 if (using_vdp)
01340 tmp_u_int32 = pip->bt_minkey;
01341 else
01342 if ((ret =
01343 __bam_get_bt_minkey(dbp, &tmp_u_int32)) != 0) {
01344 __db_err(dbenv,
01345 "DB->get_bt_minkey: %s", db_strerror(ret));
01346 goto err;
01347 }
01348 if (tmp_u_int32 != 0 && tmp_u_int32 != DEFMINKEYPAGE) {
01349 snprintf(buf, buflen,
01350 "bt_minkey=%lu\n", (u_long)tmp_u_int32);
01351 if ((ret = callback(handle, buf)) != 0)
01352 goto err;
01353 }
01354 break;
01355 case DB_HASH:
01356 #ifdef HAVE_HASH
01357 if ((ret = callback(handle, "type=hash\n")) != 0)
01358 goto err;
01359 if (using_vdp)
01360 tmp_u_int32 = pip->h_ffactor;
01361 else
01362 if ((ret =
01363 __ham_get_h_ffactor(dbp, &tmp_u_int32)) != 0) {
01364 __db_err(dbenv,
01365 "DB->get_h_ffactor: %s", db_strerror(ret));
01366 goto err;
01367 }
01368 if (tmp_u_int32 != 0) {
01369 snprintf(buf, buflen,
01370 "h_ffactor=%lu\n", (u_long)tmp_u_int32);
01371 if ((ret = callback(handle, buf)) != 0)
01372 goto err;
01373 }
01374
01375 if (using_vdp)
01376 tmp_u_int32 = pip->h_nelem;
01377 else
01378 if ((ret = __ham_get_h_nelem(dbp, &tmp_u_int32)) != 0) {
01379 __db_err(dbenv,
01380 "DB->get_h_nelem: %s", db_strerror(ret));
01381 goto err;
01382 }
01383
01384
01385
01386
01387 if (tmp_u_int32 > 1) {
01388 snprintf(buf, buflen,
01389 "h_nelem=%lu\n", (u_long)tmp_u_int32);
01390 if ((ret = callback(handle, buf)) != 0)
01391 goto err;
01392 }
01393 break;
01394 #else
01395 ret = __db_no_hash_am(dbenv);
01396 goto err;
01397 #endif
01398 case DB_QUEUE:
01399 #ifdef HAVE_QUEUE
01400 if ((ret = callback(handle, "type=queue\n")) != 0)
01401 goto err;
01402 if (using_vdp)
01403 tmp_u_int32 = vdp->re_len;
01404 else
01405 if ((ret = __ram_get_re_len(dbp, &tmp_u_int32)) != 0) {
01406 __db_err(dbenv,
01407 "DB->get_re_len: %s", db_strerror(ret));
01408 goto err;
01409 }
01410 snprintf(buf, buflen, "re_len=%lu\n", (u_long)tmp_u_int32);
01411 if ((ret = callback(handle, buf)) != 0)
01412 goto err;
01413
01414 if (using_vdp)
01415 tmp_int = (int)vdp->re_pad;
01416 else
01417 if ((ret = __ram_get_re_pad(dbp, &tmp_int)) != 0) {
01418 __db_err(dbenv,
01419 "DB->get_re_pad: %s", db_strerror(ret));
01420 goto err;
01421 }
01422 if (tmp_int != 0 && tmp_int != ' ') {
01423 snprintf(buf, buflen, "re_pad=%#x\n", tmp_int);
01424 if ((ret = callback(handle, buf)) != 0)
01425 goto err;
01426 }
01427
01428 if (using_vdp)
01429 tmp_u_int32 = vdp->page_ext;
01430 else
01431 if ((ret =
01432 __qam_get_extentsize(dbp, &tmp_u_int32)) != 0) {
01433 __db_err(dbenv, "DB->get_q_extentsize: %s",
01434 db_strerror(ret));
01435 goto err;
01436 }
01437 if (tmp_u_int32 != 0) {
01438 snprintf(buf, buflen,
01439 "extentsize=%lu\n", (u_long)tmp_u_int32);
01440 if ((ret = callback(handle, buf)) != 0)
01441 goto err;
01442 }
01443 break;
01444 #else
01445 ret = __db_no_queue_am(dbenv);
01446 goto err;
01447 #endif
01448 case DB_RECNO:
01449 if ((ret = callback(handle, "type=recno\n")) != 0)
01450 goto err;
01451 if (using_vdp)
01452 tmp_int = F_ISSET(pip, VRFY_IS_RRECNO) ? 1 : 0;
01453 else
01454 tmp_int = F_ISSET(dbp, DB_AM_RENUMBER) ? 1 : 0;
01455 if (tmp_int != 0 &&
01456 (ret = callback(handle, "renumber=1\n")) != 0)
01457 goto err;
01458
01459 if (using_vdp)
01460 tmp_int = F_ISSET(pip, VRFY_IS_FIXEDLEN) ? 1 : 0;
01461 else
01462 tmp_int = F_ISSET(dbp, DB_AM_FIXEDLEN) ? 1 : 0;
01463 if (tmp_int) {
01464 if (using_vdp)
01465 tmp_u_int32 = pip->re_len;
01466 else
01467 if ((ret =
01468 __ram_get_re_len(dbp, &tmp_u_int32)) != 0) {
01469 __db_err(dbenv, "DB->get_re_len: %s",
01470 db_strerror(ret));
01471 goto err;
01472 }
01473 snprintf(buf, buflen,
01474 "re_len=%lu\n", (u_long)tmp_u_int32);
01475 if ((ret = callback(handle, buf)) != 0)
01476 goto err;
01477
01478 if (using_vdp)
01479 tmp_int = (int)pip->re_pad;
01480 else
01481 if ((ret =
01482 __ram_get_re_pad(dbp, &tmp_int)) != 0) {
01483 __db_err(dbenv, "DB->get_re_pad: %s",
01484 db_strerror(ret));
01485 goto err;
01486 }
01487 if (tmp_int != 0 && tmp_int != ' ') {
01488 snprintf(buf,
01489 buflen, "re_pad=%#x\n", (u_int)tmp_int);
01490 if ((ret = callback(handle, buf)) != 0)
01491 goto err;
01492 }
01493 }
01494 break;
01495 case DB_UNKNOWN:
01496 DB_ASSERT(0);
01497 __db_err(dbenv,
01498 "Unknown or unsupported DB type in __db_prheader");
01499 ret = EINVAL;
01500 goto err;
01501 }
01502
01503 if (using_vdp) {
01504 if (F_ISSET(pip, VRFY_HAS_CHKSUM))
01505 if ((ret = callback(handle, "chksum=1\n")) != 0)
01506 goto err;
01507 if (F_ISSET(pip, VRFY_HAS_DUPS))
01508 if ((ret = callback(handle, "duplicates=1\n")) != 0)
01509 goto err;
01510 if (F_ISSET(pip, VRFY_HAS_DUPSORT))
01511 if ((ret = callback(handle, "dupsort=1\n")) != 0)
01512 goto err;
01513
01514
01515
01516
01517
01518
01519 } else {
01520 if (F_ISSET(dbp, DB_AM_CHKSUM))
01521 if ((ret = callback(handle, "chksum=1\n")) != 0)
01522 goto err;
01523 if (F_ISSET(dbp, DB_AM_DUP))
01524 if ((ret = callback(handle, "duplicates=1\n")) != 0)
01525 goto err;
01526 if (F_ISSET(dbp, DB_AM_DUPSORT))
01527 if ((ret = callback(handle, "dupsort=1\n")) != 0)
01528 goto err;
01529 if (!F_ISSET(dbp, DB_AM_PGDEF)) {
01530 snprintf(buf, buflen,
01531 "db_pagesize=%lu\n", (u_long)dbp->pgsize);
01532 if ((ret = callback(handle, buf)) != 0)
01533 goto err;
01534 }
01535 }
01536
01537 if (keyflag && (ret = callback(handle, "keys=1\n")) != 0)
01538 goto err;
01539
01540 ret = callback(handle, "HEADER=END\n");
01541
01542 err: if (using_vdp &&
01543 (t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
01544 ret = t_ret;
01545 if (buf != NULL)
01546 __os_free(dbenv, buf);
01547
01548 return (ret);
01549 }
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559 int
01560 __db_prfooter(handle, callback)
01561 void *handle;
01562 int (*callback) __P((void *, const void *));
01563 {
01564 return (callback(handle, "DATA=END\n"));
01565 }
01566
01567
01568
01569
01570
01571
01572
01573 int
01574 __db_pr_callback(handle, str_arg)
01575 void *handle;
01576 const void *str_arg;
01577 {
01578 char *str;
01579 FILE *f;
01580
01581 str = (char *)str_arg;
01582 f = (FILE *)handle;
01583
01584 if (fprintf(f, "%s", str) != (int)strlen(str))
01585 return (EIO);
01586
01587 return (0);
01588 }
01589
01590
01591
01592
01593
01594
01595
01596 const char *
01597 __db_dbtype_to_string(type)
01598 DBTYPE type;
01599 {
01600 switch (type) {
01601 case DB_BTREE:
01602 return ("btree");
01603 case DB_HASH:
01604 return ("hash");
01605 case DB_RECNO:
01606 return ("recno");
01607 case DB_QUEUE:
01608 return ("queue");
01609 case DB_UNKNOWN:
01610 default:
01611 break;
01612 }
01613 return ("UNKNOWN TYPE");
01614 }