/
umud/DOC/
umud/DOC/examples/
umud/DOC/internals/
umud/DOC/wizard/
umud/MISC/
umud/MISC/dbchk/
umud/RWHO/rwhod/
/*
	Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/

#ifndef	lint
static	char	RCSid[] = "$Header: /usr/users/mjr/hacks/umud/DB/RCS/dumpdb.c,v 1.1 91/07/04 17:33:09 mjr Rel $";
#endif


/* configure all options BEFORE including system stuff. */
#include	"config.h"


#include	<stdio.h>

#include	"mud.h"

extern	char	*optarg;
extern	int	optind;
extern	int	opterr;

#ifdef	DB_DIRHASH
extern	int	dhdb_init();
extern	int	dhdb_travstart();
extern	int	dhdb_traverse();
extern	int	dhdb_travend();
extern	Obj	*dhdb_get();
extern	int	dhdb_close();
extern	int	dhdb_backup();
#endif

#ifdef	DB_DBMFILE
extern	int	dddb_init();
extern	int	dddb_travstart();
extern	int	dddb_traverse();
extern	int	dddb_travend();
extern	Obj	*dddb_get();
extern	int	dddb_close();
extern	int	dddb_backup();
#endif

#ifdef	DB_GDBMFILE
extern	int	dgdb_init();
extern	int	dgdb_travstart();
extern	int	dgdb_traverse();
extern	int	dgdb_travend();
extern	Obj	*dgdb_get();
extern	int	dgdb_close();
extern	int	dgdb_backup();
#endif


main(ac,av)
int	ac;
char	**av;
{
	int	(*initin)() = 0;
	int	(*travstart)() = 0;
	int	(*trav)() = 0;
	int	(*travclose)() = 0;
	Obj	*(*objget)() = 0;
	int	(*closer)() = 0;
	int	(*backup)() = 0;
	char	obuf[MAXOID];
	char	*outfile = (char *)0;
	Obj	*op;

	FILE	*out = stdout;
	char	typ = '\0';
	char	*fdir = (char *)0;
	char	*cexp = (char *)0;
	int	cnt = 0;
	int	vflg = 0;
	int	lflg = 0;
	int	Bflg = 0;
	int	bflg = 0;
	int	x;

	while((x = getopt(ac,av,"Bb:c:o:f:hdgvl")) != EOF) {
		switch(x) {

		case 'o':
			outfile = optarg;
			break;


		case 'b':
			bflg = atoi(optarg);
			if(bflg <= 0) {
				fprintf(stderr,"%s not a valid size\n",optarg);
				exit(1);
			}
			break;

		case 'B':
			Bflg = 1;
			break;

#ifdef	DB_DIRHASH
		case 'h':
			initin = dhdb_init;
			travstart = dhdb_travstart;
			trav = dhdb_traverse;
			travclose = dhdb_travend;
			objget = dhdb_get;
			closer = dhdb_close;
			backup = dhdb_backup;
			typ = 'h';
			break;
#endif


#ifdef	DB_DBMFILE
		case 'd':
			initin = dddb_init;
			travstart = dddb_travstart;
			trav = dddb_traverse;
			travclose = dddb_travend;
			objget = dddb_get;
			closer = dddb_close;
			backup = dddb_backup;
			typ = 'd';
			break;
#endif


#ifdef	DB_GDBMFILE
		case 'g':
			initin = dgdb_init;
			travstart = dgdb_travstart;
			trav = dgdb_traverse;
			travclose = dgdb_travend;
			objget = dgdb_get;
			closer = dgdb_close;
			backup = dgdb_backup;
			typ = 'g';
			break;
#endif


		case 'c':
			cexp = optarg;
			break;


		case 'f':
			fdir = optarg;
			break;


		case 'v':
			vflg++;
			break;


		case 'l':
			lflg++;
			break;


		case '?':
		default:
			exit(usage());
		}
	}

	if(initin == 0) {
		fprintf(stderr,"what kind of database is this?\n");
		exit(1);
	}

	if(fdir != (char *)0) {
#ifdef	DB_DIRHASH
		if(typ == 'h') {
			dhdb_sethpath(fdir);
			if(bflg)
				dhdb_sethsiz(bflg);
		}
#endif
#ifdef	DB_DBMFILE
		if(typ == 'd') {
			dddb_setfile(fdir);
			if(bflg)
				dddb_setbsiz(bflg);
		}
#endif
#ifdef	DB_GDBMFILE
		if(typ == 'g')
			dgdb_setfile(fdir);
#endif
	}


	/* compile expression and check syntax */
	if(cexp != (char *)0 && setexpr(cexp))
			exit(1);


	/* open database */
	if((*initin)()) {
		fprintf(stderr,"cannot initialize db layer\n");
		exit(1);
	}
	

	/* backup mode/setup output */
	if(Bflg) {
		if(outfile == (char *)0) {
			fprintf(stderr,"backup requires an output filename\n");
			exit(1);
		}
		/* do backup and exit */
		if((*backup)(outfile)) {
			fprintf(stderr,"cannot backup db\n");
			exit(1);
		}
		exit(0);
	} else {
		if(outfile != (char *)0) {
			if((out = fopen(outfile,"w")) == (FILE *)0) {
				perror(outfile);
				exit(1);
			}
		}
	}



	/* ready traverse */
	if((*travstart)()) {
		fprintf(stderr,"cannot start db traverse\n");
		exit(1);
	}

	/* traverse */
	while((*trav)(obuf)) {
		tmp_sync();
		if((op = (*objget)(obuf)) == (Obj *)0) {
			fprintf(stderr,"WARNING: cannot get object %s\n",obuf);
			continue;
		}

		if(cexp != (char *)0 && checkexpr(obuf,op) == 0) {
			if(vflg)
				fprintf(stderr,"-> %s\n",obuf);
			objfree(op);
			continue;
		}

		/* list only */
		if(lflg) {
			fprintf(out,"%s\n",obuf);
			cnt++;
			objfree(op);
			continue;
		}

		oiftoFILE(op,out,obuf);
		objfree(op);
		if(vflg)
			fprintf(stderr,"+> %s\n",obuf);
		cnt++;
	}
	

	if((*travclose)()) {
		fprintf(stderr,"cannot cleanly shut down db traverse\n");
		exit(1);
	}
	

	if((*closer)()) {
		fprintf(stderr,"cannot cleanly close db\n");
		exit(1);
	}

	fprintf(stderr,"dumped %d objects\n",cnt);
	exit(0);
}



usage()
{
	fprintf(stderr,"usage: dumpdb -d|h|g [db type] [-f datapath] [-o outfile]\n");
	return(1);
}