From 3dcacadf03a7cf272f1618b981b08121504e131a Mon Sep 17 00:00:00 2001
From: Jonathan McDowell <noodles@earth.li>
Date: Sat, 23 Oct 2004 16:58:31 +0000
Subject: [PATCH] Move dumpdb over to using iterate_keys. iterate_keys provides
 a generic way to do stuff with every key in the DB, so use it instead for
 dumping the database and remove the old dumpdb function.

---
 keydb.h      | 12 -----------
 keydb_db2.c  | 15 -------------
 keydb_db4.c  | 59 ----------------------------------------------------
 keydb_file.c | 16 --------------
 keydb_fs.c   |  9 --------
 keydb_keyd.c | 15 -------------
 keydb_pg.c   | 15 -------------
 onak.c       | 49 ++++++++++++++++++++++++++++++++++++++++++-
 8 files changed, 48 insertions(+), 142 deletions(-)

diff --git a/keydb.h b/keydb.h
index 98cf34d..4406223 100644
--- a/keydb.h
+++ b/keydb.h
@@ -151,18 +151,6 @@ struct ll *cached_getkeysigs(uint64_t keyid);
  */
 uint64_t getfullkeyid(uint64_t keyid);
 
-/**
- *	dumpdb - dump the key database
- *	@filenamebase: The base filename to use for the dump.
- *
- *	Dumps the database into one or more files, which contain pure OpenPGP
- *	that can be reimported into onak or gpg. filenamebase provides a base
- *	file name for the dump; several files may be created, all of which will
- *	begin with this string and then have a unique number and a .pgp
- *	extension.
- */
-int dumpdb(char *filenamebase);
-
 /**
  *	iterate_keys - call a function once for each key in the db.
  *	@iterfunc: The function to call.
diff --git a/keydb_db2.c b/keydb_db2.c
index f9ca04b..affdc4b 100644
--- a/keydb_db2.c
+++ b/keydb_db2.c
@@ -249,21 +249,6 @@ int delete_key(uint64_t keyid, bool intrans)
 	return (1);
 }
 
-/**
- *	dumpdb - dump the key database
- *	@filenamebase: The base filename to use for the dump.
- *
- *	Dumps the database into one or more files, which contain pure OpenPGP
- *	that can be reimported into onak or gpg. filenamebase provides a base
- *	file name for the dump; several files may be created, all of which will
- *	begin with this string and then have a unique number and a .pgp
- *	extension.
- *          */
-int dumpdb(char *filenamebase)
-{
-	return 0;
-}
-
 /**
  *	iterate_keys - call a function once for each key in the db.
  *	@iterfunc: The function to call.
diff --git a/keydb_db4.c b/keydb_db4.c
index 1daf00b..6d57cd3 100644
--- a/keydb_db4.c
+++ b/keydb_db4.c
@@ -939,65 +939,6 @@ int delete_key(uint64_t keyid, bool intrans)
 	return deadlock ? (-1) : (ret == DB_NOTFOUND);
 }
 
-/**
- *	dumpdb - dump the key database
- *	@filenamebase: The base filename to use for the dump.
- *
- *	Dumps the database into one or more files, which contain pure OpenPGP
- *	that can be reimported into onak or gpg. filenamebase provides a base
- *	file name for the dump; several files may be created, all of which will
- *	begin with this string and then have a unique number and a .pgp
- *	extension.
- */
-int dumpdb(char *filenamebase)
-{
-	DBT   key, data;
-	DBC  *cursor = NULL;
-	int   ret = 0;
-	int   fd = -1;
-	int   i = 0;
-	char  filename[1024];
-
-	filename[1023] = 0;
-	for (i = 0; i < numdbs; i++) {
-		ret = dbconns[i]->cursor(dbconns[i],
-			NULL,
-			&cursor,
-			0);   /* flags */
-
-		snprintf(filename, 1023, "%s.%d.pgp", filenamebase, i);
-		fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0640);
-		if (fd == -1) {
-			logthing(LOGTHING_ERROR,
-				"Error opening keydump file (%s): %s",
-				filename,
-				strerror(errno));
-		} else {
-			memset(&key, 0, sizeof(key));
-			memset(&data, 0, sizeof(data));
-			ret = cursor->c_get(cursor, &key, &data, DB_NEXT);
-			while (ret == 0) {
-				write(fd, data.data, data.size);
-				memset(&key, 0, sizeof(key));
-				memset(&data, 0, sizeof(data));
-				ret = cursor->c_get(cursor, &key, &data,
-						DB_NEXT);
-			}
-			if (ret != DB_NOTFOUND) {
-				logthing(LOGTHING_ERROR,
-					"Problem reading key: %s",
-					db_strerror(ret));
-			}
-			close(fd);
-		}
-
-		ret = cursor->c_close(cursor);
-		cursor = NULL;
-	}
-	
-	return 0;
-}
-
 /**
  *	iterate_keys - call a function once for each key in the db.
  *	@iterfunc: The function to call.
diff --git a/keydb_file.c b/keydb_file.c
index 1ef81b4..a0c9032 100644
--- a/keydb_file.c
+++ b/keydb_file.c
@@ -228,22 +228,6 @@ int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key),
 	return numkeys;
 }
 
-
-/**
- *	dumpdb - dump the key database
- *	@filenamebase: The base filename to use for the dump.
- *
- *	Dumps the database into one or more files, which contain pure OpenPGP
- *	that can be reimported into onak or gpg. filenamebase provides a base
- *	file name for the dump; several files may be created, all of which will
- *	begin with this string and then have a unique number and a .pgp
- *	extension.
- *          */
-int dumpdb(char *filenamebase)
-{
-	return 0;
-}
-
 /*
  * Include the basic keydb routines.
  */
