diff options
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htdb/htdb_dump.cc')
-rw-r--r-- | debian/htdig/htdig-3.2.0b6/htdb/htdb_dump.cc | 609 |
1 files changed, 609 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htdb/htdb_dump.cc b/debian/htdig/htdig-3.2.0b6/htdb/htdb_dump.cc new file mode 100644 index 00000000..07c01315 --- /dev/null +++ b/debian/htdig/htdig-3.2.0b6/htdb/htdb_dump.cc @@ -0,0 +1,609 @@ +// Part of the ht://Dig package <http://www.htdig.org/> +// Copyright (c) 1999-2004 The ht://Dig Group +// For copyright details, see the file COPYING in your distribution +// or the GNU Library General Public License (LGPL) version 2 or later +// <http://www.gnu.org/copyleft/lgpl.html> +// + +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997, 1998, 1999 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" +#include "htconfig.h" + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1996, 1997, 1998, 1999\n\ + Sleepycat Software Inc. All rights reserved.\n"; +static const char sccsid[] = "@(#)db_dump.c 11.12 (Sleepycat) 11/10/99"; +#endif + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#endif /* HAVE_GETOPT_H */ +#endif + +extern "C" { +#include "db_int.h" +#include "db_page.h" +#include "db_shash.h" +#include "btree.h" +#include "hash.h" +#include "lock.h" +} + +#include "WordContext.h" +#include "WordDBCompress.h" + +void configure __P((char *)); +int db_init __P((char *, int)); +int dump __P((DB *, int, int)); +int dump_sub __P((DB *, char *, int, int)); +int is_sub __P((DB *, int *)); +int main __P((int, char *[])); +void onint __P((int)); +int pheader __P((DB *, char *, int, int)); +int show_subs __P((DB *)); +void siginit __P((void)); +void usage __P((void)); + +DB_ENV *dbenv; +int interrupted; +const char + *progname = "htdb_dump"; /* Program name. */ + +int +main(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + DB *dbp; + int ch, d_close; + int e_close, exitval, lflag, Nflag, pflag, ret, subs, keyflag; + char *dopt, *home, *subname; + int compress = 0; + int wordlist = 0; + u_int32_t cachesize = 0; + Configuration *config = 0; + + dbp = NULL; + d_close = e_close = exitval = lflag = Nflag = pflag = 0; + keyflag = 0; + dopt = home = subname = NULL; + while ((ch = getopt(argc, argv, "d:f:h:klNps:C:zW")) != EOF) + switch (ch) { + case 'd': + dopt = optarg; + break; + case 'f': + if (freopen(optarg, "w", stdout) == NULL) { + fprintf(stderr, "%s: %s: reopen: %s\n", + progname, optarg, strerror(errno)); + exit (1); + } + break; + case 'h': + home = optarg; + break; + case 'k': + keyflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'N': + Nflag = 1; + break; + case 'p': + pflag = 1; + break; + case 's': + subname = optarg; + break; + case 'C': + cachesize = atoi(optarg); + break; + case 'z': + compress = DB_COMPRESS; + break; + case 'W': + wordlist = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + if (dopt != NULL && pflag) { + fprintf(stderr, + "%s: the -d and -p options may not both be specified\n", + progname); + exit (1); + } + if (lflag && subname != NULL) { + fprintf(stderr, + "%s: the -l and -s options may not both be specified\n", + progname); + exit (1); + } + + /* Handle possible interruptions. */ + siginit(); + + if(wordlist && compress) { + static ConfigDefaults defaults[] = { + { "wordlist_wordkey_description", "Word/DocID 32/Flag 8/Location 16"}, + { "wordlist_env_skip", "true"}, + { 0, 0, 0 } + }; + config = WordContext::Initialize(defaults); + } + + /* + * Create an environment object and initialize it for error + * reporting. + */ + if ((ret = CDB_db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: CDB_db_env_create: %s\n", progname, CDB_db_strerror(ret)); + exit (1); + } + + e_close = 1; + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + if(compress && wordlist) dbenv->mp_cmpr_info = (new WordDBCompress)->CmprInfo(); + + /* Initialize the environment. */ + if (db_init(home, Nflag) != 0) + goto err; + + /* Create the DB object and open the file. */ + if ((ret = CDB_db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "CDB_db_create"); + goto err; + } + if(cachesize > 0) dbp->set_cachesize(dbp, 0, cachesize, 1); + d_close = 1; + if ((ret = dbp->open(dbp, + argv[0], subname, DB_UNKNOWN, (DB_RDONLY | compress), 0)) != 0) { + dbp->err(dbp, ret, "open: %s", argv[0]); + goto err; + } + + if (dopt != NULL) { + if (CDB___db_dump(dbp, dopt, NULL)) { + dbp->err(dbp, ret, "CDB___db_dump: %s", argv[0]); + goto err; + } + } else if (lflag) { + if (is_sub(dbp, &subs)) + goto err; + if (subs == 0) { + dbp->errx(dbp, + "%s: does not contain subdatabases", argv[0]); + goto err; + } + if (show_subs(dbp)) + goto err; + } else { + subs = 0; + if (subname == NULL && is_sub(dbp, &subs)) + goto err; + if (subs) { + if (dump_sub(dbp, argv[0], pflag, keyflag)) + goto err; + } else + if (pheader(dbp, NULL, pflag, keyflag) + || dump(dbp, pflag, keyflag)) + goto err; + } + + if (0) { +err: exitval = 1; + } + if (d_close && (ret = dbp->close(dbp, 0)) != 0) { + exitval = 1; + dbp->err(dbp, ret, "close"); + } + if (e_close && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, CDB_db_strerror(ret)); + } + + if (interrupted) { + (void)signal(interrupted, SIG_DFL); + (void)raise(interrupted); + /* NOTREACHED */ + } + + if(config) { + WordContext::Finish(); + delete config; + } + + return (exitval); +} + +/* + * db_init -- + * Initialize the environment. + */ +int +db_init(char *home, int Nflag) +{ + u_int32_t flags; + int ret; + + /* Optionally turn mutexes off. */ + if (Nflag) { + if ((ret = dbenv->set_mutexlocks(dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "set_mutexlocks"); + return (1); + } + if ((ret = dbenv->set_panic(dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "set_panic"); + return (1); + } + } + + /* + * Try and use the shared memory pool region when dumping a database, + * so our information is as up-to-date as possible, even if the mpool + * cache hasn't been flushed. + */ + flags = DB_USE_ENVIRON | DB_INIT_MPOOL | DB_INIT_LOCK; + if (dbenv->open(dbenv, home, NULL, flags, 0) == 0) + return (0); + + /* + * An environment is required because we may be trying to look at + * databases in directories other than the current one. We could + * avoid using an environment iff the -h option wasn't specified, + * but that seems like more work than it's worth. + * + * No environment exists (or, at least no environment that includes + * an mpool region exists). Create one, but make it private so that + * no files are actually created. + */ + LF_SET(DB_CREATE | DB_PRIVATE); + if ((ret = dbenv->open(dbenv, home, NULL, flags, 0)) == 0) + return (0); + + /* An environment is required. */ + dbenv->err(dbenv, ret, "open"); + return (1); +} + +/* + * pheader -- + * Write out the header information. + */ +int +pheader(DB *dbp, char *subname, int pflag, int keyflag) +{ + DB_BTREE_STAT *btsp; + DB_HASH_STAT *hsp; + DB_QUEUE_STAT *qsp; + int ret; + + printf("VERSION=2\n"); + printf("format=%s\n", pflag ? "print" : "bytevalue"); + if (subname != NULL) + printf("subdatabase=%s\n", subname); + switch (dbp->type) { + case DB_BTREE: + printf("type=btree\n"); + if ((ret = dbp->stat(dbp, &btsp, NULL, 0)) != 0) { + dbp->err(dbp, ret, "DB->stat"); + return (1); + } + if (F_ISSET(dbp, BTM_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 && btsp->bt_minkey != DEFMINKEYPAGE) + printf("bt_minkey=%lu\n", (u_long)btsp->bt_minkey); + break; + case DB_HASH: + printf("type=hash\n"); + if ((ret = dbp->stat(dbp, &hsp, NULL, 0)) != 0) { + dbp->err(dbp, ret, "DB->stat"); + return (1); + } + if (hsp->hash_ffactor != 0) + printf("h_ffactor=%lu\n", (u_long)hsp->hash_ffactor); + if (hsp->hash_nelem != 0 || hsp->hash_nrecs != 0) + printf("h_nelem=%lu\n", + hsp->hash_nelem > hsp->hash_nrecs ? + (u_long)hsp->hash_nelem : (u_long)hsp->hash_nrecs); + break; + case DB_QUEUE: + printf("type=queue\n"); + if ((ret = dbp->stat(dbp, &qsp, NULL, 0)) != 0) { + dbp->err(dbp, ret, "DB->stat"); + return (1); + } + printf("re_len=%lu\n", (u_long)qsp->qs_re_len); + if (qsp->qs_re_pad != 0 && qsp->qs_re_pad != ' ') + printf("re_pad=%#x\n", qsp->qs_re_pad); + break; + case DB_RECNO: + printf("type=recno\n"); + if ((ret = dbp->stat(dbp, &btsp, NULL, 0)) != 0) { + dbp->err(dbp, ret, "DB->stat"); + return (1); + } + if (F_ISSET(dbp, BTM_RENUMBER)) + printf("renumber=1\n"); + if (F_ISSET(dbp, BTM_FIXEDLEN)) + printf("re_len=%lu\n", (u_long)btsp->bt_re_len); + if (btsp->bt_re_pad != 0 && btsp->bt_re_pad != ' ') + printf("re_pad=%#x\n", btsp->bt_re_pad); + break; + case DB_UNKNOWN: + abort(); /* Impossible. */ + /* NOTREACHED */ + } + + if (F_ISSET(dbp, DB_AM_DUP)) + printf("duplicates=1\n"); + + if (!F_ISSET(dbp, DB_AM_PGDEF)) + printf("db_pagesize=%lu\n", (u_long)dbp->pgsize); + + if (keyflag) + printf("keys=1\n"); + + printf("HEADER=END\n"); + return (0); +} + +/* + * is_sub -- + * Return if the database contains subdatabases. + */ +int +is_sub(DB *dbp, int *yesno) +{ + DB_BTREE_STAT *btsp; + DB_HASH_STAT *hsp; + int ret; + + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + if ((ret = dbp->stat(dbp, &btsp, NULL, 0)) != 0) { + dbp->err(dbp, ret, "DB->stat"); + break; + } + *yesno = btsp->bt_metaflags & BTM_SUBDB ? 1 : 0; + free(btsp); + break; + case DB_HASH: + if ((ret = dbp->stat(dbp, &hsp, NULL, 0)) != 0) { + dbp->err(dbp, ret, "DB->stat"); + break; + } + *yesno = hsp->hash_metaflags & DB_HASH_SUBDB ? 1 : 0; + free(hsp); + break; + case DB_QUEUE: + return (0); + default: + abort(); + /* NOTREACHED */ + } + return (ret); +} + +/* + * dump_sub -- + * Dump out the records for a DB containing subdatabases. + */ +int +dump_sub(DB *parent_dbp, char *parent_name, int pflag, int keyflag) +{ + DB *dbp; + DBC *dbcp; + DBT key, data; + int ret; + char *subdb; + + /* + * Get a cursor and step through the database, dumping out each + * subdatabase. + */ + if ((ret = parent_dbp->cursor(parent_dbp, NULL, &dbcp, 0)) != 0) { + dbenv->err(dbenv, ret, "DB->cursor"); + return (1); + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) { + /* Nul terminate the subdatabase name. */ + if ((subdb = (char*)malloc(key.size + 1)) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + return (1); + } + memcpy(subdb, key.data, key.size); + subdb[key.size] = '\0'; + + /* Create the DB object and open the file. */ + if ((ret = CDB_db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "CDB_db_create"); + free(subdb); + return (1); + } + if ((ret = dbp->open(dbp, + parent_name, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) + dbp->err(dbp, ret, + "DB->open: %s:%s", parent_name, subdb); + if (ret == 0 && + (pheader(dbp, subdb, pflag, keyflag) || + dump(dbp, pflag, keyflag))) + ret = 1; + (void)dbp->close(dbp, 0); + free(subdb); + if (ret != 0) + return (1); + } + if (ret != DB_NOTFOUND) { + dbp->err(dbp, ret, "DBcursor->get"); + return (1); + } + + if ((ret = dbcp->c_close(dbcp)) != 0) { + dbp->err(dbp, ret, "DBcursor->close"); + return (1); + } + + return (0); +} + +/* + * show_subs -- + * Display the subdatabases for a database. + */ +int +show_subs(DB *dbp) +{ + DBC *dbcp; + DBT key, data; + int ret; + + /* + * Get a cursor and step through the database, printing out the key + * of each key/data pair. + */ + if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { + dbp->err(dbp, ret, "DB->cursor"); + return (1); + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) { + if ((ret = CDB___db_prdbt(&key, 1, NULL, stdout, 0)) != 0) { + dbp->errx(dbp, NULL); + return (1); + } + } + if (ret != DB_NOTFOUND) { + dbp->err(dbp, ret, "DBcursor->get"); + return (1); + } + + if ((ret = dbcp->c_close(dbcp)) != 0) { + dbp->err(dbp, ret, "DBcursor->close"); + return (1); + } + return (0); +} + +/* + * dump -- + * Dump out the records for a DB. + */ +int +dump(DB *dbp, int pflag, int keyflag) +{ + DBC *dbcp; + DBT key, data; + int ret, is_recno; + + /* + * Get a cursor and step through the database, printing out each + * key/data pair. + */ + if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { + dbp->err(dbp, ret, "DB->cursor"); + return (1); + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + is_recno = (dbp->type == DB_RECNO || dbp->type == DB_QUEUE); + keyflag = is_recno ? keyflag : 1; + while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) + if ((keyflag && (ret = + CDB___db_prdbt(&key, pflag, " ", stdout, is_recno)) != 0) || + (ret = CDB___db_prdbt(&data, pflag, " ", stdout, 0)) != 0) { + dbp->errx(dbp, NULL); + return (1); + } + if (ret != DB_NOTFOUND) { + dbp->err(dbp, ret, "DBcursor->get"); + return (1); + } + + if ((ret = dbcp->c_close(dbcp)) != 0) { + dbp->err(dbp, ret, "DBcursor->close"); + return (1); + } + + printf("DATA=END\n"); + 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 SIGPIPE + (void)signal(SIGPIPE, onint); +#endif + (void)signal(SIGTERM, onint); +} + +/* + * onint -- + * Interrupt signal handler. + */ +void +onint(int signo) +{ + if ((interrupted = signo) == 0) + interrupted = SIGINT; +} + +/* + * usage -- + * Display the usage message. + */ +void +usage() +{ + (void)fprintf(stderr, +"usage: htdb_dump [-klNpWz] [-C cachesize] [-d ahr] [-f file] [-h home] [-s subdb] db_file\n"); + exit(1); +} |