summary refs log tree commit diff
path: root/db2/progs
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-06-13 13:36:34 +0000
committerUlrich Drepper <drepper@redhat.com>1999-06-13 13:36:34 +0000
commitec239360d13518a13f572b635d036c7d10028010 (patch)
treebdb5111363f45d2107849c2456b575d72779174c /db2/progs
parentfc3703521650a9b6db910a50c4fc0f410496e134 (diff)
downloadglibc-ec239360d13518a13f572b635d036c7d10028010.tar.gz
glibc-ec239360d13518a13f572b635d036c7d10028010.tar.xz
glibc-ec239360d13518a13f572b635d036c7d10028010.zip
Update.
	* db2/Makefile (distribute): Remove files which do not exist
	anymore.
Diffstat (limited to 'db2/progs')
-rw-r--r--db2/progs/db_archive/db_archive.c53
-rw-r--r--db2/progs/db_checkpoint/db_checkpoint.c39
-rw-r--r--db2/progs/db_deadlock/db_deadlock.c34
-rw-r--r--db2/progs/db_dump/db_dump.c82
-rw-r--r--db2/progs/db_load/db_load.c102
-rw-r--r--db2/progs/db_printlog/README22
-rw-r--r--db2/progs/db_printlog/commit.awk7
-rw-r--r--db2/progs/db_printlog/count.awk9
-rw-r--r--db2/progs/db_printlog/db_printlog.c83
-rw-r--r--db2/progs/db_printlog/pgno.awk43
-rw-r--r--db2/progs/db_printlog/range.awk27
-rw-r--r--db2/progs/db_printlog/status.awk26
-rw-r--r--db2/progs/db_printlog/txn.awk30
-rw-r--r--db2/progs/db_recover/db_recover.c25
-rw-r--r--db2/progs/db_stat/db_stat.c56
15 files changed, 458 insertions, 180 deletions
diff --git a/db2/progs/db_archive/db_archive.c b/db2/progs/db_archive/db_archive.c
index 691824c2ab..ca489954f6 100644
--- a/db2/progs/db_archive/db_archive.c
+++ b/db2/progs/db_archive/db_archive.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_archive.c	10.17 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)db_archive.c	10.20 (Sleepycat) 10/3/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -33,12 +33,10 @@ static const char sccsid[] = "@(#)db_archive.c	10.17 (Sleepycat) 4/10/98";
 #include "common_ext.h"
 
 DB_ENV	*db_init __P((char *, int));
-void	 onint __P((int));
 int	 main __P((int, char *[]));
-void	 siginit __P((void));
+void	 nosig __P((void));
 void	 usage __P((void));
 
-int	 interrupted;
 const char
 	*progname = "db_archive";			/* Program name. */
 
@@ -83,13 +81,18 @@ main(argc, argv)
 	if (argc != 0)
 		usage();
 
-	/* Initialize the environment. */
+	/*
+	 * Ignore signals -- we don't want to be interrupted because we're
+	 * spending all of our time in the DB library.
+	 */
+	nosig();
 	dbenv = db_init(home, verbose);
 
 	/* Get the list of names. */
 	if ((errno = log_archive(dbenv->lg_info, &list, flags, NULL)) != 0) {
+		warn(NULL);
 		(void)db_appexit(dbenv);
-		err(1, "log_archive");
+		return (1);
 	}
 
 	/* Print the names. */
@@ -97,7 +100,12 @@ main(argc, argv)
 		for (; *list != NULL; ++list)
 			printf("%s\n", *list);
 
-	return (db_appexit(dbenv) ? 1 : 0);
+	if ((errno = db_appexit(dbenv)) != 0) {
+		warn(NULL);
+		return (1);
+	}
+
+	return (0);
 }
 
 /*
@@ -123,40 +131,21 @@ db_init(home, verbose)
 	    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.
+ * nosig --
+ *	We don't want to be interrupted.
  */
 void
-siginit()
+nosig()
 {
 #ifdef SIGHUP
-	(void)signal(SIGHUP, onint);
+	(void)signal(SIGHUP, SIG_IGN);
 #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)signal(SIGINT, SIG_IGN);
+	(void)signal(SIGTERM, SIG_IGN);
 }
 
 void
diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c
index 74f95ccce2..f0fe48ab2e 100644
--- a/db2/progs/db_checkpoint/db_checkpoint.c
+++ b/db2/progs/db_checkpoint/db_checkpoint.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_checkpoint.c	10.17 (Sleepycat) 5/3/98";
+static const char sccsid[] = "@(#)db_checkpoint.c	10.21 (Sleepycat) 10/4/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -59,7 +59,7 @@ main(argc, argv)
 	time_t now;
 	long argval;
 	u_int32_t kbytes, minutes, seconds;
-	int ch, eval, once, verbose;
+	int ch, once, ret, verbose;
 	char *home, *logfile;
 
 	/*
@@ -70,7 +70,7 @@ main(argc, argv)
 #define	MAX_UINT32_T	2147483647
 
 	kbytes = minutes = 0;
-	once = verbose = 0;
+	once = ret = verbose = 0;
 	home = logfile = NULL;
 	while ((ch = getopt(argc, argv, "1h:k:L:p:v")) != EOF)
 		switch (ch) {
@@ -110,6 +110,7 @@ main(argc, argv)
 	}
 
 	/* Initialize the environment. */
