From 8198f031f33a76050851ad483da96e933653bbfb Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@symas.com>
Date: Sun, 19 Nov 2017 19:48:01 +0000
Subject: [PATCH] Add mdb_drop tool

---
 external/db_drivers/liblmdb/Makefile   |   5 +-
 external/db_drivers/liblmdb/mdb_drop.1 |  40 ++++++++
 external/db_drivers/liblmdb/mdb_drop.c | 135 +++++++++++++++++++++++++
 external/db_drivers/liblmdb/tooltag    |   5 +
 4 files changed, 183 insertions(+), 2 deletions(-)
 create mode 100644 external/db_drivers/liblmdb/mdb_drop.1
 create mode 100644 external/db_drivers/liblmdb/mdb_drop.c

diff --git a/external/db_drivers/liblmdb/Makefile b/external/db_drivers/liblmdb/Makefile
index f3c93a2ff..42a5f034a 100644
--- a/external/db_drivers/liblmdb/Makefile
+++ b/external/db_drivers/liblmdb/Makefile
@@ -38,8 +38,8 @@ mandir = $(datarootdir)/man
 
 IHDRS	= lmdb.h
 ILIBS	= liblmdb.a liblmdb.so
-IPROGS	= mdb_stat mdb_copy mdb_dump mdb_load
-IDOCS	= mdb_stat.1 mdb_copy.1 mdb_dump.1 mdb_load.1
+IPROGS	= mdb_stat mdb_copy mdb_dump mdb_load mdb_drop
+IDOCS	= mdb_stat.1 mdb_copy.1 mdb_dump.1 mdb_load.1 mdb_drop.1
 PROGS	= $(IPROGS) mtest mtest2 mtest3 mtest4 mtest5
 all:	$(ILIBS) $(PROGS)
 
@@ -71,6 +71,7 @@ mdb_stat: mdb_stat.o liblmdb.a
 mdb_copy: mdb_copy.o liblmdb.a
 mdb_dump: mdb_dump.o liblmdb.a
 mdb_load: mdb_load.o liblmdb.a
+mdb_drop: mdb_drop.o liblmdb.a
 mtest:    mtest.o    liblmdb.a
 mtest2:	mtest2.o liblmdb.a
 mtest3:	mtest3.o liblmdb.a