diff --git a/keydb_fs.c b/keydb_fs.c
index 1c5d14c..14220d1 100644
--- a/keydb_fs.c
+++ b/keydb_fs.c
@@ -485,15 +485,6 @@ int fetch_key_text(const char *search,
 	return addedkeys;
 }
 
-/*
- *	dumpdb - dump the key database
- *	@filenamebase: The base filename to use for the dump.
- */
-int dumpdb(char *filenamebase)
-{
-	return 0;
-}
-
 uint64_t getfullkeyid(uint64_t keyid)
 {
 	static char buffer[PATH_MAX];
diff --git a/keydb_keyd.c b/keydb_keyd.c
index fac5548..26cb326 100644
--- a/keydb_keyd.c
+++ b/keydb_keyd.c
@@ -341,21 +341,6 @@ uint64_t getfullkeyid(uint64_t keyid)
 	return keyid;
 }
 
-/**
- *	dumpdb - dump the key database
- *	@filenamebase: The base filename to use for the dump.
- *
- *	Dumps the database into one or more files, which contain pure OpenPGP
- *	that can be reimported into onak or gpg. filenamebase provides a base
- *	file name for the dump; several files may be created, all of which will
- *	begin with this string and then have a unique number and a .pgp
- *	extension.
- */
-int dumpdb(char *filenamebase)
-{
-	return 0;
-}
-
 /**
  *	iterate_keys - call a function once for each key in the db.
  *	@iterfunc: The function to call.
diff --git a/keydb_pg.c b/keydb_pg.c
index afdbb23..5933c91 100644
--- a/keydb_pg.c
+++ b/keydb_pg.c
@@ -567,21 +567,6 @@ struct ll *getkeysigs(uint64_t keyid, bool *revoked)
 	return sigs;
 }
 
-/**
- *	dumpdb - dump the key database
- *	@filenamebase: The base filename to use for the dump.
- *
- *	Dumps the database into one or more files, which contain pure OpenPGP
- *	that can be reimported into onak or gpg. filenamebase provides a base
- *	file name for the dump; several files may be created, all of which will
- *	begin with this string and then have a unique number and a .pgp
- *	extension.
- *          */
-int dumpdb(char *filenamebase)
-{
-	return 0;
-}
-
 /**
  *	iterate_keys - call a function once for each key in the db.
  *	@iterfunc: The function to call.
diff --git a/onak.c b/onak.c
index e79e565..4e63720 100644
--- a/onak.c
+++ b/onak.c
@@ -8,10 +8,13 @@
  * Copyright 2002 Project Purple
  */
 
+#include <fcntl.h>
 #include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include "armor.h"
@@ -54,6 +57,41 @@ void find_keys(char *search, uint64_t keyid, bool ishex,
 	}
 }
 
+struct dump_ctx {
+	int count;
+	int maxcount;
+	int fd;
+	int filenum;
+	char *filebase;
+};
+
+void dump_func(void *ctx, struct openpgp_publickey *key)
+{
+	struct openpgp_packet_list *packets = NULL;
+	struct openpgp_packet_list *list_end = NULL;
+	struct dump_ctx *state;
+	char filename[1024];
+
+	state = (struct dump_ctx *) ctx;
+
+	if (state->fd == -1 || state->count > state->maxcount) {
+		if (state->fd != -1) {
+			close(state->fd);
+			state->fd = -1;
+		}
+		snprintf(filename, 1023, state->filebase, state->filenum);
+		state->fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0640);
+		state->filenum++;
+		state->count = 0;
+	}
+	flatten_publickey(key, &packets, &list_end);
+	write_openpgp_stream(file_putchar, &state->fd, packets);
+	free_packet_list(packets);
+	packets = list_end = NULL;
+
+	return;
+}
+
 void usage(void) {
 	puts("onak " PACKAGE_VERSION " - an OpenPGP keyserver.\n");
 	puts("Usage:\n");
@@ -91,6 +129,7 @@ int main(int argc, char *argv[])
 	bool				 binary = false;
 	bool				 fingerprint = false;
 	int				 optchar;
+	struct dump_ctx                  dumpstate;
 
 	while ((optchar = getopt(argc, argv, "bc:fuv")) != -1 ) {
 		switch (optchar) {
@@ -121,7 +160,15 @@ int main(int argc, char *argv[])
 		usage();
 	} else if (!strcmp("dump", argv[optind])) {
 		initdb(true);
-		dumpdb("keydump");
+		dumpstate.count = dumpstate.filenum = 0;
+		dumpstate.maxcount = 1000000;
+		dumpstate.fd = -1;
+		dumpstate.filebase = "keydump.%d.pgp";
+		iterate_keys(dump_func, &dumpstate);
+		if (dumpstate.fd != -1) {
+			close(dumpstate.fd);
+			dumpstate.fd = -1;
+		}
 		cleanupdb();
 	} else if (!strcmp("add", argv[optind])) {
 		if (binary) {
-- 
2.39.5