+	siginit();
 	dbenv = db_init(home);
 
 	if (logfile != NULL && logpid(logfile, 1)) {
@@ -122,37 +123,40 @@ main(argc, argv)
 	 * to wake up when a checkpoint is necessary.  If we have a "kbytes"
 	 * field set, then we'll check every 30 seconds.
 	 */
-	eval = 0;
 	seconds = kbytes != 0 ? 30 : minutes * 60;
 	while (!interrupted) {
 		if (verbose) {
 			(void)time(&now);
-			printf("checkpoint: %s", ctime(&now));
+			warnx("checkpoint: %s", ctime(&now));
 		}
-		errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
 
+		errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
 		while (errno == DB_INCOMPLETE) {
 			if (verbose)
-				__db_err(dbenv,
-				    "checkpoint did not finish, retrying");
-			(void)__db_sleep(2, 0);
+				warnx("checkpoint did not finish, retrying\n");
+			(void)sleep(2);
 			errno = txn_checkpoint(dbenv->tx_info, 0, 0);
 		}
 
 		if (errno != 0) {
-			eval = 1;
-			__db_err(dbenv, "checkpoint: %s", strerror(errno));
+			ret = 1;
+			warn(NULL);
 			break;
 		}
 
 		if (once)
 			break;
 
-		(void)__db_sleep(seconds, 0);
+		(void)sleep(seconds);
 	}
 
 	if (logfile != NULL && logpid(logfile, 0))
-		eval = 1;
+		ret = 1;
+
+	if ((errno = db_appexit(dbenv)) != 0) {
+		ret = 1;
+		warn(NULL);
+	}
 
 	if (interrupted) {
 		(void)signal(interrupted, SIG_DFL);
@@ -160,7 +164,7 @@ main(argc, argv)
 		/* NOTREACHED */
 	}
 
-	return (db_appexit(dbenv) || eval ? 1 : 0);
+	return (ret);
 }
 
 /*
@@ -193,8 +197,6 @@ db_init(home)
 		    "db_appinit: failed to register access method functions");
 	}
 
-	siginit();
-
 	return (dbenv);
 }
 
@@ -237,14 +239,11 @@ siginit()
 	(void)signal(SIGHUP, onint);
 #endif
 	(void)signal(SIGINT, onint);
-#ifdef SIGKILL
-	(void)signal(SIGKILL, onint);
-#endif
 	(void)signal(SIGTERM, onint);
 }
 
 /*
- * oninit --
+ * onint --
  *	Interrupt signal handler.
  */
 void
diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c
index 49a52416dd..bc5039e95f 100644
--- a/db2/progs/db_deadlock/db_deadlock.c
+++ b/db2/progs/db_deadlock/db_deadlock.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_deadlock.c	10.19 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)db_deadlock.c	10.23 (Sleepycat) 10/4/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -55,14 +55,14 @@ main(argc, argv)
 	time_t now;
 	long usecs;
 	u_int32_t flags;
-	int ch, verbose;
+	int ch, ret, verbose;
 	char *home, *logfile;
 
 	atype = DB_LOCK_DEFAULT;
 	home = logfile = NULL;
 	usecs = 0;
 	flags = 0;
-	verbose = 0;
+	ret = verbose = 0;
 	while ((ch = getopt(argc, argv, "a:h:L:t:vw")) != EOF)
 		switch (ch) {
 		case 'a':
@@ -119,6 +119,7 @@ main(argc, argv)
 		usecs = 100000;
 
 	/* Initialize the deadlock detector by opening the lock manager. */
+	siginit();
 	dbenv = db_init(home, verbose);
 
 	if (logfile != NULL && logpid(logfile, 1)) {
@@ -129,18 +130,26 @@ main(argc, argv)
 	while (!interrupted) {
 		if (dbenv->db_verbose != 0) {
 			time(&now);
-			__db_err(dbenv, "Running at %.24s", ctime(&now));
+			warnx("Running at %.24s", ctime(&now));
 		}
 
-		if ((errno = lock_detect(dbenv->lk_info, flags, atype)) != 0)
+		if ((errno = lock_detect(dbenv->lk_info, flags, atype)) != 0) {
+			ret = 1;
+			warnx(NULL);
 			break;
+		}
 
 		/* Make a pass every "usecs" usecs. */
-		(void)__db_sleep(0, usecs);
+		(void)usleep(usecs);
 	}
 
-	if (logfile != NULL)
-		(void)logpid(logfile, 0);
+	if (logfile != NULL && logpid(logfile, 0))
+		ret = 1;
+
+	if ((errno = db_appexit(dbenv)) != 0) {
+		ret = 1;
+		warn(NULL);
+	}
 
 	if (interrupted) {
 		(void)signal(interrupted, SIG_DFL);
@@ -148,7 +157,7 @@ main(argc, argv)
 		/* NOTREACHED */
 	}
 
-	return (db_appexit(dbenv));
+	return (ret);
 }
 
 DB_ENV *
@@ -170,8 +179,6 @@ db_init(home, verbose)
 	    NULL, dbenv, DB_INIT_LOCK | DB_USE_ENVIRON)) != 0)
 		err(1, "db_appinit");
 
