/
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/loaddb.c,v 1.2 91/08/11 19:46:35 mjr Exp $";
#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	int	dhdb_put();
extern	int	dhdb_close();
#endif

#ifdef	DB_DBMFILE
extern	int	dddb_init();
extern	int	dddb_travstart();
extern	int	dddb_traverse();
extern	int	dddb_travend();
extern	int	dddb_put();
extern	int	dddb_close();
#endif

#ifdef	DB_GDBMFILE
extern	int	dgdb_init();
extern	int	dgdb_travstart();
extern	int	dgdb_traverse();
extern	int	dgdb_travend();
extern	int	dgdb_put();
extern	int	dgdb_close();
#endif

main(ac,av)
int	ac;
char	**av;
{
	int	(*initin)() = 0;
	int	(*objput)() = 0;
	int	(*closer)() = 0;
	char	obuf[MAXOID];
	Obj	*op;

	FILE	*in = stdin;
	FILE	*out = stdout;
	char	typ = '\0';
	char	*fdir = (char *)0;
	char	*cexp = (char *)0;
	int	vflg = 0;
	int	lflg = 0;
	int	xflg = 0;
	int	cnt = 0;
	int	bflg = 0;
	int	avsiz = 0;
	int	losiz = 1000000;
	int	hisiz = 0;
	int	sflg = 0;
#ifdef COMPRESS_OIF
	int	cin = 0;		/* input compressed */
	int	cout = 0;		/* output compressed */
#endif
	int	x;

#ifdef COMPRESS_OIF
	comp_init();
#endif

	while((x = getopt(ac,av,"C:b:c:i:f:hsdgvlo:x")) != EOF) {
		switch(x) {
#ifdef COMPRESS_OIF
		case 'C':
			if(*optarg == 'i')
				cin = 1;
			if(*optarg == 'o')
				cout = 1;
			break;
#endif

		case 'i':
			in = fopen(optarg,"r");
			if(in == (FILE *)0) {
				perror(optarg);
				exit(1);
			}
			break;


		case 'o':
			out = fopen(optarg,"w");
			if(out == (FILE *)0) {
				perror(optarg);
				exit(1);
			}
			break;


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


#ifdef	DB_DIRHASH
		case 'h':
			initin = dhdb_init;
			objput = dhdb_put;
			closer = dhdb_close;
			typ = 'h';
			break;
#endif


#ifdef	DB_DBMFILE
		case 'd':
			initin = dddb_init;
			objput = dddb_put;
			closer = dddb_close;
			typ = 'd';
			break;
#endif


#ifdef	DB_GDBMFILE
		case 'g':
			initin = dgdb_init;
			objput = dgdb_put;
			closer = dgdb_close;
			typ = 'g';
			break;
#endif


		case 'c':
			cexp = optarg;
			break;


		case 'f':
			fdir = optarg;
			break;


		case 'v':
			vflg++;
			break;


		case 's':
			sflg++;
			break;


		case 'x':
			xflg++;
			break;


		case 'l':
			lflg++;
			break;


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

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

	if(fdir) {
#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
	}


	if(cexp != (char *)0 && setexpr(cexp))
		exit(1);


	if(!xflg && (*initin)()) {
		fprintf(stderr,"cannot initialize db layer\n");
		exit(1);
	}

	obuf[0] = '\0';
	while(1) {
		tmp_sync();

#ifdef COMPRESS_OIF
		if(cin) comp_on(1); else comp_on(0);
#endif
		op = oiffromFILE(in,obuf);
		if(op == (Obj *)0)
			break;

		if(obuf[0] == '\0') {
			fprintf(stderr,"unnamed object in input\n");
			objfree(op);
			obuf[0] = '\0';
			continue;
		}


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


		if(sflg) {
			int	nsiz;

			nsiz = oif_objsiz(op,obuf);
			avsiz = ((avsiz * cnt) + nsiz) / (cnt + 1);
			if(nsiz > hisiz)
				hisiz = nsiz;
			else
				if(nsiz < losiz)
					losiz = nsiz;
		}

		/* list only */
		if(lflg) {
			printf("%s\n",obuf);
			objfree(op);
			obuf[0] = '\0';
			cnt++;
			continue;
		}

#ifdef COMPRESS_OIF
		if(cout) comp_on(1); else comp_on(0);
#endif

		/* copy to stdout */
		if(xflg) {
			oiftoFILE(op,out,obuf);
			objfree(op);
			obuf[0] = '\0';
			cnt++;
			continue;
		}

		if((*objput)(op,obuf)) {
			fprintf(stderr,"cannot store object %s\n",obuf);
			objfree(op);
			obuf[0] = '\0';
			continue;
		} else {
		    cnt++;
		    if(vflg)
			fprintf(stderr,"<+ %s\n",obuf);
		    objfree(op);
		    obuf[0] = '\0';
		}
	}
	

	if(!xflg && (*closer)()) {
		fprintf(stderr,"cannot close db layer\n");
		exit(1);
	}

	if(xflg)
		fprintf(stderr,"selected %d objects\n",cnt);
	else
		fprintf(stderr,"stored %d objects\n",cnt);
	if(sflg)
		fprintf(stderr,"object size: %d min, %d average, %d max\n",
			losiz,avsiz,hisiz);
	exit(0);
}



usage()
{
	fprintf(stderr,"usage: loaddb -d|h|g|x [-f datapath] [-i infile]\n");
	fprintf(stderr,"[-v (verbose)] [-l (list only)] [-o outfile]\n");
	fprintf(stderr,"[-s (object size statistics)]\n");
	fprintf(stderr,"[-c selection_expression]\n");

#ifdef	COMPRESS_OIF
	fprintf(stderr,"[-C i (input is compressed)] [-C o (compress output)]\n");
#endif
	return(1);
}