diff --git a/external/db_drivers/liblmdb/mdb_drop.1 b/external/db_drivers/liblmdb/mdb_drop.1
new file mode 100644
index 000000000..997e29118
--- /dev/null
+++ b/external/db_drivers/liblmdb/mdb_drop.1
@@ -0,0 +1,40 @@
+.TH MDB_DROP 1 "2017/11/19" "LMDB 0.9.70"
+.\" Copyright 2014-2017 Howard Chu, Symas Corp. All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+mdb_drop \- LMDB database delete tool
+.SH SYNOPSIS
+.B mdb_drop
+[\c
+.BR \-V ]
+[\c
+.BR \-n ]
+[\c
+.BR \-d ]
+[\c
+.BI \-s \ subdb\fR]
+.BR \ envpath
+.SH DESCRIPTION
+The
+.B mdb_drop
+utility empties or deletes a database in the specified
+environment.
+.SH OPTIONS
+.TP
+.BR \-V
+Write the library version number to the standard output, and exit.
+.TP
+.BR \-n
+Operate on an LMDB database which does not use subdirectories.
+.TP
+.BR \-d
+Delete the specified database, don't just empty it.
+.TP
+.BR \-s \ subdb
+Operate on a specific subdatabase. If no database is specified, only the main database is dropped.
+.SH DIAGNOSTICS
+Exit status is zero if no errors occur.
+Errors result in a non-zero exit status and
+a diagnostic message being written to standard error.
+.SH AUTHOR
+Howard Chu of Symas Corporation <http://www.symas.com>
diff --git a/external/db_drivers/liblmdb/mdb_drop.c b/external/db_drivers/liblmdb/mdb_drop.c
new file mode 100644
index 000000000..725891685
--- /dev/null
+++ b/external/db_drivers/liblmdb/mdb_drop.c
@@ -0,0 +1,135 @@
+/* mdb_drop.c - memory-mapped database delete tool */
+/*
+ * Copyright 2016-2017 Howard Chu, Symas Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <signal.h>
+#include "lmdb.h"
+
+static volatile sig_atomic_t gotsig;
+
+static void dumpsig( int sig )
+{
+	gotsig=1;
+}
+
+static void usage(char *prog)
+{
+	fprintf(stderr, "usage: %s [-V] [-n] [-d] [-s subdb] dbpath\n", prog);
+	exit(EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[])
+{
+	int i, rc;
+	MDB_env *env;
+	MDB_txn *txn;
+	MDB_dbi dbi;
+	char *prog = argv[0];
+	char *envname;
+	char *subname = NULL;
+	int envflags = 0, delete = 0;
+
+	if (argc < 2) {
+		usage(prog);
+	}
+
+	/* -d: delete the db, don't just empty it
+	 * -s: drop the named subDB
+	 * -n: use NOSUBDIR flag on env_open
+	 * -V: print version and exit
+	 * (default) empty the main DB
+	 */
+	while ((i = getopt(argc, argv, "dns:V")) != EOF) {
+		switch(i) {
+		case 'V':
+			printf("%s\n", MDB_VERSION_STRING);
+			exit(0);
+			break;
+		case 'd':
+			delete = 1;
+			break;
+		case 'n':
+			envflags |= MDB_NOSUBDIR;
+			break;
+		case 's':
+			subname = optarg;
+			break;
+		default:
+			usage(prog);
+		}
+	}
+
+	if (optind != argc - 1)
+		usage(prog);
+
+#ifdef SIGPIPE
+	signal(SIGPIPE, dumpsig);
+#endif
+#ifdef SIGHUP
+	signal(SIGHUP, dumpsig);
+#endif
+	signal(SIGINT, dumpsig);
+	signal(SIGTERM, dumpsig);
+
+	envname = argv[optind];
+	rc = mdb_env_create(&env);
+	if (rc) {
+		fprintf(stderr, "mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc));
+		return EXIT_FAILURE;
+	}
+
+	mdb_env_set_maxdbs(env, 2);
+
+	rc = mdb_env_open(env, envname, envflags, 0664);
+	if (rc) {
+		fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
+		goto env_close;
+	}
+
+	rc = mdb_txn_begin(env, NULL, 0, &txn);
+	if (rc) {
+		fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
+		goto env_close;
+	}
+
+	rc = mdb_open(txn, subname, 0, &dbi);
+	if (rc) {
+		fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
+		goto txn_abort;
+	}
+
+	rc = mdb_drop(txn, dbi, delete);
+	if (rc) {
+		fprintf(stderr, "mdb_drop failed, error %d %s\n", rc, mdb_strerror(rc));
+		goto txn_abort;
+	}
+	rc = mdb_txn_commit(txn);
+	if (rc) {
+		fprintf(stderr, "mdb_txn_commit failed, error %d %s\n", rc, mdb_strerror(rc));
+		goto txn_abort;
+	}
+	txn = NULL;
+
+txn_abort:
+	if (txn)
+		mdb_txn_abort(txn);
+env_close:
+	mdb_env_close(env);
+
+	return rc ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/external/db_drivers/liblmdb/tooltag b/external/db_drivers/liblmdb/tooltag
index 229bf16ba..879c14d22 100644
--- a/external/db_drivers/liblmdb/tooltag
+++ b/external/db_drivers/liblmdb/tooltag
@@ -4,6 +4,11 @@
 	<title>mdb_copy - environment copy tool</title>
 	<filename>mdb_copy.1</filename>
   </compound>
+  <compound kind="page">
+    <name>mdb_drop_1</name>
+	<title>mdb_drop - database delete tool</title>
+	<filename>mdb_drop.1</filename>
+  </compound>
   <compound kind="page">
     <name>mdb_dump_1</name>
 	<title>mdb_dump - environment export tool</title>