-	siginit();
-
 	return (dbenv);
 }
 
@@ -214,14 +221,11 @@ siginit()
 	(void)signal(SIGHUP, onint);
 #endif
 	(void)signal(SIGINT, onint);
-#ifdef SIGKILL
-	(void)signal(SIGKILL, onint);
-#endif
 	(void)signal(SIGTERM, onint);
 }
 
 /*
- * oninit --
+ * onint --
  *	Interrupt signal handler.
  */
 void
diff --git a/db2/progs/db_dump/db_dump.c b/db2/progs/db_dump/db_dump.c
index f532bc2779..0f34ddc789 100644
--- a/db2/progs/db_dump/db_dump.c
+++ b/db2/progs/db_dump/db_dump.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_dump.c	10.19 (Sleepycat) 5/23/98";
+static const char sccsid[] = "@(#)db_dump.c	10.24 (Sleepycat) 11/22/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -25,14 +25,14 @@ static const char sccsid[] = "@(#)db_dump.c	10.19 (Sleepycat) 5/23/98";
 #include <unistd.h>
 #endif
 
+#undef stat
+
 #include "db_int.h"
 #include "db_page.h"
 #include "btree.h"
 #include "hash.h"
 #include "clib_ext.h"
 
-#undef stat
-
 void	configure __P((char *));
 DB_ENV *db_init __P((char *));
 int	main __P((int, char *[]));
@@ -58,7 +58,7 @@ main(argc, argv)
 
 	home = NULL;
 	checkprint = dflag = 0;
-	while ((ch = getopt(argc, argv, "df:h:p")) != EOF)
+	while ((ch = getopt(argc, argv, "df:h:Np")) != EOF)
 		switch (ch) {
 		case 'd':
 			dflag = 1;
@@ -70,6 +70,9 @@ main(argc, argv)
 		case 'h':
 			home = optarg;
 			break;
+		case 'N':
+			(void)db_value_set(0, DB_MUTEXLOCKS);
+			break;
 		case 'p':
 			checkprint = 1;
 			break;
@@ -83,16 +86,11 @@ main(argc, argv)
 	if (argc != 1)
 		usage();
 
-	if (dflag) {
-		if (home != NULL)
-			errx(1,
-			    "the -d and -h options may not both be specified");
-		if (checkprint)
-			errx(1,
-			    "the -d and -p options may not both be specified");
-	}
+	if (dflag && checkprint)
+		errx(1, "the -d and -p options may not both be specified");
+
 	/* Initialize the environment. */
-	dbenv = dflag ? NULL : db_init(home);
+	dbenv = db_init(home);
 
 	/* Open the DB file. */
 	if ((errno =
@@ -108,7 +106,7 @@ main(argc, argv)
 	}
 
 	/* Get a cursor and step through the database. */
-	if ((errno = dbp->cursor(dbp, NULL, &dbcp)) != 0) {
+	if ((errno = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
 		(void)dbp->close(dbp, 0);
 		err(1, "cursor");
 	}
@@ -145,16 +143,35 @@ db_init(home)
 {
 	DB_ENV *dbenv;
 
-	if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
+	if ((dbenv = (DB_ENV *)calloc(1, sizeof(DB_ENV))) == NULL) {
 		errno = ENOMEM;
 		err(1, NULL);
 	}
+
+	/*
+	 * Try and use the shared mpool region so that we get pages that
+	 * haven't been flushed to disk (mostly useful for debugging).
+	 * If that fails, try again, without the DB_INIT_MPOOL flag.
+	 *
+	 * If it works, set the error output options so that future errors
+	 * are correctly reported.
+	 */
+	if ((errno = db_appinit(home,
+	    NULL, dbenv, DB_USE_ENVIRON | DB_INIT_MPOOL)) == 0) {
+		dbenv->db_errfile = stderr;
+		dbenv->db_errpfx = progname;
+		return (dbenv);
+	}
+
+	/* Set the error output options -- this time we want a message. */
+	memset(dbenv, 0, sizeof(*dbenv));
 	dbenv->db_errfile = stderr;
 	dbenv->db_errpfx = progname;
 
-	if ((errno =
-	    db_appinit(home, NULL, dbenv, DB_CREATE | DB_USE_ENVIRON)) != 0)
+	/* Try again, and it's fatal if we fail. */
+	if ((errno = db_appinit(home, NULL, dbenv, DB_USE_ENVIRON)) != 0)
 		err(1, "db_appinit");
+
 	return (dbenv);
 }
 
@@ -167,10 +184,10 @@ pheader(dbp, pflag)
 	DB *dbp;
 	int pflag;
 {
+	DBC *dbc;
 	DB_BTREE_STAT *btsp;
-	HTAB *hashp;
-	HASHHDR *hdr;
-	db_pgno_t pgno;
+	HASH_CURSOR *hcp;
+	int ret;
 
 	printf("format=%s\n", pflag ? "print" : "bytevalue");
 	switch (dbp->type) {
@@ -187,18 +204,25 @@ pheader(dbp, pflag)
 		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);
+		if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
+			break;
+		hcp = (HASH_CURSOR *)dbc->internal;
+		GET_META(dbp, hcp, ret);
+		if (ret == 0) {
+			if (hcp->hdr->ffactor != 0)
+				printf("h_ffactor=%lu\n",
+				    (u_long)hcp->hdr->ffactor);
+			if (hcp->hdr->nelem != 0)
+				printf("h_nelem=%lu\n",
+				    (u_long)hcp->hdr->nelem);
+			RELEASE_META(dbp, hcp);
 		}
+		(void)dbc->c_close(dbc);
 		break;
 	case DB_RECNO:
 		printf("type=recno\n");
+		if ((errno = dbp->stat(dbp, &btsp, NULL, 0)) != 0)
+			err(1, "dbp->stat");
 		if (F_ISSET(dbp, DB_RE_RENUMBER))
 			printf("renumber=1\n");
 		if (F_ISSET(dbp, DB_RE_FIXEDLEN))
@@ -231,6 +255,6 @@ void
 usage()
 {
 	(void)fprintf(stderr,
-	    "usage: db_dump [-dp] [-f file] [-h home] db_file\n");
+	    "usage: db_dump [-dNp] [-f file] [-h home] db_file\n");
 	exit(1);
 }
diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c
index 84cfb36775..ca30cef342 100644
--- a/db2/progs/db_load/db_load.c
+++ b/db2/progs/db_load/db_load.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_load.c	10.20 (Sleepycat) 6/2/98";
+static const char sccsid[] = "@(#)db_load.c	10.23 (Sleepycat) 10/4/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,6 +19,7 @@ static const char sccsid[] = "@(#)db_load.c	10.20 (Sleepycat) 6/2/98";
 
 #include <errno.h>
 #include <limits.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -37,9 +38,12 @@ int	dbt_rdump __P((DBT *));
 int	dbt_rprint __P((DBT *));
 int	digitize __P((int));
 int	main __P((int, char *[]));
+void	onint __P((int));
 void	rheader __P((DBTYPE *, int *, DB_INFO *));
+void	siginit __P((void));
 void	usage __P((void));
 
+int	 interrupted;
 const char
 	*progname = "db_load";				/* Program name. */
 
@@ -57,16 +61,17 @@ main(argc, argv)
 	DB_INFO dbinfo;
 	db_recno_t recno;
 	u_int32_t db_nooverwrite;
-	int ch, checkprint, existed, no_header;
+	int ch, checkprint, existed, no_header, ret;
 	char **clist, **clp, *home;
 
 	/* Allocate enough room for configuration arguments. */
 	if ((clp = clist = (char **)calloc(argc + 1, sizeof(char *))) == NULL)
 		err(1, NULL);
 
+	dbp = NULL;
 	home = NULL;
 	db_nooverwrite = 0;
-	existed = checkprint = no_header = 0;
+	checkprint = existed = no_header = ret = 0;
 	argtype = dbtype = DB_UNKNOWN;
 	while ((ch = getopt(argc, argv, "c:f:h:nTt:")) != EOF)
 		switch (ch) {
@@ -111,9 +116,6 @@ main(argc, argv)
 	if (argc != 1)
 		usage();
 
-	/* Initialize the environment if the user specified one. */
-	dbenv = home == NULL ? NULL : db_init(home);
-
 	/*
 	 * Read the header.  If there isn't any header, we're expecting flat
 	 * text, set the checkprint flag appropriately.
@@ -128,21 +130,17 @@ main(argc, argv)
 			if ((dbtype == DB_RECNO && argtype != DB_RECNO) ||
 			    (argtype == DB_RECNO && dbtype != DB_RECNO))
 				errx(1,
-			    "databases of type recno may not be converted");
+				"databases of type recno may not be converted");
 			dbtype = argtype;
 		}
 	}
+
 	if (dbtype == DB_UNKNOWN)
 		errx(1, "no database type specified");
 
 	/* Apply command-line configuration changes. */
 	configure(&dbinfo, clist);
 
-	/* Open the DB file. */
-	if ((errno = db_open(argv[0], dbtype, DB_CREATE,
-	    __db_omode("rwrwrw"), dbenv, &dbinfo, &dbp)) != 0)
-		err(1, "%s", argv[0]);
-
 	/* Initialize the key/data pair. */
 	memset(&key, 0, sizeof(DBT));
 	if (dbtype == DB_RECNO) {
@@ -159,9 +157,20 @@ main(argc, argv)
 		err(1, NULL);
 	}
 
+	/* Initialize the environment if the user specified one. */
+	siginit();
+	dbenv = home == NULL ? NULL : db_init(home);
+
+	/* Open the DB file. */
+	if ((errno = db_open(argv[0], dbtype, DB_CREATE,
+	    __db_omode("rwrwrw"), dbenv, &dbinfo, &dbp)) != 0) {
+		warn("%s", argv[0]);
+		goto err;
+	}
+
 	/* Get each key/data pair and add them to the database. */
-	for (recno = 1;; ++recno) {
-		if (dbtype == DB_RECNO) {
+	for (recno = 1; !interrupted; ++recno) {
+		if (dbtype == DB_RECNO)
 			if (checkprint) {
 				if (dbt_rprint(&data))
 					break;
@@ -169,7 +178,7 @@ main(argc, argv)
 				if (dbt_rdump(&data))
 					break;
 			}
-		} else
+		else
 			if (checkprint) {
 				if (dbt_rprint(&key))
 					break;
@@ -178,8 +187,10 @@ main(argc, argv)
 			} else {
 				if (dbt_rdump(&key))
 					break;
-				if (dbt_rdump(&data))
-fmt:					err(1, "odd number of key/data pairs");
+				if (dbt_rdump(&data)) {
+fmt:					warnx("odd number of key/data pairs");
+					goto err;
+				}
 			}
 		switch (errno =
 		    dbp->put(dbp, NULL, &key, &data, db_nooverwrite)) {
@@ -190,17 +201,36 @@ fmt:					err(1, "odd number of key/data pairs");
 			warnx("%s: line %d: key already exists, not loaded:",
 			    argv[0],
 			    dbtype == DB_RECNO ? recno : recno * 2 - 1);
+
 			(void)__db_prdbt(&key, checkprint, stderr);
 			break;
 		default:
-			err(1, "%s", argv[0]);
-			/* NOTREACHED */
+			warn(NULL);
+			goto err;
 		}
 	}
 
-	if ((errno = dbp->close(dbp, 0)) != 0)
-		err(1, "%s", argv[0]);
-	return (existed ? 1 : 0);
+	if (0) {
+err:		ret = 1;
+	}
+	if (dbp != NULL && (errno = dbp->close(dbp, 0)) != 0) {
+		ret = 1;
+		warn(NULL);
+	}
+
+	if (dbenv != NULL && (errno = db_appexit(dbenv)) != 0) {
+		ret = 1;
+		warn(NULL);
+	}
+
+	if (interrupted) {
+		(void)signal(interrupted, SIG_DFL);
+		(void)raise(interrupted);
+		/* NOTREACHED */
+	}
+
+	/* Return 0 on success, 1 if keys existed already, and 2 on failure. */
+	return (ret == 0 ? (existed == 0 ? 0 : 1) : 2);
 }
 
 /*
@@ -499,6 +529,34 @@ badnum()
 }
 
 /*
+ * 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);
+	(void)signal(SIGTERM, onint);
+}
+
+/*
+ * onint --
+ *	Interrupt signal handler.
+ */
+void
+onint(signo)
+	int signo;
+{
+	if ((interrupted = signo) == 0)
+		interrupted = SIGINT;
+}
+
+/*
  * usage --
  *	Display the usage message.
  */
diff --git a/db2/progs/db_printlog/README b/db2/progs/db_printlog/README
new file mode 100644
index 0000000000..05051f33cd
--- /dev/null
+++ b/db2/progs/db_printlog/README
@@ -0,0 +1,22 @@
+# @(#)README	10.3 (Sleepycat) 11/1/98
+
+Berkeley DB log dump utility.  This utility dumps out a DB log in human
+readable form, a record at a time, to assist in recovery and transaction
+abort debugging.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+commit.awk	Output transaction ID of committed transactions.
+
+count.awk	Print out the number of log records for transactions
+		that we encountered.
+
+pgno.awk	Take a comma-separated list of page numbers and spit
+		out all the log records that affect those page numbers.
+
+range.awk	Print out a range of the log.
+
+status.awk	Read through db_printlog output and list the transactions
+		encountered, and whether they commited or aborted.
+
+txn.awk		Print out all the records for a comma-separated list of
+		transaction IDs.
diff --git a/db2/progs/db_printlog/commit.awk b/db2/progs/db_printlog/commit.awk
new file mode 100644
index 0000000000..711064bb00
--- /dev/null
+++ b/db2/progs/db_printlog/commit.awk
@@ -0,0 +1,7 @@
+# @(#)commit.awk	10.1 (Sleepycat) 11/1/98
+#
+# Output tid of committed transactions.
+
+/txn_regop/ {
+	print $5
+}
diff --git a/db2/progs/db_printlog/count.awk b/db2/progs/db_printlog/count.awk
new file mode 100644
index 0000000000..a0b214a6ff
--- /dev/null
+++ b/db2/progs/db_printlog/count.awk
@@ -0,0 +1,9 @@
+# @(#)count.awk	10.1 (Sleepycat) 11/1/98
+#
+# Print out the number of log records for transactions that we
+# encountered.
+
+/^\[/{
+	if ($5 != 0)
+		print $5
+}
diff --git a/db2/progs/db_printlog/db_printlog.c b/db2/progs/db_printlog/db_printlog.c
index 3b48ad9643..5a0c2ebd9f 100644
--- a/db2/progs/db_printlog/db_printlog.c
+++ b/db2/progs/db_printlog/db_printlog.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_printlog.c	10.12 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)db_printlog.c	10.17 (Sleepycat) 11/1/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,6 +19,7 @@ static const char sccsid[] = "@(#)db_printlog.c	10.12 (Sleepycat) 4/10/98";
 
 #include <errno.h>
 #include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -37,6 +38,7 @@ static const char sccsid[] = "@(#)db_printlog.c	10.12 (Sleepycat) 4/10/98";
 DB_ENV *db_init __P((char *));
 int	main __P((int, char *[]));
 void	onint __P((int));
+void	siginit __P((void));
 void	usage __P((void));
 
 int	 interrupted;
@@ -53,15 +55,19 @@ main(argc, argv)
 	DB_ENV *dbenv;
 	DBT data;
 	DB_LSN key;
-	int ch, eval;
+	int ch, ret;
 	char *home;
 
+	ret = 0;
 	home = NULL;
-	while ((ch = getopt(argc, argv, "h:")) != EOF)
+	while ((ch = getopt(argc, argv, "h:N")) != EOF)
 		switch (ch) {
 		case 'h':
 			home = optarg;
 			break;
+		case 'N':
+			(void)db_value_set(0, DB_MUTEXLOCKS);
+			break;
 		case '?':
 		default:
 			usage();
@@ -69,54 +75,62 @@ main(argc, argv)
 	argc -= optind;
 	argv += optind;
 
-	if ((home != NULL && argc > 0) || argc > 1)
+	if (argc > 0)
 		usage();
 
-	/* XXX: backward compatibility, first argument is home. */
-	if (argc == 1)
-		home = argv[0];
-
+	/* Initialize the environment. */
+	siginit();
 	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);
+		return (1);
 	}
 
-	(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;
+			goto err;
 		}
-		if ((errno =
-		    __db_dispatch(dbenv->lg_info, &data, &key, 0, NULL)) != 0) {
-			eval = 1;
+		if (dbenv->tx_recover != NULL)
+			errno = dbenv->tx_recover(dbenv->lg_info,
+			    &data, &key, 0, NULL);
+		else
+			errno = __db_dispatch(dbenv->lg_info,
+			    &data, &key, 0, NULL);
+
+		fflush(stdout);
+		if (errno != 0) {
 			warn("dispatch");
-			break;
+			goto err;
 		}
 	}
 
-	(void)db_appexit(dbenv);
+	if (0) {
+err:		ret = 1;
+	}
+
+	if (dbenv != NULL && (errno = db_appexit(dbenv)) != 0) {
+		ret = 1;
+		warn(NULL);
+	}
 
 	if (interrupted) {
-		(void)signal(SIGINT, SIG_DFL);
-		(void)raise(SIGINT);
+		(void)signal(interrupted, SIG_DFL);
+		(void)raise(interrupted);
 		/* NOTREACHED */
 	}
-	return (eval);
+
+	return (ret);
 }
 
 /*
@@ -143,21 +157,36 @@ db_init(home)
 }
 
 /*
- * oninit --
+ * 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);
+	(void)signal(SIGTERM, onint);
+}
+
+/*
+ * onint --
  *	Interrupt signal handler.
  */
 void
 onint(signo)
 	int signo;
 {
-	COMPQUIET(signo, 0);
-
-	interrupted = 1;
+	if ((interrupted = signo) == 0)
+		interrupted = SIGINT;
 }
 
 void
 usage()
 {
-	fprintf(stderr, "usage: db_printlog [-h home]\n");
+	fprintf(stderr, "usage: db_printlog [-N] [-h home]\n");
 	exit (1);
 }
diff --git a/db2/progs/db_printlog/pgno.awk b/db2/progs/db_printlog/pgno.awk
new file mode 100644
index 0000000000..99aa38f2b9
--- /dev/null
+++ b/db2/progs/db_printlog/pgno.awk
@@ -0,0 +1,43 @@
+# @(#)pgno.awk	10.1 (Sleepycat) 11/1/98
+#
+# Take a comma-separated list of page numbers and spit out all the
+# log records that affect those page numbers.
+
+{
+	if (NR == 1) {
+		npages = 0
+		while ((ndx = index(PGNO, ",")) != 0) {
+			pgno[npages] = substr(PGNO, 1, ndx - 1);
+			PGNO = substr(PGNO, ndx + 1, length(PGNO) - ndx);
+			npages++
+		}
+		pgno[npages] = PGNO;
+	}
+}
+/^\[/{
+	if (printme == 1) {
+		printf("%s\n", rec);
+		printme = 0
+	}
+	rec = "";
+
+	rec = $0
+}
+/^	/{
+	rec = sprintf("%s\n%s", rec, $0);
+}
+/pgno/{
+	for (i = 0; i <= npages; i++)
+		if ($2 == pgno[i])
+			printme = 1
+}
+/right/{
+	for (i = 0; i <= npages; i++)
+		if ($2 == pgno[i])
+			printme = 1
+}
+/left/{
+	for (i = 0; i <= npages; i++)
+		if ($2 == pgno[i])
+			printme = 1
+}
diff --git a/db2/progs/db_printlog/range.awk b/db2/progs/db_printlog/range.awk
new file mode 100644
index 0000000000..89c56eae52
--- /dev/null
+++ b/db2/progs/db_printlog/range.awk
@@ -0,0 +1,27 @@
+# @(#)range.awk	10.1 (Sleepycat) 11/1/98
+#
+# Print out a range of the log
+
+/^\[/{
+	l = length($1) - 1;
+	i = index($1, "]");
+	file = substr($1, 2, i - 2);
+	file += 0;
+	start = i + 2;
+	offset = substr($1, start, l - start + 1);
+	i = index(offset, "]");
+	offset = substr($1, start, i - 1);
+	offset += 0;
+
+	if ((file == START_FILE && offset >= START_OFFSET || file > START_FILE)\
+	    && (file < END_FILE || (file == END_FILE && offset < END_OFFSET)))
+		printme = 1
+	else if (file == END_FILE && offset > END_OFFSET || file > END_FILE)
+		exit
+	else
+		printme = 0
+}
+{
+	if (printme == 1)
+		print $0
+}
diff --git a/db2/progs/db_printlog/status.awk b/db2/progs/db_printlog/status.awk
new file mode 100644
index 0000000000..d97e9357b7
--- /dev/null
+++ b/db2/progs/db_printlog/status.awk
@@ -0,0 +1,26 @@
+# @(#)status.awk	10.1 (Sleepycat) 11/1/98
+#
+# Read through db_printlog output and list all the transactions encountered
+# and whether they commited or aborted.
+#
+# 1 = started
+# 2 = commited
+BEGIN {
+	cur_txn = 0
+}
+/^\[/{
+	if (status[$5] == 0) {
+		status[$5] = 1;
+		txns[cur_txn] = $5;
+		cur_txn++;
+	}
+}
+/txn_regop/ {
+	status[$5] = 2
+}
+END {
+	for (i = 0; i < cur_txn; i++) {
+		printf("%s\t%s\n",
+		    txns[i], status[txns[i]] == 1 ? "ABORT" : "COMMIT");
+	}
+}
diff --git a/db2/progs/db_printlog/txn.awk b/db2/progs/db_printlog/txn.awk
new file mode 100644
index 0000000000..c8d3bd36c8
--- /dev/null
+++ b/db2/progs/db_printlog/txn.awk
@@ -0,0 +1,30 @@
+# @(#)txn.awk	10.1 (Sleepycat) 11/1/98
+#
+# Print out all the records for a comma-separated list of transaction ids.
+{
+	if (NR == 1) {
+		ntxns = 0
+		while ((ndx = index(TXN, ",")) != 0) {
+			txn[ntxns] = substr(TXN, 1, ndx - 1);
+			TXN = substr(TXN, ndx + 1, length(TXN) - ndx);
+			ntxns++
+		}
+		txn[ntxns] = TXN;
+	}
+}
+/^\[/{
+	if (printme == 1) {
+		printf("%s\n", rec);
+		printme = 0
+	}
+	rec = "";
+
+	for (i = 0; i <= ntxns; i++)
+		if (txn[i] == $5) {
+			rec = $0
+			printme = 1
+		}
+}
+/^	/{
+	rec = sprintf("%s\n%s", rec, $0);
+}
diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c
index a2845725b8..d946ca15ee 100644
--- a/db2/progs/db_recover/db_recover.c
+++ b/db2/progs/db_recover/db_recover.c
@@ -11,13 +11,14 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_recover.c	10.19 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)db_recover.c	10.23 (Sleepycat) 10/5/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
 #include <sys/types.h>
 
 #include <errno.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <time.h>
 #include <unistd.h>
@@ -31,6 +32,7 @@ static const char sccsid[] = "@(#)db_recover.c	10.19 (Sleepycat) 4/10/98";
 
 DB_ENV	*db_init __P((char *, u_int32_t, int));
 int	 main __P((int, char *[]));
+void	 nosig __P((void));
 void	 usage __P((void));
 
 const char
@@ -72,10 +74,15 @@ main(argc, argv)
 	if (argc != 0)
 		usage();
 
+	/*
+	 * Ignore signals -- we don't want to be interrupted because we're
+	 * spending all of our time in the DB library.
+	 */
+	nosig();
 	dbenv = db_init(home, flags, verbose);
 	if (verbose) {
 		__db_err(dbenv, "Recovery complete at %.24s", ctime(&now));
-		__db_err(dbenv, "%s %lu %s [%lu][%lu]",
+		__db_err(dbenv, "%s %lx %s [%lu][%lu]",
 		    "Maximum transaction id",
 		    (u_long)dbenv->tx_info->region->last_txnid,
 		    "Recovery checkpoint",
@@ -118,6 +125,20 @@ db_init(home, flags, verbose)
 	return (dbenv);
 }
 
+/*
+ * nosig --
+ *	We don't want to be interrupted.
+ */
+void
+nosig()
+{
+#ifdef SIGHUP
+	(void)signal(SIGHUP, SIG_IGN);
+#endif
+	(void)signal(SIGINT, SIG_IGN);
+	(void)signal(SIGTERM, SIG_IGN);
+}
+
 void
 usage()
 {
diff --git a/db2/progs/db_stat/db_stat.c b/db2/progs/db_stat/db_stat.c
index f2551805b0..cef645da00 100644
--- a/db2/progs/db_stat/db_stat.c
+++ b/db2/progs/db_stat/db_stat.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_stat.c	8.38 (Sleepycat) 5/30/98";
+static const char sccsid[] = "@(#)db_stat.c	8.41 (Sleepycat) 10/3/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -26,6 +26,8 @@ static const char sccsid[] = "@(#)db_stat.c	8.38 (Sleepycat) 5/30/98";
 #include <unistd.h>
 #endif
 
+#undef stat
+
 #include "db_int.h"
 #include "shqueue.h"
 #include "db_shash.h"
@@ -33,8 +35,6 @@ static const char sccsid[] = "@(#)db_stat.c	8.38 (Sleepycat) 5/30/98";
 #include "mp.h"
 #include "clib_ext.h"
 
-#undef stat
-
 typedef enum { T_NOTSET, T_DB, T_LOCK, T_LOG, T_MPOOL, T_TXN } test_t;
 
 int	argcheck __P((char *, const char *));
@@ -48,13 +48,12 @@ void	log_stats __P((DB_ENV *));
 int	main __P((int, char *[]));
 int	mpool_ok __P((char *));
 void	mpool_stats __P((DB_ENV *));
-void	onint __P((int));
+void	nosig __P((void));
 void	prflags __P((u_int32_t, const FN *));
 int	txn_compare __P((const void *, const void *));
 void	txn_stats __P((DB_ENV *));
 void	usage __P((void));
 
-int	 interrupted;
 char	*internal;
 const char
 	*progname = "db_stat";				/* Program name. */
@@ -118,15 +117,20 @@ main(argc, argv)
 	if (argc != 0 || ttype == T_NOTSET)
 		usage();
 
+	/*
+	 * Ignore signals -- we don't want to be interrupted because we're
+	 * spending all of our time in the DB library.
+	 */
+	nosig();
 	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)
+		    DB_RDONLY, 0, dbenv, NULL, &dbp)) != 0) {
+			warn("%s", db);
 			return (1);
+		}
 		switch (dbp->type) {
 		case DB_BTREE:
 		case DB_RECNO:
@@ -158,12 +162,9 @@ main(argc, argv)
 		/* NOTREACHED */
 	}
 
-	(void)db_appexit(dbenv);
-
-	if (interrupted) {
-		(void)signal(SIGINT, SIG_DFL);
-		(void)raise(SIGINT);
-		/* NOTREACHED */
+	if ((errno = db_appexit(dbenv)) != 0) {
+		warn(NULL);
+		return (1);
 	}
 	return (0);
 }
@@ -218,7 +219,6 @@ btree_stats(dbp)
 	dl("Number of tree duplicate pages.\n", (u_long)sp->bt_dup_pg);
 	dl("Number of tree overflow pages.\n", (u_long)sp->bt_over_pg);
 	dl("Number of pages on the free list.\n", (u_long)sp->bt_free);
-	dl("Number of pages freed for reuse.\n", (u_long)sp->bt_freed);
 	dl("Number of bytes free in tree internal pages",
 	    (u_long)sp->bt_int_pgfree);
 	printf(" (%.0f%% ff).\n", PCT(sp->bt_int_pgfree, sp->bt_int_pg));
@@ -231,17 +231,6 @@ btree_stats(dbp)
 	dl("Number of bytes free in tree overflow pages",
 	    (u_long)sp->bt_over_pgfree);
 	printf(" (%.0f%% ff).\n", PCT(sp->bt_over_pgfree, sp->bt_over_pg));
-	dl("Number of bytes saved by prefix compression.\n",
-	    (u_long)sp->bt_pfxsaved);
-	dl("Total number of tree page splits.\n", (u_long)sp->bt_split);
-	dl("Number of root page splits.\n", (u_long)sp->bt_rootsplit);
-	dl("Number of fast splits.\n", (u_long)sp->bt_fastsplit);
-	dl("Number of hits in tree fast-insert code.\n",
-	    (u_long)sp->bt_cache_hit);
-	dl("Number of misses in tree fast-insert code.\n",
-	    (u_long)sp->bt_cache_miss);
-	dl("Number of keys added.\n", (u_long)sp->bt_added);
-	dl("Number of keys deleted.\n", (u_long)sp->bt_deleted);
 }
 
 /*
@@ -610,16 +599,17 @@ argcheck(arg, ok_args)
 }
 
 /*
- * oninit --
- *	Interrupt signal handler.
+ * nosig --
+ *	We don't want to be interrupted.
  */
 void
-onint(signo)
-	int signo;
+nosig()
 {
-	COMPQUIET(signo, 0);
-
-	interrupted = 1;
+#ifdef SIGHUP
+	(void)signal(SIGHUP, SIG_IGN);
+#endif
+	(void)signal(SIGINT, SIG_IGN);
+	(void)signal(SIGTERM, SIG_IGN);
 }
 
 void