summaryrefslogtreecommitdiff
path: root/db2/progs
diff options
context:
space:
mode:
Diffstat (limited to 'db2/progs')
-rw-r--r--db2/progs/db_archive/db_archive.c165
-rw-r--r--db2/progs/db_checkpoint/db_checkpoint.c246
-rw-r--r--db2/progs/db_deadlock/db_deadlock.c236
-rw-r--r--db2/progs/db_dump/db_dump.c280
-rw-r--r--db2/progs/db_dump185/db_dump185.c322
-rw-r--r--db2/progs/db_load/db_load.c457
-rw-r--r--db2/progs/db_printlog/db_printlog.c160
-rw-r--r--db2/progs/db_recover/db_recover.c122
-rw-r--r--db2/progs/db_stat/db_stat.c434
9 files changed, 2422 insertions, 0 deletions
diff --git a/db2/progs/db_archive/db_archive.c b/db2/progs/db_archive/db_archive.c
new file mode 100644
index 0000000000..136cf2c360
--- /dev/null
+++ b/db2/progs/db_archive/db_archive.c
@@ -0,0 +1,165 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_archive.c 10.12 (Sleepycat) 7/25/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#endif
+
+#include "db_int.h"
+#include "shqueue.h"
+#include "log.h"
+#include "db_dispatch.h"
+#include "clib_ext.h"
+#include "common_ext.h"
+
+DB_ENV *db_init __P((char *, int));
+void onint __P((int));
+void siginit __P((void));
+void usage __P((void));
+int main __P((int, char *[]));
+
+int interrupted;
+const char *progname = "db_archive"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB_ENV *dbenv;
+ int ch, flags, verbose;
+ char *home, **list;
+
+ flags = verbose = 0;
+ home = NULL;
+ while ((ch = getopt(argc, argv, "ah:lsv")) != EOF)
+ switch (ch) {
+ case 'a':
+ flags |= DB_ARCH_ABS;
+ break;
+ case 'h':
+ home = optarg;
+ break;
+ case 'l':
+ flags |= DB_ARCH_LOG;
+ break;
+ case 's':
+ flags |= DB_ARCH_DATA;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage();
+
+ /* Initialize the environment. */
+ dbenv = db_init(home, verbose);
+
+ /* Get the list of names. */
+ if ((errno = log_archive(dbenv->lg_info, &list, flags, NULL)) != 0) {
+ (void)db_appexit(dbenv);
+ err(1, "log_archive");
+ }
+
+ /* Print the names. */
+ if (list != NULL)
+ for (; *list != NULL; ++list)
+ printf("%s\n", *list);
+
+ return (db_appexit(dbenv) ? 1 : 0);
+}
+
+/*
+ * db_init --
+ * Initialize the environment.
+ */
+DB_ENV *
+db_init(home, verbose)
+ char *home;
+ int verbose;
+{
+ DB_ENV *dbenv;
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = progname;
+ dbenv->db_verbose = verbose;
+
+ if ((errno = db_appinit(home, NULL, dbenv,
+ DB_CREATE | DB_INIT_LOG | DB_INIT_TXN | DB_USE_ENVIRON)) != 0)
+ err(1, "db_appinit");
+
+ siginit();
+
+ return (dbenv);
+}
+
+/*
+ * siginit --
+ * Initialize the set of signals for which we want to clean up.
+ * Generally, we try not to leave the shared regions locked if
+ * we can.
+ */
+void
+siginit()
+{
+#ifdef SIGHUP
+ (void)signal(SIGHUP, onint);
+#endif
+ (void)signal(SIGINT, onint);
+#ifdef SIGKILL
+ (void)signal(SIGKILL, onint);
+#endif
+ (void)signal(SIGTERM, onint);
+}
+
+/*
+ * oninit --
+ * Interrupt signal handler.
+ */
+void
+onint(signo)
+ int signo;
+{
+ if ((interrupted = signo) == 0)
+ interrupted = SIGINT;
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr, "usage: db_archive [-alsv] [-h home]\n");
+ exit(1);
+}
diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c
new file mode 100644
index 0000000000..586b4b9686
--- /dev/null
+++ b/db2/progs/db_checkpoint/db_checkpoint.c
@@ -0,0 +1,246 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_checkpoint.c 10.9 (Sleepycat) 7/4/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#endif
+
+#include "db_int.h"
+#include "shqueue.h"
+#include "db_page.h"
+#include "log.h"
+#include "btree.h"
+#include "hash.h"
+#include "clib_ext.h"
+#include "common_ext.h"
+
+char *check __P((DB_ENV *, long, long));
+int checkpoint __P((DB_ENV *, char *, int));
+DB_ENV *db_init __P((char *));
+int logpid __P((char *, int));
+void onint __P((int));
+void siginit __P((void));
+void usage __P((void));
+int main __P((int, char *[]));
+
+int interrupted;
+time_t now; /* Checkpoint time. */
+const char *progname = "db_checkpoint"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB_ENV *dbenv;
+ time_t now;
+ long kbytes, minutes, seconds;
+ int ch, rval, verbose;
+ char *home, *logfile;
+
+ home = logfile = NULL;
+ kbytes = minutes = 0;
+ verbose = 0;
+ while ((ch = getopt(argc, argv, "h:k:L:p:v")) != EOF)
+ switch (ch) {
+ case 'h':
+ home = optarg;
+ break;
+ case 'k':
+ get_long(optarg, 1, LONG_MAX, &kbytes);
+ break;
+ case 'L':
+ logfile = optarg;
+ break;
+ case 'p':
+ get_long(optarg, 1, LONG_MAX, &minutes);
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage();
+
+ if (kbytes == 0 && minutes == 0) {
+ warnx("at least one of -k and -p must be specified");
+ usage();
+ }
+
+ /* Initialize the environment. */
+ dbenv = db_init(home);
+
+ if (logfile != NULL && logpid(logfile, 1)) {
+ (void)db_appexit(dbenv);
+ return (1);
+ }
+
+ /*
+ * If we have only a time delay, then we'll sleep the right amount
+ * to wake up when a checkpoint is necessary. If we have a "kbytes"
+ * field set, then we'll check every 30 seconds.
+ */
+ rval = 0;
+ seconds = kbytes != 0 ? 30 : minutes * 60;
+ while (!interrupted) {
+ (void)__db_sleep(seconds, 0);
+
+ if (verbose) {
+ (void)time(&now);
+ printf("checkpoint: %s", ctime(&now));
+ }
+ rval = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
+ if (rval < 0)
+ break;
+
+ while (rval > 0) {
+ if (verbose)
+ __db_err(dbenv,
+ "checkpoint did not finish, retrying");
+ (void)__db_sleep(2, 0);
+ rval = txn_checkpoint(dbenv->tx_info, 0, 0);
+ }
+ if (rval < 0)
+ break;
+ }
+
+ if (logfile != NULL && logpid(logfile, 0))
+ rval = 1;
+
+ if (interrupted) {
+ (void)signal(interrupted, SIG_DFL);
+ (void)raise(interrupted);
+ /* NOTREACHED */
+ }
+
+ return (db_appexit(dbenv) || rval ? 1 : 0);
+}
+
+/*
+ * db_init --
+ * Initialize the environment.
+ */
+DB_ENV *
+db_init(home)
+ char *home;
+{
+ DB_ENV *dbenv;
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = progname;
+
+ if ((errno = db_appinit(home, NULL, dbenv,
+ DB_INIT_LOG | DB_INIT_TXN | DB_INIT_MPOOL | DB_USE_ENVIRON)) != 0)
+ err(1, "db_appinit");
+
+ if (memp_register(dbenv->mp_info,
+ DB_FTYPE_BTREE, __bam_pgin, __bam_pgout) ||
+ memp_register(dbenv->mp_info,
+ DB_FTYPE_HASH, __ham_pgin, __ham_pgout)) {
+ (void)db_appexit(dbenv);
+ errx(1,
+ "db_appinit: failed to register access method functions");
+ }
+
+ siginit();
+
+ return (dbenv);
+}
+
+/*
+ * logpid --
+ * Log that we're running.
+ */
+int
+logpid(fname, is_open)
+ char *fname;
+ int is_open;
+{
+ FILE *fp;
+ time_t now;
+
+ if (is_open) {
+ if ((fp = fopen(fname, "w")) == NULL) {
+ warn("%s", fname);
+ return (1);
+ }
+ (void)time(&now);
+ fprintf(fp,
+ "%s: %lu %s", progname, (u_long)getpid(), ctime(&now));
+ fclose(fp);
+ } else
+ (void)remove(fname);
+ return (0);
+}
+
+/*
+ * siginit --
+ * Initialize the set of signals for which we want to clean up.
+ * Generally, we try not to leave the shared regions locked if
+ * we can.
+ */
+void
+siginit()
+{
+#ifdef SIGHUP
+ (void)signal(SIGHUP, onint);
+#endif
+ (void)signal(SIGINT, onint);
+#ifdef SIGKILL
+ (void)signal(SIGKILL, onint);
+#endif
+ (void)signal(SIGTERM, onint);
+}
+
+/*
+ * oninit --
+ * Interrupt signal handler.
+ */
+void
+onint(signo)
+ int signo;
+{
+ if ((interrupted = signo) == 0)
+ interrupted = SIGINT;
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr,
+ "usage: db_checkpoint [-v] [-h home] [-k kbytes] [-L file] [-p min]\n");
+ exit(1);
+}
diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c
new file mode 100644
index 0000000000..9437e3552d
--- /dev/null
+++ b/db2/progs/db_deadlock/db_deadlock.c
@@ -0,0 +1,236 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_deadlock.c 10.13 (Sleepycat) 7/20/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#endif
+
+#include "db_int.h"
+#include "clib_ext.h"
+#include "common_ext.h"
+
+#define BAD_KILLID 0xffffffff
+
+DB_ENV *db_init __P((char *, int));
+void onint __P((int));
+void siginit __P((void));
+void usage __P((void));
+int logpid __P((char *, int));
+int main __P((int, char *[]));
+
+int interrupted;
+const char *progname = "db_deadlock"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB_ENV *dbenv;
+ u_int32_t atype;
+ time_t now;
+ long seconds;
+ int ch, flags, verbose;
+ char *home, *logfile;
+
+ atype = DB_LOCK_DEFAULT;
+ home = logfile = NULL;
+ seconds = 0;
+ flags = verbose = 0;
+ while ((ch = getopt(argc, argv, "a:h:L:t:vw")) != EOF)
+ switch (ch) {
+ case 'a':
+ switch (optarg[0]) {
+ case 'o':
+ atype = DB_LOCK_OLDEST;
+ break;
+ case 'y':
+ atype = DB_LOCK_YOUNGEST;
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ if (optarg[1] != '\0')
+ usage();
+ break;
+ case 'h':
+ home = optarg;
+ break;
+ case 'L':
+ logfile = optarg;
+ break;
+ case 't':
+ get_long(optarg, 1, LONG_MAX, &seconds);
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'w':
+ LF_SET(DB_LOCK_CONFLICT);
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage();
+
+ if (seconds == 0 && !LF_ISSET(DB_LOCK_CONFLICT)) {
+ warnx("at least one of -t and -w must be specified");
+ usage();
+ }
+
+ /*
+ * We detect every second when we're running in DB_LOCK_CONFLICT mode.
+ */
+ if (seconds == 0)
+ seconds = 1;
+
+ /* Initialize the deadlock detector by opening the lock manager. */
+ dbenv = db_init(home, verbose);
+
+ if (logfile != NULL && logpid(logfile, 1)) {
+ (void)db_appexit(dbenv);
+ return (1);
+ }
+
+ while (!interrupted) {
+ if (dbenv->db_verbose != 0) {
+ time(&now);
+ __db_err(dbenv, "Running at %s", ctime(&now));
+ }
+
+ if ((errno = lock_detect(dbenv->lk_info, flags, atype)) != 0)
+ break;
+
+ /* Make a pass every "seconds" seconds. */
+ (void)__db_sleep(seconds, 0);
+ }
+
+ if (logfile != NULL)
+ (void)logpid(logfile, 0);
+
+ if (interrupted) {
+ (void)signal(interrupted, SIG_DFL);
+ (void)raise(interrupted);
+ /* NOTREACHED */
+ }
+
+ return (db_appexit(dbenv));
+}
+
+DB_ENV *
+db_init(home, verbose)
+ char *home;
+ int verbose;
+{
+ DB_ENV *dbenv;
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = progname;
+ dbenv->db_verbose = verbose;
+
+ if ((errno = db_appinit(home,
+ NULL, dbenv, DB_INIT_LOCK | DB_USE_ENVIRON)) != 0)
+ err(1, "db_appinit");
+
+ siginit();
+
+ return (dbenv);
+}
+
+/*
+ * logpid --
+ * Log that we're running.
+ */
+int
+logpid(fname, is_open)
+ char *fname;
+ int is_open;
+{
+ FILE *fp;
+ time_t now;
+
+ if (is_open) {
+ if ((fp = fopen(fname, "w")) == NULL) {
+ warn("%s", fname);
+ return (1);
+ }
+ (void)time(&now);
+ fprintf(fp,
+ "%s: %lu %s", progname, (u_long)getpid(), ctime(&now));
+ fclose(fp);
+ } else
+ (void)remove(fname);
+ return (0);
+}
+
+/*
+ * siginit --
+ * Initialize the set of signals for which we want to clean up.
+ * Generally, we try not to leave the shared regions locked if
+ * we can.
+ */
+void
+siginit()
+{
+#ifdef SIGHUP
+ (void)signal(SIGHUP, onint);
+#endif
+ (void)signal(SIGINT, onint);
+#ifdef SIGKILL
+ (void)signal(SIGKILL, onint);
+#endif
+ (void)signal(SIGTERM, onint);
+}
+
+/*
+ * oninit --
+ * Interrupt signal handler.
+ */
+void
+onint(signo)
+ int signo;
+{
+ if ((interrupted = signo) == 0)
+ interrupted = SIGINT;
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr,
+ "usage: db_deadlock [-vw] [-a m | o | y] [-h home] [-L file] [-t sec]\n");
+ exit(1);
+}
diff --git a/db2/progs/db_dump/db_dump.c b/db2/progs/db_dump/db_dump.c
new file mode 100644
index 0000000000..d60aa9b5c9
--- /dev/null
+++ b/db2/progs/db_dump/db_dump.c
@@ -0,0 +1,280 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_dump.c 10.13 (Sleepycat) 8/19/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+#include "db_page.h"
+#include "btree.h"
+#include "hash.h"
+#include "clib_ext.h"
+
+void configure __P((char *));
+DB_ENV *db_init __P((char *));
+void dbt_dump __P((DBT *));
+void dbt_print __P((DBT *));
+void pheader __P((DB *, int));
+void usage __P((void));
+int main __P((int, char *[]));
+
+const char *progname = "db_dump"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB *dbp;
+ DBC *dbcp;
+ DBT key, data;
+ DB_ENV *dbenv;
+ int ch, dflag, pflag;
+ char *home;
+
+ home = NULL;
+ dflag = pflag = 0;
+ while ((ch = getopt(argc, argv, "df:h:p")) != EOF)
+ switch (ch) {
+ case 'd':
+ dflag = 1;
+ break;
+ case 'f':
+ if (freopen(optarg, "w", stdout) == NULL)
+ err(1, "%s", optarg);
+ break;
+ case 'h':
+ home = optarg;
+ break;
+ case 'p':
+ pflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage();
+
+ if (dflag) {
+ if (home != NULL)
+ errx(1,
+ "the -d and -h options may not both be specified");
+ if (pflag)
+ errx(1,
+ "the -d and -p options may not both be specified");
+ }
+ /* Initialize the environment. */
+ dbenv = dflag ? NULL : db_init(home);
+
+ /* Open the DB file. */
+ if ((errno =
+ db_open(argv[0], DB_UNKNOWN, DB_RDONLY, 0, dbenv, NULL, &dbp)) != 0)
+ err(1, "%s", argv[0]);
+
+ /* DB dump. */
+ if (dflag) {
+ (void)__db_dump(dbp, NULL, 1);
+ if ((errno = dbp->close(dbp, 0)) != 0)
+ err(1, "close");
+ exit (0);
+ }
+
+ /* Get a cursor and step through the database. */
+ if ((errno = dbp->cursor(dbp, NULL, &dbcp)) != 0) {
+ (void)dbp->close(dbp, 0);
+ err(1, "cursor");
+ }
+
+ /* Print out the header. */
+ pheader(dbp, pflag);
+
+ /* Print out the key/data pairs. */
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ if (pflag)
+ while ((errno = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
+ if (dbp->type != DB_RECNO)
+ dbt_print(&key);
+ dbt_print(&data);
+ }
+ else
+ while ((errno = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
+ if (dbp->type != DB_RECNO)
+ dbt_dump(&key);
+ dbt_dump(&data);
+ }
+ if (errno != DB_NOTFOUND)
+ err(1, "cursor get");
+
+ if ((errno = dbp->close(dbp, 0)) != 0)
+ err(1, "close");
+ return (0);
+}
+
+/*
+ * db_init --
+ * Initialize the environment.
+ */
+DB_ENV *
+db_init(home)
+ char *home;
+{
+ DB_ENV *dbenv;
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = progname;
+
+ if ((errno =
+ db_appinit(home, NULL, dbenv, DB_CREATE | DB_USE_ENVIRON)) != 0)
+ err(1, "db_appinit");
+ return (dbenv);
+}
+
+/*
+ * pheader --
+ * Write out the header information.
+ */
+void
+pheader(dbp, pflag)
+ DB *dbp;
+ int pflag;
+{
+ DB_BTREE_STAT *btsp;
+ HTAB *hashp;
+ HASHHDR *hdr;
+ db_pgno_t pgno;
+
+ printf("format=%s\n", pflag ? "print" : "bytevalue");
+ switch (dbp->type) {
+ case DB_BTREE:
+ printf("type=btree\n");
+ if ((errno = dbp->stat(dbp, &btsp, NULL, 0)) != 0)
+ err(1, "dbp->stat");
+ if (F_ISSET(dbp, DB_BT_RECNUM))
+ printf("recnum=1\n");
+ if (btsp->bt_maxkey != 0)
+ printf("bt_maxkey=%lu\n", (u_long)btsp->bt_maxkey);
+ if (btsp->bt_minkey != 0)
+ printf("bt_minkey=%lu\n", (u_long)btsp->bt_minkey);
+ break;
+ case DB_HASH:
+ printf("type=hash\n");
+ hashp = dbp->internal;
+ pgno = PGNO_METADATA;
+ if (memp_fget(dbp->mpf, &pgno, 0, &hdr) == 0) {
+ if (hdr->ffactor != 0)
+ printf("h_ffactor=%lu\n", (u_long)hdr->ffactor);
+ if (hdr->nelem != 0)
+ printf("h_nelem=%lu\n", (u_long)hdr->nelem);
+ (void)memp_fput(dbp->mpf, hdr, 0);
+ }
+ break;
+ case DB_RECNO:
+ printf("type=recno\n");
+ if (F_ISSET(dbp, DB_RE_RENUMBER))
+ printf("renumber=1\n");
+ if (F_ISSET(dbp, DB_RE_FIXEDLEN))
+ printf("re_len=%lu\n", (u_long)btsp->bt_re_len);
+ if (F_ISSET(dbp, DB_RE_PAD))
+ printf("re_pad=%#x\n", btsp->bt_re_pad);
+ break;
+ case DB_UNKNOWN:
+ abort();
+ /* NOTREACHED */
+ }
+
+ if (F_ISSET(dbp, DB_AM_DUP))
+ printf("duplicates=1\n");
+
+ if (dbp->dbenv->db_lorder != 0)
+ printf("db_lorder=%lu\n", (u_long)dbp->dbenv->db_lorder);
+
+ if (!F_ISSET(dbp, DB_AM_PGDEF))
+ printf("db_pagesize=%lu\n", (u_long)dbp->pgsize);
+
+ printf("HEADER=END\n");
+}
+
+static char hex[] = "0123456789abcdef";
+
+/*
+ * dbt_dump --
+ * Write out a key or data item using byte values.
+ */
+void
+dbt_dump(dbtp)
+ DBT *dbtp;
+{
+ u_int32_t len;
+ u_int8_t *p;
+
+ for (len = dbtp->size, p = dbtp->data; len--; ++p)
+ (void)printf("%c%c",
+ hex[(u_int8_t)(*p & 0xf0) >> 4], hex[*p & 0x0f]);
+ printf("\n");
+}
+
+/*
+ * dbt_print --
+ * Write out a key or data item using printable characters.
+ */
+void
+dbt_print(dbtp)
+ DBT *dbtp;
+{
+ u_int32_t len;
+ u_int8_t *p;
+
+ for (len = dbtp->size, p = dbtp->data; len--; ++p)
+ if (isprint(*p)) {
+ if (*p == '\\')
+ (void)printf("\\");
+ (void)printf("%c", *p);
+ } else
+ (void)printf("\\%c%c",
+ hex[(u_int8_t)(*p & 0xf0) >> 4], hex[*p & 0x0f]);
+ printf("\n");
+}
+
+/*
+ * usage --
+ * Display the usage message.
+ */
+void
+usage()
+{
+ (void)fprintf(stderr,
+ "usage: db_dump [-dp] [-f file] [-h home] db_file\n");
+ exit(1);
+}
diff --git a/db2/progs/db_dump185/db_dump185.c b/db2/progs/db_dump185/db_dump185.c
new file mode 100644
index 0000000000..f3c1187e45
--- /dev/null
+++ b/db2/progs/db_dump185/db_dump185.c
@@ -0,0 +1,322 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_dump185.c 10.5 (Sleepycat) 7/2/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+
+#include "db_185.h"
+#include "clib_ext.h"
+
+/* Hash Table Information */
+typedef struct hashhdr { /* Disk resident portion */
+ int magic; /* Magic NO for hash tables */
+ int version; /* Version ID */
+ u_int32_t lorder; /* Byte Order */
+ int bsize; /* Bucket/Page Size */
+ int bshift; /* Bucket shift */
+ int dsize; /* Directory Size */
+ int ssize; /* Segment Size */
+ int sshift; /* Segment shift */
+ int ovfl_point; /* Where overflow pages are being
+ * allocated */
+ int last_freed; /* Last overflow page freed */
+ int max_bucket; /* ID of Maximum bucket in use */
+ int high_mask; /* Mask to modulo into entire table */
+ int low_mask; /* Mask to modulo into lower half of
+ * table */
+ int ffactor; /* Fill factor */
+ int nkeys; /* Number of keys in hash table */
+} HASHHDR;
+
+typedef struct htab { /* Memory resident data structure */
+ HASHHDR hdr; /* Header */
+} HTAB;
+
+typedef struct _epgno {
+ u_int32_t pgno; /* the page number */
+ u_int16_t index; /* the index on the page */
+} EPGNO;
+
+typedef struct _epg {
+ void *page; /* the (pinned) page */
+ u_int16_t index; /* the index on the page */
+} EPG;
+
+typedef struct _cursor {
+ EPGNO pg; /* B: Saved tree reference. */
+ DBT key; /* B: Saved key, or key.data == NULL. */
+ u_int32_t rcursor; /* R: recno cursor (1-based) */
+
+#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
+#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
+#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
+#define CURS_INIT 0x08 /* RB: Cursor initialized. */
+ u_int8_t flags;
+} CURSOR;
+
+/* The in-memory btree/recno data structure. */
+typedef struct _btree {
+ void *bt_mp; /* memory pool cookie */
+
+ void *bt_dbp; /* pointer to enclosing DB */
+
+ EPG bt_cur; /* current (pinned) page */
+ void *bt_pinned; /* page pinned across calls */
+
+ CURSOR bt_cursor; /* cursor */
+
+ EPGNO bt_stack[50]; /* stack of parent pages */
+ EPGNO *bt_sp; /* current stack pointer */
+
+ DBT bt_rkey; /* returned key */
+ DBT bt_rdata; /* returned data */
+
+ int bt_fd; /* tree file descriptor */
+
+ u_int32_t bt_free; /* next free page */
+ u_int32_t bt_psize; /* page size */
+ u_int16_t bt_ovflsize; /* cut-off for key/data overflow */
+ int bt_lorder; /* byte order */
+ /* sorted order */
+ enum { NOT, BACK, FORWARD } bt_order;
+ EPGNO bt_last; /* last insert */
+
+ /* B: key comparison function */
+ int (*bt_cmp) __P((const DBT *, const DBT *));
+ /* B: prefix comparison function */
+ size_t (*bt_pfx) __P((const DBT *, const DBT *));
+ /* R: recno input function */
+ int (*bt_irec) __P((struct _btree *, u_int32_t));
+
+ FILE *bt_rfp; /* R: record FILE pointer */
+ int bt_rfd; /* R: record file descriptor */
+
+ void *bt_cmap; /* R: current point in mapped space */
+ void *bt_smap; /* R: start of mapped space */
+ void *bt_emap; /* R: end of mapped space */
+ size_t bt_msize; /* R: size of mapped region. */
+
+ u_int32_t bt_nrecs; /* R: number of records */
+ size_t bt_reclen; /* R: fixed record length */
+ u_char bt_bval; /* R: delimiting byte/pad character */
+
+/*
+ * NB:
+ * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
+ */
+#define B_INMEM 0x00001 /* in-memory tree */
+#define B_METADIRTY 0x00002 /* need to write metadata */
+#define B_MODIFIED 0x00004 /* tree modified */
+#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
+#define B_RDONLY 0x00010 /* read-only tree */
+
+#define B_NODUPS 0x00020 /* no duplicate keys permitted */
+#define R_RECNO 0x00080 /* record oriented tree */
+
+#define R_CLOSEFP 0x00040 /* opened a file pointer */
+#define R_EOF 0x00100 /* end of input file reached. */
+#define R_FIXLEN 0x00200 /* fixed length records */
+#define R_MEMMAPPED 0x00400 /* memory mapped file. */
+#define R_INMEM 0x00800 /* in-memory file */
+#define R_MODIFIED 0x01000 /* modified file */
+#define R_RDONLY 0x02000 /* read-only file */
+
+#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
+#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
+#define B_DB_TXN 0x10000 /* DB_TXN specified. */
+ u_int32_t flags;
+} BTREE;
+
+void db_185_btree __P((DB *, int));
+void db_185_hash __P((DB *, int));
+void dbt_dump __P((DBT *));
+void dbt_print __P((DBT *));
+void usage __P((void));
+int main __P((int, char *[]));
+
+const char *progname = "db_dump185"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB *dbp;
+ DBT key, data;
+ int ch, pflag, rval;
+
+ pflag = 0;
+ while ((ch = getopt(argc, argv, "f:p")) != EOF)
+ switch (ch) {
+ case 'f':
+ if (freopen(optarg, "w", stdout) == NULL)
+ err(1, "%s", optarg);
+ break;
+ case 'p':
+ pflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage();
+
+ if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) {
+ if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL)
+ return (1);
+ db_185_hash(dbp, pflag);
+ } else
+ db_185_btree(dbp, pflag);
+
+ /*
+ * !!!
+ * DB 1.85 DBTs are a subset of DB 2.0 DBTs, so we just use the
+ * new dump/print routines.
+ */
+ if (pflag)
+ while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) {
+ dbt_print(&key);
+ dbt_print(&data);
+ }
+ else
+ while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) {
+ dbt_dump(&key);
+ dbt_dump(&data);
+ }
+
+ if (rval == -1)
+ err(1, "seq");
+ return (0);
+}
+
+/*
+ * db_185_hash --
+ * Dump out hash header information.
+ */
+void
+db_185_hash(dbp, pflag)
+ DB *dbp;
+ int pflag;
+{
+ HTAB *hashp;
+
+ hashp = dbp->internal;
+
+ printf("format=%s\n", pflag ? "print" : "bytevalue");
+ printf("type=hash\n");
+ printf("h_ffactor=%lu\n", (u_long)hashp->hdr.ffactor);
+#ifdef NOT_AVAILABLE_IN_DB_185
+ printf("h_nelem=%lu\n", (u_long)hashp->hdr.nelem);
+#endif
+ if (hashp->hdr.lorder != 0)
+ printf("db_lorder=%lu\n", (u_long)hashp->hdr.lorder);
+ printf("db_pagesize=%lu\n", (u_long)hashp->hdr.bsize);
+ printf("HEADER=END\n");
+}
+
+/*
+ * db_185_btree --
+ * Dump out btree header information.
+ */
+void
+db_185_btree(dbp, pflag)
+ DB *dbp;
+ int pflag;
+{
+ BTREE *btp;
+
+ btp = dbp->internal;
+
+ printf("format=%s\n", pflag ? "print" : "bytevalue");
+ printf("type=btree\n");
+#ifdef NOT_AVAILABLE_IN_185
+ printf("bt_minkey=%lu\n", (u_long)XXX);
+ printf("bt_maxkey=%lu\n", (u_long)XXX);
+#endif
+ if (btp->bt_lorder != 0)
+ printf("db_lorder=%lu\n", (u_long)btp->bt_lorder);
+ printf("db_pagesize=%lu\n", (u_long)btp->bt_psize);
+ if (!(btp->flags & B_NODUPS))
+ printf("duplicates=1\n");
+ printf("HEADER=END\n");
+}
+
+static char hex[] = "0123456789abcdef";
+
+/*
+ * dbt_dump --
+ * Write out a key or data item using byte values.
+ */
+void
+dbt_dump(dbtp)
+ DBT *dbtp;
+{
+ size_t len;
+ u_int8_t *p;
+
+ for (len = dbtp->size, p = dbtp->data; len--; ++p)
+ (void)printf("%c%c",
+ hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]);
+ printf("\n");
+}
+
+/*
+ * dbt_print --
+ * Write out a key or data item using printable characters.
+ */
+void
+dbt_print(dbtp)
+ DBT *dbtp;
+{
+ size_t len;
+ u_int8_t *p;
+
+ for (len = dbtp->size, p = dbtp->data; len--; ++p)
+ if (isprint(*p)) {
+ if (*p == '\\')
+ (void)printf("\\");
+ (void)printf("%c", *p);
+ } else
+ (void)printf("\\%c%c",
+ hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]);
+ printf("\n");
+}
+
+/*
+ * usage --
+ * Display the usage message.
+ */
+void
+usage()
+{
+ (void)fprintf(stderr, "usage: db_dump [-p] [-f file] db_file\n");
+ exit(1);
+}
diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c
new file mode 100644
index 0000000000..cc90e7bd27
--- /dev/null
+++ b/db2/progs/db_load/db_load.c
@@ -0,0 +1,457 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_load.c 10.9 (Sleepycat) 8/19/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+#include "clib_ext.h"
+
+void badnum __P((void));
+void configure __P((DB_INFO *, char **));
+DB_ENV *db_init __P((char *));
+int dbt_rdump __P((DBT *));
+int dbt_rprint __P((DBT *));
+int digitize __P((int));
+void rheader __P((DBTYPE *, int *, DB_INFO *));
+void usage __P((void));
+int main __P((int, char *[]));
+
+const char *progname = "db_load"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB *dbp;
+ DBT key, data;
+ DBTYPE argtype, headertype;
+ DB_ENV *dbenv;
+ DB_INFO dbinfo;
+ db_recno_t recno;
+ int ch, pflag;
+ char **clist, **clp, *home;
+
+ /* Allocate enough room for configuration arguments. */
+ if ((clp = clist = calloc(argc + 1, sizeof(char *))) == NULL)
+ err(1, NULL);
+
+ home = NULL;
+ argtype = DB_UNKNOWN;
+ while ((ch = getopt(argc, argv, "c:f:h:t:")) != EOF)
+ switch (ch) {
+ case 'c':
+ *clp++ = optarg;
+ break;
+ case 'f':
+ if (freopen(optarg, "r", stdin) == NULL)
+ err(1, "%s", optarg);
+ break;
+ case 'h':
+ home = optarg;
+ break;
+ case 't':
+ if (strcmp(optarg, "btree") == 0) {
+ argtype = DB_BTREE;
+ break;
+ }
+ if (strcmp(optarg, "hash") == 0) {
+ argtype = DB_HASH;
+ break;
+ }
+ usage();
+ /* NOTREACHED */
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage();
+
+ /* Initialize the environment. */
+ dbenv = db_init(home);
+ memset(&dbinfo, 0, sizeof(DB_INFO));
+
+ /* Read the header. */
+ rheader(&headertype, &pflag, &dbinfo);
+
+ /* Apply command-line configuration changes. */
+ configure(&dbinfo, clist);
+
+ /* Conversion to/from recno is prohibited. */
+ if (argtype != DB_UNKNOWN) {
+ if (headertype == DB_RECNO)
+ errx(1, "databases of type recno may not be converted");
+ headertype = argtype;
+ }
+
+ /* Open the DB file. */
+ if ((errno = db_open(argv[0], headertype, DB_CREATE | DB_TRUNCATE,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
+ dbenv, &dbinfo, &dbp)) != 0)
+ err(1, "%s", argv[0]);
+
+ /* Initialize the key/data pair. */
+ memset(&key, 0, sizeof(DBT));
+ if ((key.data = (void *)malloc(key.ulen = 1024)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ memset(&data, 0, sizeof(DBT));
+ if ((data.data = (void *)malloc(data.ulen = 1024)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+
+ /* Get each key/data pair and add them to the database. */
+ if (headertype == DB_RECNO) {
+ key.data = &recno;
+ key.size = sizeof(recno);
+ for (recno = 1;; ++recno) {
+ if (pflag) {
+ if (dbt_rprint(&data))
+ break;
+ } else
+ if (dbt_rdump(&data))
+ break;
+ if ((errno = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
+ err(1, "%s", argv[0]);
+ }
+ } else
+ for (;;) {
+ if (pflag) {
+ if (dbt_rprint(&key))
+ break;
+ if (dbt_rprint(&data))
+ goto fmt;
+ } else {
+ if (dbt_rdump(&key))
+ break;
+ if (dbt_rdump(&data))
+fmt: err(1, "odd number of key/data pairs");
+ }
+ if ((errno = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
+ err(1, "%s", argv[0]);
+ }
+
+ if ((errno = dbp->close(dbp, 0)) != 0)
+ err(1, "%s", argv[0]);
+ return (0);
+}
+
+/*
+ * db_init --
+ * Initialize the environment.
+ */
+DB_ENV *
+db_init(home)
+ char *home;
+{
+ DB_ENV *dbenv;
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = progname;
+
+ if ((errno =
+ db_appinit(home, NULL, dbenv, DB_CREATE | DB_USE_ENVIRON)) != 0)
+ err(1, "db_appinit");
+ return (dbenv);
+}
+
+#define FLAG(name, value, keyword, flag) \
+ if (strcmp(name, keyword) == 0) { \
+ switch (*value) { \
+ case '1': \
+ dbinfop->flags |= (flag); \
+ break; \
+ case '0': \
+ dbinfop->flags &= ~(flag); \
+ break; \
+ default: \
+ badnum(); \
+ /* NOTREACHED */ \
+ } \
+ continue; \
+ }
+#define NUMBER(name, value, keyword, field, flag) \
+ if (strcmp(name, keyword) == 0) { \
+ get_long(value, 1, LONG_MAX, &val); \
+ dbinfop->field = val; \
+ if (flag != 0) \
+ dbinfop->flags |= (flag); \
+ continue; \
+ }
+#define STRING(name, value, keyword, field, flag) \
+ if (strcmp(name, keyword) == 0) { \
+ dbinfop->field = value[0]; \
+ if (flag != 0) \
+ dbinfop->flags |= (flag); \
+ continue; \
+ }
+
+/*
+ * configure --
+ * Handle command-line configuration options.
+ */
+void
+configure(dbinfop, clp)
+ DB_INFO *dbinfop;
+ char **clp;
+{
+ long val;
+ char *name, *value;
+
+ for (; (name = *clp) != NULL; ++clp) {
+ if ((value = strchr(name, '=')) == NULL)
+ errx(1,
+ "command-line configuration uses name=value format");
+ *value++ = '\0';
+
+ NUMBER(name, value, "bt_maxkey", bt_maxkey, 0);
+ NUMBER(name, value, "bt_minkey", bt_minkey, 0);
+ NUMBER(name, value, "db_lorder", db_lorder, 0);
+ NUMBER(name, value, "db_pagesize", db_pagesize, 0);
+ FLAG(name, value, "duplicates", DB_DUP);
+ NUMBER(name, value, "h_ffactor", h_ffactor, 0);
+ NUMBER(name, value, "h_nelem", h_nelem, 0);
+ NUMBER(name, value, "re_len", re_len, DB_FIXEDLEN);
+ STRING(name, value, "re_pad", re_pad, DB_PAD);
+ FLAG(name, value, "recnum", DB_RECNUM);
+ FLAG(name, value, "renumber", DB_RENUMBER);
+
+ errx(1, "unknown command-line configuration keyword");
+ }
+}
+
+/*
+ * rheader --
+ * Read the header message.
+ */
+void
+rheader(dbtypep, pflagp, dbinfop)
+ DBTYPE *dbtypep;
+ int *pflagp;
+ DB_INFO *dbinfop;
+{
+ long lineno, val;
+ char name[256], value[256];
+
+ *dbtypep = DB_UNKNOWN;
+ *pflagp = 0;
+
+ for (lineno = 1;; ++lineno) {
+ if (fscanf(stdin, "%[^=]=%s\n", name, value) != 2)
+ errx(1, "line %lu: unexpected line", lineno);
+ if (strcmp(name, "HEADER") == 0)
+ break;
+
+ if (strcmp(name, "format") == 0) {
+ if (strcmp(value, "bytevalue") == 0) {
+ *pflagp = 0;
+ continue;
+ }
+ if (strcmp(value, "print") == 0) {
+ *pflagp = 1;
+ continue;
+ }
+ errx(1, "line %d: unknown format", lineno);
+ }
+ if (strcmp(name, "type") == 0) {
+ if (strcmp(value, "btree") == 0) {
+ *dbtypep = DB_BTREE;
+ continue;
+ }
+ if (strcmp(value, "hash") == 0) {
+ *dbtypep = DB_HASH;
+ continue;
+ }
+ if (strcmp(value, "recno") == 0) {
+ *dbtypep = DB_RECNO;
+ continue;
+ }
+ errx(1, "line %d: unknown type", lineno);
+ }
+ NUMBER(name, value, "bt_maxkey", bt_maxkey, 0);
+ NUMBER(name, value, "bt_minkey", bt_minkey, 0);
+ NUMBER(name, value, "db_lorder", db_lorder, 0);
+ NUMBER(name, value, "db_pagesize", db_pagesize, 0);
+ FLAG(name, value, "duplicates", DB_DUP);
+ NUMBER(name, value, "h_ffactor", h_ffactor, 0);
+ NUMBER(name, value, "h_nelem", h_nelem, 0);
+ NUMBER(name, value, "re_len", re_len, DB_FIXEDLEN);
+ STRING(name, value, "re_pad", re_pad, DB_PAD);
+ FLAG(name, value, "recnum", DB_RECNUM);
+ FLAG(name, value, "renumber", DB_RENUMBER);
+
+ errx(1, "unknown input-file header configuration keyword");
+ }
+}
+
+/*
+ * dbt_rprint --
+ * Read a printable line into a DBT structure.
+ */
+int
+dbt_rprint(dbtp)
+ DBT *dbtp;
+{
+ u_int32_t len;
+ u_int8_t *p;
+ int c1, c2, escape;
+
+ escape = 0;
+ for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
+ if (c1 == EOF) {
+ if (len == 0)
+ return (1);
+ err(1, "unexpected end of key/data pair");
+ }
+ if (escape) {
+ if (c1 != '\\') {
+ if ((c2 = getchar()) == EOF)
+ err(1,
+ "unexpected end of key/data pair");
+ c1 = digitize(c1) << 4 | digitize(c2);
+ }
+ escape = 0;
+ } else
+ if (c1 == '\\') {
+ escape = 1;
+ continue;
+ }
+ if (++len >= dbtp->ulen - 10) {
+ dbtp->ulen *= 2;
+ if ((dbtp->data =
+ (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ p = (u_int8_t *)dbtp->data + len;
+ }
+ *p++ = c1;
+ }
+ dbtp->size = len;
+ return (0);
+}
+
+/*
+ * digitize --
+ * Convert a character to an integer.
+ */
+int
+digitize(c)
+ int c;
+{
+ switch (c) { /* Don't depend on ASCII ordering. */
+ case '0': return (0);
+ case '1': return (1);
+ case '2': return (2);
+ case '3': return (3);
+ case '4': return (4);
+ case '5': return (5);
+ case '6': return (6);
+ case '7': return (7);
+ case '8': return (8);
+ case '9': return (9);
+ case 'a': return (10);
+ case 'b': return (11);
+ case 'c': return (12);
+ case 'd': return (13);
+ case 'e': return (14);
+ case 'f': return (15);
+ }
+
+ err(1, "unexpected hexadecimal value");
+ /* NOTREACHED */
+
+ return (0);
+}
+
+/*
+ * dbt_rdump --
+ * Read a byte dump line into a DBT structure.
+ */
+int
+dbt_rdump(dbtp)
+ DBT *dbtp;
+{
+ u_int32_t len;
+ u_int8_t *p;
+ int c1, c2;
+
+ for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
+ if (c1 == EOF) {
+ if (len == 0)
+ return (1);
+ err(1, "unexpected end of key/data pair");
+ }
+ if ((c2 = getchar()) == EOF)
+ err(1, "unexpected end of key/data pair");
+ if (++len >= dbtp->ulen - 10) {
+ dbtp->ulen *= 2;
+ if ((dbtp->data =
+ (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ p = (u_int8_t *)dbtp->data + len;
+ }
+ *p++ = digitize(c1) << 4 | digitize(c2);
+ }
+ dbtp->size = len;
+ return (0);
+}
+
+/*
+ * badnum --
+ * Display the bad number message.
+ */
+void
+badnum()
+{
+ err(1, "boolean name=value pairs require a value of 0 or 1");
+}
+
+/*
+ * usage --
+ * Display the usage message.
+ */
+void
+usage()
+{
+ (void)fprintf(stderr,
+"usage: db_load [-c name=value] [-f file] [-h home] [-t btree | hash] db_file\n");
+ exit(1);
+}
diff --git a/db2/progs/db_printlog/db_printlog.c b/db2/progs/db_printlog/db_printlog.c
new file mode 100644
index 0000000000..12c365524f
--- /dev/null
+++ b/db2/progs/db_printlog/db_printlog.c
@@ -0,0 +1,160 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_printlog.c 10.8 (Sleepycat) 7/15/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+#include "db_int.h"
+#include "shqueue.h"
+#include "db_page.h"
+#include "btree.h"
+#include "hash.h"
+#include "log.h"
+#include "txn.h"
+#include "db_am.h"
+#include "clib_ext.h"
+
+DB_ENV *db_init __P((char *));
+void onint __P((int));
+void usage __P((void));
+
+int interrupted;
+char *progname = "db_printlog"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB_ENV *dbenv;
+ DBT data;
+ DB_LSN key;
+ int ch, eval;
+ char *home;
+
+ home = NULL;
+ while ((ch = getopt(argc, argv, "h:")) != EOF)
+ switch (ch) {
+ case 'h':
+ home = optarg;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if ((home != NULL && argc > 0) || argc > 1)
+ usage();
+
+ /* XXX: backward compatibility, first argument is home. */
+ if (argc == 1)
+ home = argv[0];
+
+ dbenv = db_init(home);
+
+ eval = 0;
+ if ((errno = __bam_init_print(dbenv)) != 0 ||
+ (errno = __db_init_print(dbenv)) != 0 ||
+ (errno = __ham_init_print(dbenv)) != 0 ||
+ (errno = __log_init_print(dbenv)) != 0 ||
+ (errno = __txn_init_print(dbenv)) != 0) {
+ warn("initialization");
+ eval = 1;
+ (void)db_appexit(dbenv);
+ }
+
+ (void)signal(SIGINT, onint);
+
+ memset(&data, 0, sizeof(data));
+ while (!interrupted) {
+ if ((errno =
+ log_get(dbenv->lg_info, &key, &data, DB_NEXT)) != 0) {
+ if (errno == DB_NOTFOUND)
+ break;
+ eval = 1;
+ warn("log_get");
+ break;
+ }
+ if ((errno =
+ __db_dispatch(dbenv->lg_info, &data, &key, 0, NULL)) != 0) {
+ eval = 1;
+ warn("dispatch");
+ break;
+ }
+ }
+
+ (void)db_appexit(dbenv);
+
+ if (interrupted) {
+ (void)signal(SIGINT, SIG_DFL);
+ (void)raise(SIGINT);
+ /* NOTREACHED */
+ }
+ exit (eval);
+}
+
+/*
+ * db_init --
+ * Initialize the environment.
+ */
+DB_ENV *
+db_init(home)
+ char *home;
+{
+ DB_ENV *dbenv;
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = progname;
+
+ if ((errno =
+ db_appinit(home, NULL, dbenv, DB_CREATE | DB_INIT_LOG)) != 0)
+ err(1, "db_appinit");
+ return (dbenv);
+}
+
+/*
+ * oninit --
+ * Interrupt signal handler.
+ */
+void
+onint(signo)
+ int signo;
+{
+ signo = 1; /* XXX: Shut the compiler up. */
+ interrupted = 1;
+}
+
+void
+usage()
+{
+ fprintf(stderr, "usage: db_printlog [-h home]\n");
+ exit (1);
+}
diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c
new file mode 100644
index 0000000000..4ac5925f79
--- /dev/null
+++ b/db2/progs/db_recover/db_recover.c
@@ -0,0 +1,122 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_recover.c 10.12 (Sleepycat) 7/27/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <time.h>
+#endif
+
+#include "db_int.h"
+#include "txn.h"
+#include "common_ext.h"
+#include "clib_ext.h"
+
+DB_ENV *db_init __P((char *, int, int));
+void usage __P((void));
+int main __P((int, char *[]));
+
+const char *progname = "db_recover"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB_ENV *dbenv;
+ time_t now;
+ int ch, flags, verbose;
+ char *home;
+
+ home = NULL;
+ flags = verbose = 0;
+ while ((ch = getopt(argc, argv, "ch:v")) != EOF)
+ switch (ch) {
+ case 'c':
+ LF_SET(DB_RECOVER_FATAL);
+ break;
+ case 'h':
+ home = optarg;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage();
+
+ dbenv = db_init(home, flags, verbose);
+ if (verbose) {
+ __db_err(dbenv, "Recovery complete at %s", ctime(&now));
+ __db_err(dbenv, "%s %lu %s [%lu][%lu]",
+ "Maximum transaction id",
+ (u_long)dbenv->tx_info->region->last_txnid,
+ "Recovery checkpoint",
+ (u_long)dbenv->tx_info->region->last_ckp.file,
+ (u_long)dbenv->tx_info->region->last_ckp.offset);
+ }
+
+ exit (db_appexit(dbenv));
+}
+
+DB_ENV *
+db_init(home, flags, verbose)
+ char *home;
+ int flags, verbose;
+{
+ DB_ENV *dbenv;
+ int local_flags;
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = "db_recover";
+ dbenv->db_verbose = verbose;
+
+ /* Initialize environment for pathnames only. */
+ local_flags = DB_CREATE | DB_INIT_LOG |
+ DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_USE_ENVIRON;
+
+ if (LF_ISSET(DB_RECOVER_FATAL))
+ local_flags |= DB_RECOVER_FATAL;
+ else
+ local_flags |= DB_RECOVER;
+
+ if ((errno = db_appinit(home, NULL, dbenv, local_flags)) != 0)
+ err(1, "appinit failed");
+
+ return (dbenv);
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr, "usage: db_recover [-cv] [-h home]\n");
+ exit(1);
+}
diff --git a/db2/progs/db_stat/db_stat.c b/db2/progs/db_stat/db_stat.c
new file mode 100644
index 0000000000..5c7044dbce
--- /dev/null
+++ b/db2/progs/db_stat/db_stat.c
@@ -0,0 +1,434 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997
+ * Sleepycat Software. All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1997\n\
+ Sleepycat Software Inc. All rights reserved.\n";
+static const char sccsid[] = "@(#)db_stat.c 8.17 (Sleepycat) 8/24/97";
+#endif
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#endif
+
+#include "db_int.h"
+#include "clib_ext.h"
+
+#define DIVIDER "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
+
+typedef enum { T_NOTSET, T_DB, T_MPOOL, T_TXN } test_t;
+
+void bstat __P((DB *));
+DB_ENV *db_init __P((char *, test_t));
+void hstat __P((DB *));
+void mstat __P((DB_ENV *));
+void prflags __P((u_int32_t, const FN *));
+void onint __P((int));
+void tstat __P((DB_ENV *));
+int txn_compare __P((const void *, const void *));
+void usage __P((void));
+int main __P((int, char *[]));
+
+int interrupted;
+const char *progname = "db_stat"; /* Program name. */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ DB *dbp;
+ DB_ENV *dbenv;
+ test_t ttype;
+ int ch;
+ char *db, *home;
+
+ ttype = T_NOTSET;
+ db = home = NULL;
+ while ((ch = getopt(argc, argv, "d:h:mt")) != EOF)
+ switch (ch) {
+ case 'd':
+ db = optarg;
+ ttype = T_DB;
+ break;
+ case 'h':
+ home = optarg;
+ break;
+ case 'm':
+ ttype = T_MPOOL;
+ break;
+ case 't':
+ ttype = T_TXN;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0 || ttype == T_NOTSET)
+ usage();
+
+ dbenv = db_init(home, ttype);
+
+ (void)signal(SIGINT, onint);
+
+ switch (ttype) {
+ case T_DB:
+ if ((errno = db_open(db, DB_UNKNOWN,
+ DB_RDONLY, 0, dbenv, NULL, &dbp)) != 0)
+ return (1);
+ switch (dbp->type) {
+ case DB_BTREE:
+ case DB_RECNO:
+ bstat(dbp);
+ break;
+ case DB_HASH:
+ hstat(dbp);
+ break;
+ case DB_UNKNOWN:
+ abort(); /* Impossible. */
+ /* NOTREACHED */
+ }
+ (void)dbp->close(dbp, 0);
+ break;
+ case T_MPOOL:
+ mstat(dbenv);
+ break;
+ case T_TXN:
+ tstat(dbenv);
+ break;
+ case T_NOTSET:
+ abort(); /* Impossible. */
+ /* NOTREACHED */
+ }
+
+ (void)db_appexit(dbenv);
+
+ if (interrupted) {
+ (void)signal(SIGINT, SIG_DFL);
+ (void)raise(SIGINT);
+ /* NOTREACHED */
+ }
+ return (0);
+}
+
+/*
+ * bstat --
+ * Display btree/recno statistics.
+ */
+void
+bstat(dbp)
+ DB *dbp;
+{
+ static const FN fn[] = {
+ { DB_DUP, "DB_DUP" },
+ { DB_FIXEDLEN, "DB_FIXEDLEN" },
+ { DB_RECNUM, "DB_RECNUM" },
+ { DB_RENUMBER, "DB_RENUMBER" },
+ { 0 }
+ };
+ DB_BTREE_STAT *sp;
+
+ if (dbp->stat(dbp, &sp, NULL, 0))
+ err(1, "dbp->stat");
+
+#define PCT(f, t) \
+ (t == 0 ? 0 : \
+ (((double)((t * sp->bt_pagesize) - f) / (t * sp->bt_pagesize)) * 100))
+
+ prflags(sp->bt_flags, fn);
+ if (dbp->type == DB_BTREE) {
+#ifdef NOT_IMPLEMENTED
+ printf("%lu\tMaximum keys per-page.\n", (u_long)sp->bt_maxkey);
+#endif
+ printf("%lu\tMinimum keys per-page.\n", (u_long)sp->bt_minkey);
+ }
+ if (dbp->type == DB_RECNO) {
+ printf("%lu\tFixed-length record size.\n",
+ (u_long)sp->bt_re_len);
+ if (isprint(sp->bt_re_pad))
+ printf("%c\tFixed-length record pad.\n",
+ (int)sp->bt_re_pad);
+ else
+ printf("0x%x\tFixed-length record pad.\n",
+ (int)sp->bt_re_pad);
+ }
+ printf("%lu\tUnderlying tree page size.\n", (u_long)sp->bt_pagesize);
+ printf("%lu\tNumber of levels in the tree.\n", (u_long)sp->bt_levels);
+ printf("%lu\tNumber of keys in the tree.\n", (u_long)sp->bt_nrecs);
+ printf("%lu\tNumber of tree internal pages.\n", (u_long)sp->bt_int_pg);
+ printf("%lu\tNumber of tree leaf pages.\n", (u_long)sp->bt_leaf_pg);
+ printf("%lu\tNumber of tree duplicate pages.\n",
+ (u_long)sp->bt_dup_pg);
+ printf("%lu\tNumber of tree overflow pages.\n",
+ (u_long)sp->bt_over_pg);
+ printf("%lu\tNumber of pages on the free list.\n",
+ (u_long)sp->bt_free);
+ printf("%lu\tNumber of pages freed for reuse.\n",
+ (u_long)sp->bt_freed);
+ printf("%lu\tNumber of bytes free in tree internal pages (%.0f%% ff)\n",
+ (u_long)sp->bt_int_pgfree,
+ PCT(sp->bt_int_pgfree, sp->bt_int_pg));
+ printf("%lu\tNumber of bytes free in tree leaf pages (%.0f%% ff).\n",
+ (u_long)sp->bt_leaf_pgfree,
+ PCT(sp->bt_leaf_pgfree, sp->bt_leaf_pg));
+printf("%lu\tNumber of bytes free in tree duplicate pages (%.0f%% ff).\n",
+ (u_long)sp->bt_dup_pgfree,
+ PCT(sp->bt_dup_pgfree, sp->bt_dup_pg));
+printf("%lu\tNumber of bytes free in tree overflow pages (%.0f%% ff).\n",
+ (u_long)sp->bt_over_pgfree,
+ PCT(sp->bt_over_pgfree, sp->bt_over_pg));
+ printf("%lu\tNumber of bytes saved by prefix compression.\n",
+ (u_long)sp->bt_pfxsaved);
+ printf("%lu\tTotal number of tree page splits.\n",
+ (u_long)sp->bt_split);
+ printf("%lu\tNumber of root page splits.\n", (u_long)sp->bt_rootsplit);
+ printf("%lu\tNumber of fast splits.\n", (u_long)sp->bt_fastsplit);
+ printf("%lu\tNumber of hits in tree fast-insert code.\n",
+ (u_long)sp->bt_cache_hit);
+ printf("%lu\tNumber of misses in tree fast-insert code.\n",
+ (u_long)sp->bt_cache_miss);
+ printf("%lu\tNumber of keys added.\n", (u_long)sp->bt_added);
+ printf("%lu\tNumber of keys deleted.\n", (u_long)sp->bt_deleted);
+}
+
+/*
+ * hstat --
+ * Display hash statistics.
+ */
+void
+hstat(dbp)
+ DB *dbp;
+{
+ return;
+}
+
+/*
+ * mstat --
+ * Display mpool statistics.
+ */
+void
+mstat(dbenv)
+ DB_ENV *dbenv;
+{
+ DB_MPOOL_FSTAT **fsp;
+ DB_MPOOL_STAT *gsp;
+
+ if (memp_stat(dbenv->mp_info, &gsp, &fsp, NULL))
+ err(1, NULL);
+
+ printf("%lu\tCache size (%luK).\n",
+ (u_long)gsp->st_cachesize, (u_long)gsp->st_cachesize / 1024);
+ printf("%lu\tRequested pages found in the cache", gsp->st_cache_hit);
+ if (gsp->st_cache_hit + gsp->st_cache_miss != 0)
+ printf(" (%.0f%%)", ((double)gsp->st_cache_hit /
+ (gsp->st_cache_hit + gsp->st_cache_miss)) * 100);
+ printf(".\n");
+ printf("%lu\tRequested pages mapped into the process' address space.\n",
+ gsp->st_map);
+ printf("%lu\tRequested pages not found in the cache.\n",
+ gsp->st_cache_miss);
+ printf("%lu\tPages created in the cache.\n", gsp->st_page_create);
+ printf("%lu\tPages read into the cache.\n", gsp->st_page_in);
+ printf("%lu\tPages written from the cache to the backing file.\n",
+ gsp->st_page_out);
+ printf("%lu\tRead-only pages forced from the cache.\n",
+ gsp->st_ro_evict);
+ printf("%lu\tRead-write pages forced from the cache.\n",
+ gsp->st_rw_evict);
+ printf("%lu\tNumber of hash buckets used for page location.\n",
+ gsp->st_hash_buckets);
+ printf("%lu\tTotal number of times hash chains searched for a page.\n",
+ gsp->st_hash_searches);
+ printf("%lu\tThe longest hash chain searched for a page.\n",
+ gsp->st_hash_longest);
+ printf(
+ "%lu\tTotal number of hash buckets examined for page location.\n",
+ gsp->st_hash_examined);
+
+ for (; fsp != NULL && *fsp != NULL; ++fsp) {
+ printf("%s\n", DIVIDER);
+ printf("%s\n", (*fsp)->file_name);
+ printf("%lu\tPage size.\n", (u_long)(*fsp)->st_pagesize);
+ printf("%lu\tRequested pages found in the cache",
+ (*fsp)->st_cache_hit);
+ if ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss != 0)
+ printf(" (%.0f%%)", ((double)(*fsp)->st_cache_hit /
+ ((*fsp)->st_cache_hit + (*fsp)->st_cache_miss)) *
+ 100);
+ printf(".\n");
+ printf("%lu\tRequested pages mapped into the process' address space.\n",
+ (*fsp)->st_map);
+ printf("%lu\tRequested pages not found in the cache.\n",
+ (*fsp)->st_cache_miss);
+ printf("%lu\tPages created in the cache.\n",
+ (*fsp)->st_page_create);
+ printf("%lu\tPages read into the cache.\n", (*fsp)->st_page_in);
+ printf("%lu\tPages written from the cache to the backing file.\n",
+ (*fsp)->st_page_out);
+ }
+}
+
+/*
+ * tstat --
+ * Display transaction statistics.
+ */
+void
+tstat(dbenv)
+ DB_ENV *dbenv;
+{
+ DB_TXN_STAT *tstat;
+ unsigned int i;
+ const char *p;
+
+ if (txn_stat(dbenv->tx_info, &tstat, NULL))
+ err(1, NULL);
+
+ p = tstat->st_last_ckp.file == 0 ?
+ "No checkpoint LSN." : "File/offset for last checkpoint LSN.";
+ printf("%lu/%lu\t%s\n", (u_long)tstat->st_last_ckp.file,
+ (u_long)tstat->st_last_ckp.offset, p);
+ p = tstat->st_pending_ckp.file == 0 ?
+ "No pending checkpoint LSN." :
+ "File/offset for last pending checkpoint LSN.";
+ printf("%lu/%lu\t%s.\n",
+ (u_long)tstat->st_pending_ckp.file,
+ (u_long)tstat->st_pending_ckp.offset, p);
+ if (tstat->st_time_ckp == 0)
+ printf("0\tNo checkpoint timestamp.\n");
+ else
+ printf("%.24s\tCheckpoint timestamp.\n",
+ ctime(&tstat->st_time_ckp));
+ printf("%lx\tLast transaction ID allocated.\n",
+ (u_long)tstat->st_last_txnid);
+ printf("%lu\tMaximum number of active transactions.\n",
+ (u_long)tstat->st_maxtxns);
+ printf("%lu\tNumber of transactions begun.\n",
+ (u_long)tstat->st_nbegins);
+ printf("%lu\tNumber of transactions aborted.\n",
+ (u_long)tstat->st_naborts);
+ printf("%lu\tNumber of transactions committed.\n",
+ (u_long)tstat->st_ncommits);
+ printf("%lu\tActive transactions.\n", (u_long)tstat->st_nactive);
+ qsort(tstat->st_txnarray,
+ tstat->st_nactive, sizeof(tstat->st_txnarray[0]), txn_compare);
+ for (i = 0; i < tstat->st_nactive; ++i)
+ printf("\tid: %lx; initial LSN file/offest %lu/%lu\n",
+ (u_long)tstat->st_txnarray[i].txnid,
+ (u_long)tstat->st_txnarray[i].lsn.file,
+ (u_long)tstat->st_txnarray[i].lsn.offset);
+}
+
+int
+txn_compare(a1, b1)
+ const void *a1, *b1;
+{
+ const DB_TXN_ACTIVE *a, *b;
+
+ a = a1;
+ b = b1;
+
+ if (a->txnid > b->txnid)
+ return (1);
+ if (a->txnid < b->txnid)
+ return (-1);
+ return (0);
+}
+
+/*
+ * prflags --
+ * Print out flag values.
+ */
+void
+prflags(flags, fn)
+ u_int32_t flags;
+ FN const *fn;
+{
+ const FN *fnp;
+ int found;
+ const char *sep;
+
+ sep = " ";
+ printf("Flags:");
+ for (found = 0, fnp = fn; fnp->mask != 0; ++fnp)
+ if (fnp->mask & flags) {
+ printf("%s%s", sep, fnp->name);
+ sep = ", ";
+ found = 1;
+ }
+ printf("\n");
+}
+
+/*
+ * db_init --
+ * Initialize the environment.
+ */
+DB_ENV *
+db_init(home, ttype)
+ char *home;
+ test_t ttype;
+{
+ DB_ENV *dbenv;
+ int flags;
+
+ flags = DB_USE_ENVIRON;
+ switch (ttype) {
+ case T_MPOOL:
+ flags |= DB_INIT_MPOOL;
+ break;
+ case T_TXN:
+ flags |= DB_INIT_TXN;
+ break;
+ default:
+ break;
+ }
+
+ if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+ errno = ENOMEM;
+ err(1, NULL);
+ }
+ dbenv->db_errfile = stderr;
+ dbenv->db_errpfx = progname;
+
+ if ((errno = db_appinit(home, NULL, dbenv, flags)) != 0)
+ err(1, "db_appinit");
+ return (dbenv);
+}
+
+/*
+ * oninit --
+ * Interrupt signal handler.
+ */
+void
+onint(signo)
+ int signo;
+{
+ signo = 1; /* XXX: Shut the compiler up. */
+ interrupted = 1;
+}
+
+void
+usage()
+{
+ fprintf(stderr, "usage: db_stat [-mt] [-d file] [-h home]\n");
+ exit (1);
+}