00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__pr_8c-source.html,v 1.1 2008/06/08 10:18:09 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <ctype.h>
00018 #include <errno.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #endif
00023
00024 #include "db_int.h"
00025 #include "db_page.h"
00026 #include "btree.h"
00027 #include "hash.h"
00028 #include "qam.h"
00029 #include "db_am.h"
00030 #include "db_verify.h"
00031
00032 static int __db_bmeta __P((DB *, FILE *, BTMETA *, u_int32_t));
00033 static int __db_hmeta __P((DB *, FILE *, HMETA *, u_int32_t));
00034 static void __db_meta __P((DB *, DBMETA *, FILE *, FN const *, u_int32_t));
00035 static const char *__db_dbtype_to_string __P((DB *));
00036 static void __db_prdb __P((DB *, FILE *, u_int32_t));
00037 static FILE *__db_prinit __P((FILE *));
00038 static void __db_proff __P((void *));
00039 static int __db_prtree __P((DB *, u_int32_t));
00040 static void __db_psize __P((DB *));
00041 static int __db_qmeta __P((DB *, FILE *, QMETA *, u_int32_t));
00042
00043
00044
00045
00046
00047 #define PSIZE_BOUNDARY (64 * 1024 + 1)
00048 static size_t set_psize = PSIZE_BOUNDARY;
00049
00050 static FILE *set_fp;
00051
00052
00053
00054
00055
00056
00057
00058 void
00059 CDB___db_loadme()
00060 {
00061 getpid();
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 int
00071 CDB___db_dump(dbp, op, name)
00072 DB *dbp;
00073 char *op, *name;
00074 {
00075 FILE *fp, *save_fp;
00076 u_int32_t flags;
00077
00078 COMPQUIET(save_fp, NULL);
00079
00080 if (set_psize == PSIZE_BOUNDARY)
00081 __db_psize(dbp);
00082
00083 if (name != NULL) {
00084 if ((fp = fopen(name, "w")) == NULL)
00085 return (CDB___os_get_errno());
00086 save_fp = set_fp;
00087 set_fp = fp;
00088 } else
00089 fp = __db_prinit(NULL);
00090
00091 for (flags = 0; *op != '\0'; ++op)
00092 switch (*op) {
00093 case 'a':
00094 LF_SET(DB_PR_PAGE);
00095 break;
00096 case 'h':
00097 break;
00098 case 'r':
00099 LF_SET(DB_PR_RECOVERYTEST);
00100 break;
00101 default:
00102 return (EINVAL);
00103 }
00104
00105 __db_prdb(dbp, fp, flags);
00106
00107 fprintf(fp, "%s\n", DB_LINE);
00108
00109 (void)__db_prtree(dbp, flags);
00110
00111 fflush(fp);
00112
00113 if (name != NULL) {
00114 fclose(fp);
00115 set_fp = save_fp;
00116 }
00117 return (0);
00118 }
00119
00120
00121
00122
00123
00124 static void
00125 __db_prdb(dbp, fp, flags)
00126 DB *dbp;
00127 FILE *fp;
00128 u_int32_t flags;
00129 {
00130 static const FN fn[] = {
00131 { DB_AM_DISCARD, "discard cached pages" },
00132 { DB_AM_DUP, "duplicates" },
00133 { DB_AM_INMEM, "in-memory" },
00134 { DB_AM_PGDEF, "default page size" },
00135 { DB_AM_RDONLY, "read-only" },
00136 { DB_AM_SUBDB, "multiple-databases" },
00137 { DB_AM_SWAP, "needswap" },
00138 { DB_BT_RECNUM, "btree:recnum" },
00139 { DB_BT_REVSPLIT, "btree:no reverse split" },
00140 { DB_DBM_ERROR, "dbm/ndbm error" },
00141 { DB_OPEN_CALLED, "DB->open called" },
00142 { DB_RE_DELIMITER, "recno:delimiter" },
00143 { DB_RE_FIXEDLEN, "recno:fixed-length" },
00144 { DB_RE_PAD, "recno:pad" },
00145 { DB_RE_RENUMBER, "recno:renumber" },
00146 { DB_RE_SNAPSHOT, "recno:snapshot" },
00147 { 0, NULL }
00148 };
00149 static const FN bfn[] = {
00150 { RECNO_MODIFIED, "recno:modified" },
00151 { RECNO_READFILE, "recno:readfile" },
00152 { 0, NULL }
00153 };
00154 BTREE *bt;
00155 HASH *h;
00156 QUEUE *q;
00157
00158 COMPQUIET(flags, 0);
00159
00160 fprintf(fp,
00161 "In-memory DB structure:\n%s: %#lx",
00162 __db_dbtype_to_string(dbp), (u_long)dbp->flags);
00163 CDB___db_prflags(dbp->flags, fn, fp);
00164 fprintf(fp, "\n");
00165
00166 switch (dbp->type) {
00167 case DB_BTREE:
00168 case DB_RECNO:
00169 bt = dbp->bt_internal;
00170 fprintf(fp, "bt_lpgno: %lu\n", (u_long)bt->bt_lpgno);
00171 fprintf(fp, "bt_meta: %lu: bt_root: %lu\n",
00172 (u_long)bt->bt_meta, (u_long)bt->bt_root);
00173 fprintf(fp, "bt_maxkey: %lu bt_minkey: %lu\n",
00174 (u_long)bt->bt_maxkey, (u_long)bt->bt_minkey);
00175 fprintf(fp, "bt_compare: %#lx bt_prefix: %#lx\n",
00176 (u_long)bt->bt_compare, (u_long)bt->bt_prefix);
00177 if (dbp->type == DB_RECNO) {
00178 fprintf(fp,
00179 "re_pad: %#lx re_delim: %#lx re_len: %lu re_source: %s\n",
00180 (u_long)bt->re_pad, (u_long)bt->re_delim,
00181 (u_long)bt->re_len,
00182 bt->re_source == NULL ? "" : bt->re_source);
00183 fprintf(fp, "re_last: %lu\n", (u_long)bt->re_last);
00184 fprintf(fp,
00185 "cmap: %#lx smap: %#lx emap: %#lx msize: %lu\n",
00186 (u_long)bt->re_cmap, (u_long)bt->re_smap,
00187 (u_long)bt->re_emap, (u_long)bt->re_msize);
00188 fprintf(fp, "re_irec: %#lx\n", (u_long)bt->re_irec);
00189 }
00190 fprintf(fp, "flags: %#lx", (u_long)bt->flags);
00191 CDB___db_prflags(bt->flags, bfn, fp);
00192 fprintf(fp, "\n");
00193 break;
00194 case DB_HASH:
00195 h = dbp->h_internal;
00196 fprintf(fp, "meta_pgno: %lu\n", (u_long)h->meta_pgno);
00197 fprintf(fp, "h_ffactor: %lu\n", (u_long)h->h_ffactor);
00198 fprintf(fp, "h_nelem: %lu\n", (u_long)h->h_nelem);
00199 fprintf(fp, "h_hash: %#lx\n", (u_long)h->h_hash);
00200 break;
00201 case DB_QUEUE:
00202 q = dbp->q_internal;
00203 fprintf(fp, "q_meta: %lu\n", (u_long)q->q_meta);
00204 fprintf(fp, "q_root: %lu\n", (u_long)q->q_root);
00205 fprintf(fp, "re_pad: %#lx re_len: %lu\n",
00206 (u_long)q->re_pad, (u_long)q->re_len);
00207 fprintf(fp, "rec_page: %lu\n", (u_long)q->rec_page);
00208 break;
00209 default:
00210 break;
00211 }
00212 }
00213
00214
00215
00216
00217
00218 static int
00219 __db_prtree(dbp, flags)
00220 DB *dbp;
00221 u_int32_t flags;
00222 {
00223 PAGE *h;
00224 db_pgno_t i, last;
00225 int ret;
00226
00227 if (set_psize == PSIZE_BOUNDARY)
00228 __db_psize(dbp);
00229
00230
00231 if ((ret = CDB_memp_fget(dbp->mpf, &last, DB_MPOOL_LAST, &h)) != 0)
00232 return (ret);
00233 if ((ret = CDB_memp_fput(dbp->mpf, h, 0)) != 0)
00234 return (ret);
00235
00236
00237 for (i = 0; i <= last; ++i) {
00238 if ((ret = CDB_memp_fget(dbp->mpf, &i, 0, &h)) != 0)
00239 return (ret);
00240 (void)CDB___db_prpage(dbp, h, flags);
00241 if ((ret = CDB_memp_fput(dbp->mpf, h, 0)) != 0)
00242 return (ret);
00243 }
00244
00245 (void)fflush(__db_prinit(NULL));
00246 return (0);
00247 }
00248
00249
00250
00251
00252
00253 static void
00254 __db_meta(dbp, dbmeta, fp, fn, flags)
00255 DB *dbp;
00256 DBMETA *dbmeta;
00257 FILE *fp;
00258 FN const *fn;
00259 u_int32_t flags;
00260 {
00261 PAGE *h;
00262 int cnt;
00263 db_pgno_t pgno;
00264 u_int8_t *p;
00265 int ret;
00266 const char *sep;
00267
00268 fprintf(fp, "\tmagic: %#lx\n", (u_long)dbmeta->magic);
00269 fprintf(fp, "\tversion: %lu\n", (u_long)dbmeta->version);
00270 fprintf(fp, "\tpagesize: %lu\n", (u_long)dbmeta->pagesize);
00271 fprintf(fp, "\ttype: %lu\n", (u_long)dbmeta->type);
00272 fprintf(fp, "\tkeys: %lu\trecords: %lu\n",
00273 (u_long)dbmeta->key_count, (u_long)dbmeta->record_count);
00274 fprintf(fp, "\talloc_lsn(lsn.file: %lu lsn.offset: %lu)\n",
00275 (u_long)dbmeta->alloc_lsn.file, (u_long)dbmeta->alloc_lsn.offset);
00276
00277 if (!LF_ISSET(DB_PR_RECOVERYTEST)) {
00278
00279
00280
00281
00282
00283 fprintf(fp, "\tfree list: %lu", (u_long)dbmeta->free);
00284 for (pgno = dbmeta->free,
00285 cnt = 0, sep = ", "; pgno != PGNO_INVALID;) {
00286 if ((ret = CDB_memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) {
00287 fprintf(fp,
00288 "Unable to retrieve free-list page: %lu: %s\n",
00289 (u_long)pgno, CDB_db_strerror(ret));
00290 break;
00291 }
00292 pgno = h->next_pgno;
00293 (void)CDB_memp_fput(dbp->mpf, h, 0);
00294 fprintf(fp, "%s%lu", sep, (u_long)pgno);
00295 if (++cnt % 10 == 0) {
00296 fprintf(fp, "\n");
00297 cnt = 0;
00298 sep = "\t";
00299 } else
00300 sep = ", ";
00301 }
00302 fprintf(fp, "\n");
00303 }
00304
00305 if (fn != NULL) {
00306 fprintf(fp, "\tflags: %#lx", (u_long)dbmeta->flags);
00307 CDB___db_prflags(dbmeta->flags, fn, fp);
00308 fprintf(fp, "\n");
00309 }
00310
00311 fprintf(fp, "\tuid: ");
00312 for (p = (u_int8_t *)dbmeta->uid,
00313 cnt = 0; cnt < DB_FILE_ID_LEN; ++cnt) {
00314 fprintf(fp, "%x", *p++);
00315 if (cnt < DB_FILE_ID_LEN - 1)
00316 fprintf(fp, " ");
00317 }
00318 fprintf(fp, "\n");
00319 }
00320
00321
00322
00323
00324
00325 static int
00326 __db_bmeta(dbp, fp, h, flags)
00327 DB *dbp;
00328 FILE *fp;
00329 BTMETA *h;
00330 u_int32_t flags;
00331 {
00332 static const FN mfn[] = {
00333 { BTM_DUP, "duplicates" },
00334 { BTM_RECNO, "recno" },
00335 { BTM_RECNUM, "btree:recnum" },
00336 { BTM_FIXEDLEN, "recno:fixed-length" },
00337 { BTM_RENUMBER, "recno:renumber" },
00338 { BTM_SUBDB, "multiple-databases" },
00339 { 0, NULL }
00340 };
00341
00342 __db_meta(dbp, (DBMETA *)h, fp, mfn, flags);
00343
00344 fprintf(fp, "\tmaxkey: %lu minkey: %lu\n",
00345 (u_long)h->maxkey, (u_long)h->minkey);
00346 if (dbp->type == DB_RECNO)
00347 fprintf(fp, "\tre_len: %#lx re_pad: %lu\n",
00348 (u_long)h->re_len, (u_long)h->re_pad);
00349 fprintf(fp, "\troot: %lu\n", (u_long)h->root);
00350
00351 return (0);
00352 }
00353
00354
00355
00356
00357
00358 static int
00359 __db_hmeta(dbp, fp, h, flags)
00360 DB *dbp;
00361 FILE *fp;
00362 HMETA *h;
00363 u_int32_t flags;
00364 {
00365 static const FN mfn[] = {
00366 { DB_HASH_DUP, "duplicates" },
00367 { DB_HASH_SUBDB, "multiple-databases" },
00368 { 0, NULL }
00369 };
00370 int i;
00371
00372 __db_meta(dbp, (DBMETA *)h, fp, mfn, flags);
00373
00374 fprintf(fp, "\tmax_bucket: %lu\n", (u_long)h->max_bucket);
00375 fprintf(fp, "\thigh_mask: %#lx\n", (u_long)h->high_mask);
00376 fprintf(fp, "\tlow_mask: %#lx\n", (u_long)h->low_mask);
00377 fprintf(fp, "\tffactor: %lu\n", (u_long)h->ffactor);
00378 fprintf(fp, "\tnelem: %lu\n", (u_long)h->nelem);
00379 fprintf(fp, "\th_charkey: %#lx\n", (u_long)h->h_charkey);
00380 fprintf(fp, "\tspare points: ");
00381 for (i = 0; i < NCACHED; i++)
00382 fprintf(fp, "%lu ", (u_long)h->spares[i]);
00383 fprintf(fp, "\n");
00384
00385 return (0);
00386 }
00387
00388
00389
00390
00391
00392 static int
00393 __db_qmeta(dbp, fp, h, flags)
00394 DB *dbp;
00395 FILE *fp;
00396 QMETA *h;
00397 u_int32_t flags;
00398 {
00399 __db_meta(dbp, (DBMETA *)h, fp, NULL, flags);
00400
00401 fprintf(fp, "\tstart: %lu\n", (u_long)h->start);
00402 fprintf(fp, "\tfirst_recno: %lu\n", (u_long)h->first_recno);
00403 fprintf(fp, "\tcur_recno: %lu\n", (u_long)h->cur_recno);
00404 fprintf(fp, "\tre_len: %#lx re_pad: %lu\n",
00405 (u_long)h->re_len, (u_long)h->re_pad);
00406 fprintf(fp, "\trec_page: %lu\n", (u_long)h->rec_page);
00407
00408 return (0);
00409 }
00410
00411
00412
00413
00414
00415
00416
00417 int
00418 CDB___db_prnpage(dbp, pgno)
00419 DB *dbp;
00420 db_pgno_t pgno;
00421 {
00422 PAGE *h;
00423 int ret;
00424
00425 if (set_psize == PSIZE_BOUNDARY)
00426 __db_psize(dbp);
00427
00428 if ((ret = CDB_memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
00429 return (ret);
00430
00431 ret = CDB___db_prpage(dbp, h, DB_PR_PAGE);
00432 (void)fflush(__db_prinit(NULL));
00433
00434 (void)CDB_memp_fput(dbp->mpf, h, 0);
00435 return (ret);
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 int
00445 CDB___db_prpage(dbp, h, flags)
00446 DB *dbp;
00447 PAGE *h;
00448 u_int32_t flags;
00449 {
00450 BINTERNAL *bi;
00451 BKEYDATA *bk;
00452 BTREE *t;
00453 FILE *fp;
00454 HOFFPAGE a_hkd;
00455 QAMDATA *qp, *qep;
00456 RINTERNAL *ri;
00457 db_indx_t dlen, len, i;
00458 db_pgno_t pgno;
00459 db_recno_t recno;
00460 int deleted, ret;
00461 const char *s;
00462 u_int32_t qlen;
00463 u_int8_t *ep, *hk, *p;
00464 void *sp;
00465
00466 fp = __db_prinit(NULL);
00467
00468
00469
00470
00471
00472 if (LF_ISSET(DB_PR_RECOVERYTEST) && TYPE(h) == P_INVALID)
00473 return (0);
00474
00475 s = CDB___db_pagetype_to_string(TYPE(h));
00476 if (s == NULL) {
00477 fprintf(fp, "ILLEGAL PAGE TYPE: page: %lu type: %lu\n",
00478 (u_long)h->pgno, (u_long)TYPE(h));
00479 return (1);
00480 }
00481
00482
00483 fprintf(fp, "page %lu: %s level: %lu",
00484 (u_long)h->pgno, s, (u_long)h->level);
00485
00486
00487 if (TYPE(h) == P_IBTREE ||
00488 TYPE(h) == P_IRECNO || (TYPE(h) == P_LRECNO &&
00489 h->pgno == ((BTREE *)dbp->bt_internal)->bt_root))
00490 fprintf(fp, " records: %lu", (u_long)RE_NREC(h));
00491
00492
00493 fprintf(fp, " (lsn.file: %lu lsn.offset: %lu)\n",
00494 (u_long)LSN(h).file, (u_long)LSN(h).offset);
00495
00496 switch (TYPE(h)) {
00497 case P_BTREEMETA:
00498 return (__db_bmeta(dbp, fp, (BTMETA *)h, flags));
00499 case P_HASHMETA:
00500 return (__db_hmeta(dbp, fp, (HMETA *)h, flags));
00501 case P_QAMMETA:
00502 return (__db_qmeta(dbp, fp, (QMETA *)h, flags));
00503 case P_QAMDATA:
00504 if (!LF_ISSET(DB_PR_PAGE))
00505 return (0);
00506
00507 qlen = ((QUEUE *)dbp->q_internal)->re_len;
00508 recno = (h->pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1;
00509 i = 0;
00510 qep = (QAMDATA *)((u_int8_t *)h + set_psize - qlen);
00511 for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep;
00512 recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) {
00513 if (!F_ISSET(qp, QAM_SET))
00514 continue;
00515
00516 fprintf(fp, "%s",
00517 F_ISSET(qp, QAM_VALID) ? "\t" : " D");
00518 fprintf(fp, "[%03lu] %4lu ",
00519 (u_long)recno, (u_long)qp - (u_long)h);
00520 CDB___db_pr(qp->data, qlen);
00521 }
00522 return (0);
00523 }
00524
00525 t = dbp->bt_internal;
00526
00527 s = "\t";
00528 if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) {
00529 fprintf(fp, "%sprev: %4lu next: %4lu",
00530 s, (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h));
00531 s = " ";
00532 }
00533 if (TYPE(h) == P_OVERFLOW) {
00534 fprintf(fp, "%sref cnt: %4lu ", s, (u_long)OV_REF(h));
00535 CDB___db_pr((u_int8_t *)h + P_OVERHEAD, OV_LEN(h));
00536 return (0);
00537 }
00538 fprintf(fp, "%sentries: %4lu", s, (u_long)NUM_ENT(h));
00539 fprintf(fp, " offset: %4lu\n", (u_long)HOFFSET(h));
00540
00541 if (TYPE(h) == P_INVALID || !LF_ISSET(DB_PR_PAGE))
00542 return (0);
00543
00544 ret = 0;
00545 for (i = 0; i < NUM_ENT(h); i++) {
00546 if (P_ENTRY(h, i) - (u_int8_t *)h < P_OVERHEAD ||
00547 (size_t)(P_ENTRY(h, i) - (u_int8_t *)h) >= set_psize) {
00548 fprintf(fp,
00549 "ILLEGAL PAGE OFFSET: indx: %lu of %lu\n",
00550 (u_long)i, (u_long)h->inp[i]);
00551 ret = EINVAL;
00552 continue;
00553 }
00554 deleted = 0;
00555 switch (TYPE(h)) {
00556 case P_HASH:
00557 case P_IBTREE:
00558 case P_IRECNO:
00559 sp = P_ENTRY(h, i);
00560 break;
00561 case P_LBTREE:
00562 sp = P_ENTRY(h, i);
00563 deleted = i % 2 == 0 &&
00564 B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type);
00565 break;
00566 case P_LDUP:
00567 case P_LRECNO:
00568 sp = P_ENTRY(h, i);
00569 deleted = B_DISSET(GET_BKEYDATA(h, i)->type);
00570 break;
00571 default:
00572 fprintf(fp,
00573 "ILLEGAL PAGE ITEM: %lu\n", (u_long)TYPE(h));
00574 ret = EINVAL;
00575 continue;
00576 }
00577 fprintf(fp, "%s", deleted ? " D" : "\t");
00578 fprintf(fp, "[%03lu] %4lu ", (u_long)i, (u_long)h->inp[i]);
00579 switch (TYPE(h)) {
00580 case P_HASH:
00581 hk = sp;
00582 switch (HPAGE_PTYPE(hk)) {
00583 case H_OFFDUP:
00584 memcpy(&pgno,
00585 HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
00586 fprintf(fp,
00587 "%4lu [offpage dups]\n", (u_long)pgno);
00588 break;
00589 case H_DUPLICATE:
00590
00591
00592
00593
00594
00595
00596 if (i != 0)
00597 len = LEN_HKEYDATA(h, 0, i);
00598 else
00599 len = 1;
00600
00601 fprintf(fp, "Duplicates:\n");
00602 for (p = HKEYDATA_DATA(hk),
00603 ep = p + len; p < ep;) {
00604 memcpy(&dlen, p, sizeof(db_indx_t));
00605 p += sizeof(db_indx_t);
00606 fprintf(fp, "\t\t");
00607 CDB___db_pr(p, dlen);
00608 p += sizeof(db_indx_t) + dlen;
00609 }
00610 break;
00611 case H_KEYDATA:
00612 CDB___db_pr(HKEYDATA_DATA(hk),
00613 LEN_HKEYDATA(h, i == 0 ? set_psize : 0, i));
00614 break;
00615 case H_OFFPAGE:
00616 memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
00617 fprintf(fp,
00618 "overflow: total len: %4lu page: %4lu\n",
00619 (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
00620 break;
00621 }
00622 break;
00623 case P_IBTREE:
00624 bi = sp;
00625 fprintf(fp, "count: %4lu pgno: %4lu type: %4lu",
00626 (u_long)bi->nrecs, (u_long)bi->pgno, (u_long)bi->type);
00627 switch (B_TYPE(bi->type)) {
00628 case B_KEYDATA:
00629 CDB___db_pr(bi->data, bi->len);
00630 break;
00631 case B_DUPLICATE:
00632 case B_OVERFLOW:
00633 __db_proff(bi->data);
00634 break;
00635 default:
00636 fprintf(fp, "ILLEGAL BINTERNAL TYPE: %lu\n",
00637 (u_long)B_TYPE(bi->type));
00638 ret = EINVAL;
00639 break;
00640 }
00641 break;
00642 case P_IRECNO:
00643 ri = sp;
00644 fprintf(fp, "entries %4lu pgno %4lu\n",
00645 (u_long)ri->nrecs, (u_long)ri->pgno);
00646 break;
00647 case P_LBTREE:
00648 case P_LDUP:
00649 case P_LRECNO:
00650 bk = sp;
00651 switch (B_TYPE(bk->type)) {
00652 case B_KEYDATA:
00653 CDB___db_pr(bk->data, bk->len);
00654 break;
00655 case B_DUPLICATE:
00656 case B_OVERFLOW:
00657 __db_proff(bk);
00658 break;
00659 default:
00660 fprintf(fp,
00661 "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu\n",
00662 (u_long)B_TYPE(bk->type));
00663 ret = EINVAL;
00664 break;
00665 }
00666 break;
00667 }
00668 }
00669 (void)fflush(fp);
00670 return (ret);
00671 }
00672
00673
00674
00675
00676
00677
00678
00679 void
00680 CDB___db_pr(p, len)
00681 u_int8_t *p;
00682 u_int32_t len;
00683 {
00684 FILE *fp;
00685 u_int lastch;
00686 int i;
00687
00688 fp = __db_prinit(NULL);
00689
00690 fprintf(fp, "len: %3lu", (u_long)len);
00691 lastch = '.';
00692 if (len != 0) {
00693 fprintf(fp, " data: ");
00694 for (i = len <= 20 ? len : 20; i > 0; --i, ++p) {
00695 lastch = *p;
00696 if (isprint(*p) || *p == '\n')
00697 fprintf(fp, "%c", *p);
00698 else
00699 fprintf(fp, "0x%.2x", (u_int)*p);
00700 }
00701 if (len > 20) {
00702 fprintf(fp, "...");
00703 lastch = '.';
00704 }
00705 }
00706 if (lastch != '\n')
00707 fprintf(fp, "\n");
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717 int
00718 CDB___db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, vdp)
00719 DBT *dbtp;
00720 int checkprint;
00721 const char *prefix;
00722 void *handle;
00723 int (*callback) __P((void *, const void *));
00724 int is_recno;
00725 VRFY_DBINFO *vdp;
00726 {
00727 static const char hex[] = "0123456789abcdef";
00728 #define DBTBUFLEN 100
00729 char buf[DBTBUFLEN];
00730 db_recno_t recno;
00731 int ret;
00732 u_int32_t len;
00733 u_int8_t *p;
00734
00735 if (vdp != NULL) {
00736
00737
00738
00739
00740
00741
00742
00743
00744 if (F_ISSET(vdp, SALVAGE_PRINTHEADER))
00745 (void)CDB___db_prheader(NULL, "__OTHER__", 0, 0,
00746 handle, callback, vdp, 0);
00747 F_CLR(vdp, SALVAGE_PRINTHEADER);
00748 F_SET(vdp, SALVAGE_PRINTFOOTER);
00749 }
00750
00751
00752
00753
00754
00755
00756
00757 if (prefix != NULL && (ret = callback(handle, prefix)) != 0)
00758 return (ret);
00759 if (is_recno) {
00760
00761
00762
00763
00764
00765 CDB___ua_memcpy(&recno, dbtp->data, sizeof(recno));
00766 snprintf(buf, DBTBUFLEN, "%lu", (u_long)recno);
00767 if ((ret = callback(handle, buf)) != 0)
00768 return (ret);
00769 } else if (checkprint) {
00770 for (len = dbtp->size, p = dbtp->data; len--; ++p)
00771 if (isprint(*p)) {
00772 if (*p == '\\' &&
00773 (ret = callback(handle, "\\")) != 0)
00774 return (ret);
00775 snprintf(buf, DBTBUFLEN, "%c", *p);
00776 if ((ret = callback(handle, buf)) != 0)
00777 return (ret);
00778 } else {
00779 snprintf(buf, DBTBUFLEN, "\\%c%c",
00780 hex[(u_int8_t)(*p & 0xf0) >> 4],
00781 hex[*p & 0x0f]);
00782 if ((ret = callback(handle, buf)) != 0)
00783 return (ret);
00784 }
00785 } else
00786 for (len = dbtp->size, p = dbtp->data; len--; ++p) {
00787 snprintf(buf, DBTBUFLEN, "%c%c",
00788 hex[(u_int8_t)(*p & 0xf0) >> 4],
00789 hex[*p & 0x0f]);
00790 if ((ret = callback(handle, buf)) != 0)
00791 return (ret);
00792 }
00793
00794 return (callback(handle, "\n"));
00795 }
00796
00797
00798
00799
00800
00801 static void
00802 __db_proff(vp)
00803 void *vp;
00804 {
00805 FILE *fp;
00806 BOVERFLOW *bo;
00807
00808 fp = __db_prinit(NULL);
00809
00810 bo = vp;
00811 switch (B_TYPE(bo->type)) {
00812 case B_OVERFLOW:
00813 fprintf(fp, "overflow: total len: %4lu page: %4lu\n",
00814 (u_long)bo->tlen, (u_long)bo->pgno);
00815 break;
00816 case B_DUPLICATE:
00817 fprintf(fp, "duplicate: page: %4lu\n", (u_long)bo->pgno);
00818 break;
00819 }
00820 }
00821
00822
00823
00824
00825
00826
00827
00828 void
00829 CDB___db_prflags(flags, fn, fp)
00830 u_int32_t flags;
00831 FN const *fn;
00832 FILE *fp;
00833 {
00834 const FN *fnp;
00835 int found;
00836 const char *sep;
00837
00838 sep = " (";
00839 for (found = 0, fnp = fn; fnp->mask != 0; ++fnp)
00840 if (LF_ISSET(fnp->mask)) {
00841 fprintf(fp, "%s%s", sep, fnp->name);
00842 sep = ", ";
00843 found = 1;
00844 }
00845 if (found)
00846 fprintf(fp, ")");
00847 }
00848
00849
00850
00851
00852
00853 static FILE *
00854 __db_prinit(fp)
00855 FILE *fp;
00856 {
00857 if (set_fp == NULL)
00858 set_fp = fp == NULL ? stdout : fp;
00859 return (set_fp);
00860 }
00861
00862
00863
00864
00865
00866 static void
00867 __db_psize(dbp)
00868 DB *dbp;
00869 {
00870 DBMETA *mp;
00871 db_pgno_t pgno;
00872
00873 set_psize = PSIZE_BOUNDARY - 1;
00874
00875 pgno = PGNO_BASE_MD;
00876 if (CDB_memp_fget(dbp->mpf, &pgno, 0, &mp) != 0)
00877 return;
00878
00879 switch (mp->magic) {
00880 case DB_BTREEMAGIC:
00881 case DB_HASHMAGIC:
00882 case DB_QAMMAGIC:
00883 set_psize = mp->pagesize;
00884 break;
00885 }
00886 (void)CDB_memp_fput(dbp->mpf, mp, 0);
00887 }
00888
00889
00890
00891
00892
00893 static const char *
00894 __db_dbtype_to_string(dbp)
00895 DB *dbp;
00896 {
00897 switch (dbp->type) {
00898 case DB_BTREE:
00899 return ("btree");
00900 case DB_HASH:
00901 return ("hash");
00902 break;
00903 case DB_RECNO:
00904 return ("recno");
00905 break;
00906 case DB_QUEUE:
00907 return ("queue");
00908 default:
00909 return ("UNKNOWN TYPE");
00910 }
00911
00912 }
00913
00914
00915
00916
00917
00918
00919
00920 const char *
00921 CDB___db_pagetype_to_string(type)
00922 u_int32_t type;
00923 {
00924 char *s;
00925
00926 s = NULL;
00927 switch (type) {
00928 case P_BTREEMETA:
00929 s = "btree metadata";
00930 break;
00931 case P_LDUP:
00932 s = "duplicate";
00933 break;
00934 case P_HASH:
00935 s = "hash";
00936 break;
00937 case P_HASHMETA:
00938 s = "hash metadata";
00939 break;
00940 case P_IBTREE:
00941 s = "btree internal";
00942 break;
00943 case P_INVALID:
00944 s = "invalid";
00945 break;
00946 case P_IRECNO:
00947 s = "recno internal";
00948 break;
00949 case P_LBTREE:
00950 s = "btree leaf";
00951 break;
00952 case P_LRECNO:
00953 s = "recno leaf";
00954 break;
00955 case P_OVERFLOW:
00956 s = "overflow";
00957 break;
00958 case P_QAMMETA:
00959 s = "queue metadata";
00960 break;
00961 case P_QAMDATA:
00962 s = "queue";
00963 break;
00964 default:
00965
00966 break;
00967 }
00968 return (s);
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978 int
00979 CDB___db_prheader(dbp, subname, pflag, keyflag, handle, callback, vdp, meta_pgno)
00980 DB *dbp;
00981 char *subname;
00982 int pflag, keyflag;
00983 void *handle;
00984 int (*callback) __P((void *, const void *));
00985 VRFY_DBINFO *vdp;
00986 db_pgno_t meta_pgno;
00987 {
00988 DB_BTREE_STAT *btsp;
00989 DB_ENV *dbenv;
00990 DB_HASH_STAT *hsp;
00991 DB_QUEUE_STAT *qsp;
00992 VRFY_PAGEINFO *pip;
00993 char *buf;
00994 int ret, t_ret, buflen;
00995 u_int32_t dbtype;
00996
00997 btsp = NULL;
00998 hsp = NULL;
00999 qsp = NULL;
01000 ret = 0;
01001 buf = NULL;
01002 COMPQUIET(buflen, 0);
01003
01004 if (dbp == NULL)
01005 dbenv = NULL;
01006 else
01007 dbenv = dbp->dbenv;
01008
01009
01010
01011
01012
01013
01014 if (vdp != NULL) {
01015 if ((ret = CDB___db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0)
01016 return (ret);
01017 } else
01018 pip = NULL;
01019
01020
01021
01022
01023
01024
01025
01026 if (dbp == NULL)
01027 dbtype = DB_BTREE;
01028 else if (pip != NULL)
01029 switch (pip->type) {
01030 case P_BTREEMETA:
01031 if (F_ISSET(pip, VRFY_IS_RECNO))
01032 dbtype = DB_RECNO;
01033 else
01034 dbtype = DB_BTREE;
01035 break;
01036 case P_HASHMETA:
01037 dbtype = DB_HASH;
01038 break;
01039 default:
01040
01041 DB_ASSERT(0);
01042 ret = EINVAL;
01043 goto err;
01044 }
01045 else
01046 dbtype = dbp->type;
01047
01048 if ((ret = callback(handle, "VERSION=2\n")) != 0)
01049 goto err;
01050 if (pflag) {
01051 if ((ret = callback(handle, "format=print\n")) != 0)
01052 goto err;
01053 } else if ((ret = callback(handle, "format=bytevalue\n")) != 0)
01054 goto err;
01055
01056
01057
01058
01059
01060
01061 buflen = 64 + ((subname != NULL) ? strlen(subname) : 0);
01062 if ((ret = CDB___os_malloc(dbenv, buflen, NULL, &buf)) != 0)
01063 goto err;
01064 if (subname != NULL) {
01065 snprintf(buf, buflen, "database=%s\n", subname);
01066 if ((ret = callback(handle, buf)) != 0)
01067 goto err;
01068 }
01069 switch (dbtype) {
01070 case DB_BTREE:
01071 if ((ret = callback(handle, "type=btree\n")) != 0)
01072 goto err;
01073 if (pip != NULL) {
01074 if (F_ISSET(pip, VRFY_HAS_RECNUMS))
01075 if ((ret =
01076 callback(handle, "recnum=1\n")) != 0)
01077 goto err;
01078 if (pip->bt_maxkey != 0) {
01079 snprintf(buf, buflen, "bt_maxkey=%lu\n",
01080 (u_long)pip->bt_maxkey);
01081 if ((ret = callback(handle, buf)) != 0)
01082 goto err;
01083 }
01084 if (pip->bt_minkey != 0 &&
01085 pip->bt_minkey != DEFMINKEYPAGE) {
01086 snprintf(buf, buflen, "bt_minkey=%lu\n",
01087 (u_long)pip->bt_minkey);
01088 if ((ret = callback(handle, buf)) != 0)
01089 goto err;
01090 }
01091 break;
01092 }
01093 if ((ret = dbp->stat(dbp, &btsp, NULL, 0)) != 0) {
01094 dbp->err(dbp, ret, "DB->stat");
01095 goto err;
01096 }
01097 if (F_ISSET(dbp, DB_BT_RECNUM))
01098 if ((ret = callback(handle, "recnum=1\n")) != 0)
01099 goto err;
01100 if (btsp->bt_maxkey != 0) {
01101 snprintf(buf, buflen,
01102 "bt_maxkey=%lu\n", (u_long)btsp->bt_maxkey);
01103 if ((ret = callback(handle, buf)) != 0)
01104 goto err;
01105 }
01106 if (btsp->bt_minkey != 0 && btsp->bt_minkey != DEFMINKEYPAGE) {
01107 snprintf(buf, buflen,
01108 "bt_minkey=%lu\n", (u_long)btsp->bt_minkey);
01109 if ((ret = callback(handle, buf)) != 0)
01110 goto err;
01111 }
01112 break;
01113 case DB_HASH:
01114 if ((ret = callback(handle, "type=hash\n")) != 0)
01115 goto err;
01116 if (pip != NULL) {
01117 if (pip->h_ffactor != 0) {
01118 snprintf(buf, buflen, "h_ffactor=%lu\n",
01119 (u_long)pip->h_ffactor);
01120 if ((ret = callback(handle, buf)) != 0)
01121 goto err;
01122 }
01123 if (pip->h_nelem != 0) {
01124 snprintf(buf, buflen, "h_nelem=%lu\n",
01125 (u_long)pip->h_nelem);
01126 if ((ret = callback(handle, buf)) != 0)
01127 goto err;
01128 }
01129 break;
01130 }
01131 if ((ret = dbp->stat(dbp, &hsp, NULL, 0)) != 0) {
01132 dbp->err(dbp, ret, "DB->stat");
01133 goto err;
01134 }
01135 if (hsp->hash_ffactor != 0) {
01136 snprintf(buf, buflen,
01137 "h_ffactor=%lu\n", (u_long)hsp->hash_ffactor);
01138 if ((ret = callback(handle, buf)) != 0)
01139 goto err;
01140 }
01141 if (hsp->hash_nelem != 0 || hsp->hash_nkeys != 0) {
01142 snprintf(buf, buflen, "h_nelem=%lu\n",
01143 hsp->hash_nelem > hsp->hash_nkeys ?
01144 (u_long)hsp->hash_nelem : (u_long)hsp->hash_nkeys);
01145 if ((ret = callback(handle, buf)) != 0)
01146 goto err;
01147 }
01148 break;
01149 case DB_QUEUE:
01150 if ((ret = callback(handle, "type=queue\n")) != 0)
01151 goto err;
01152 if (vdp != NULL) {
01153 snprintf(buf,
01154 buflen, "re_len=%lu\n", (u_long)vdp->re_len);
01155 if ((ret = callback(handle, buf)) != 0)
01156 goto err;
01157 break;
01158 }
01159 if ((ret = dbp->stat(dbp, &qsp, NULL, 0)) != 0) {
01160 dbp->err(dbp, ret, "DB->stat");
01161 goto err;
01162 }
01163 snprintf(buf, buflen, "re_len=%lu\n", (u_long)qsp->qs_re_len);
01164 if (qsp->qs_re_pad != 0 && qsp->qs_re_pad != ' ')
01165 snprintf(buf, buflen, "re_pad=%#x\n", qsp->qs_re_pad);
01166 if ((ret = callback(handle, buf)) != 0)
01167 goto err;
01168 break;
01169 case DB_RECNO:
01170 if ((ret = callback(handle, "type=recno\n")) != 0)
01171 goto err;
01172 if (pip != NULL) {
01173 if (F_ISSET(pip, VRFY_IS_RRECNO))
01174 if ((ret =
01175 callback(handle, "renumber=1\n")) != 0)
01176 goto err;
01177 if (pip->re_len > 0) {
01178 snprintf(buf, buflen, "re_len=%lu\n",
01179 (u_long)pip->re_len);
01180 if ((ret = callback(handle, buf)) != 0)
01181 goto err;
01182 }
01183 break;
01184 }
01185 if ((ret = dbp->stat(dbp, &btsp, NULL, 0)) != 0) {
01186 dbp->err(dbp, ret, "DB->stat");
01187 goto err;
01188 }
01189 if (F_ISSET(dbp, DB_RE_RENUMBER))
01190 if ((ret = callback(handle, "renumber=1\n")) != 0)
01191 goto err;
01192 if (F_ISSET(dbp, DB_RE_FIXEDLEN)) {
01193 snprintf(buf, buflen,
01194 "re_len=%lu\n", (u_long)btsp->bt_re_len);
01195 if ((ret = callback(handle, buf)) != 0)
01196 goto err;
01197 }
01198 if (btsp->bt_re_pad != 0 && btsp->bt_re_pad != ' ') {
01199 snprintf(buf, buflen, "re_pad=%#x\n", btsp->bt_re_pad);
01200 if ((ret = callback(handle, buf)) != 0)
01201 goto err;
01202 }
01203 break;
01204 case DB_UNKNOWN:
01205 DB_ASSERT(0);
01206 CDB___db_err(dbp->dbenv, "Impossible DB type in CDB___db_prheader");
01207 ret = EINVAL;
01208 goto err;
01209 }
01210
01211 if (pip != NULL) {
01212 if (F_ISSET(pip, VRFY_HAS_DUPS))
01213 if ((ret = callback(handle, "duplicates=1\n")) != 0)
01214 goto err;
01215 if (F_ISSET(pip, VRFY_HAS_DUPSORT))
01216 if ((ret = callback(handle, "dupsort=1\n")) != 0)
01217 goto err;
01218
01219 } else {
01220 if (F_ISSET(dbp, DB_AM_DUP))
01221 if ((ret = callback(handle, "duplicates=1\n")) != 0)
01222 goto err;
01223 if (F_ISSET(dbp, DB_AM_DUPSORT))
01224 if ((ret = callback(handle, "dupsort=1\n")) != 0)
01225 goto err;
01226 if (!F_ISSET(dbp, DB_AM_PGDEF)) {
01227 snprintf(buf, buflen, "db_pagesize=%lu\n",
01228 (u_long)dbp->pgsize);
01229 if ((ret = callback(handle, buf)) != 0)
01230 goto err;
01231 }
01232 }
01233
01234 if (keyflag)
01235 if ((ret = callback(handle, "keys=1\n")) != 0)
01236 goto err;
01237
01238 ret = callback(handle, "HEADER=END\n");
01239
01240 err: if (pip != NULL &&
01241 (t_ret = CDB___db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0)
01242 ret = t_ret;
01243 if (btsp != NULL)
01244 CDB___os_free(btsp, 0);
01245 if (hsp != NULL)
01246 CDB___os_free(hsp, 0);
01247 if (qsp != NULL)
01248 CDB___os_free(qsp, 0);
01249 if (buf != NULL)
01250 CDB___os_free(buf, buflen);
01251
01252 return (ret);
01253 }
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263 int
01264 CDB___db_prfooter(handle, callback)
01265 void *handle;
01266 int (*callback) __P((void *, const void *));
01267 {
01268 return (callback(handle, "DATA=END\n"));
01269 }