/
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/gdbmchunk.c,v 1.1 91/07/04 17:33:10 mjr Rel $";
#endif

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


#ifdef	DB_GDBMFILE

#include	<gdbm.h>
#include	<sys/file.h>

#include	"mud.h"


/*
gdbm-based object storage routines. Just store the objects in the gdbm
database with their name as the key.
*/

static	char		*dbfile = DEFAULT_GDBMCHUNKFILE;
static	int		db_initted = 0;
static	GDBM_FILE	dbp = (GDBM_FILE)0;

int
dgdb_init()
{
	if((dbp = gdbm_open(dbfile,0,GDBM_WRCREAT,0600,0)) == (GDBM_FILE)0) {
		logf("db_init cannot dbm_open ",dbfile," ",(char *)-1,"\n",(char *)0);
		return(1);
	}

	db_initted = 1;
	return(0);
}



dgdb_initted()
{
	return(db_initted);
}



dgdb_setfile(fil)
char	*fil;
{
	char	*xp;

	if(db_initted)
		return(1);

	/* KNOWN memory leak. can't help it. it's small */
	xp = malloc((unsigned)strlen(fil) + 1);
	if(xp == (char *)0)
		return(1);
	(void)strcpy(xp,fil);
	dbfile = xp;
	return(0);
}



int
dgdb_close()
{
	if(dbp != (GDBM_FILE)0) {
		gdbm_close(dbp);
		dbp = (GDBM_FILE)0;
	}

	db_initted = 0;
	return(0);
}




Obj	*
dgdb_get(nam)
char	*nam;
{
	Obj		*ret;
	datum		key, dat;

	if(!db_initted)
		return((Obj *)0);

	key.dptr = nam;
	key.dsize = strlen(nam) + 1;
	dat = gdbm_fetch(dbp,key);

	if(dat.dptr == (char *)0)
		return((Obj *)0);

	/* if the string is badly formatted, ret == Obj * 0 */
	if((ret = oiffromSTRING((char *)dat.dptr,(char *)0)) == (Obj *)0)
		logf("db_get: cannot decode ",nam,"\n",(char *)0);

	free((mall_t)dat.dptr);
	return(ret);
}





int
dgdb_put(obj,nam)
Obj	*obj;
char	*nam;
{
	datum		key;
	datum		dat;

	if(!db_initted)
		return(1);

	key.dptr = nam;
	key.dsize = strlen(nam) + 1;

	dat.dsize = oif_objsiz(obj,nam) + 1;
	dat.dptr = malloc((unsigned)dat.dsize);

	if( !dat.dptr ) {
		logf("db_put: can't allocate mem for object ",nam," ",(char *)-1,"\n",(char *)0);
		return(1);
	}

	if( oiftoSTRING(obj,dat.dptr,nam,dat.dsize) ) {
		logf("db_put: can't convert ",nam," to OIF",(char *)-1,"\n",(char *)0);
		free((mall_t)dat.dptr);
		return(1);
	}

	if(gdbm_store(dbp,key,dat,GDBM_REPLACE)) {
		logf("db_put: can't gdbm_store ",nam," ",(char *)-1,"\n",(char *)0);
		free((mall_t)dat.dptr);
		return(1);
	}

	free((mall_t)dat.dptr);
	return(0);
}




int
dgdb_check(nam)
char	*nam;
{
        datum key, dat;

	if(!db_initted)
		return(0);

	key.dptr = nam;
	key.dsize = strlen(nam) + 1;
	dat = gdbm_fetch(dbp,key);
	if(dat.dptr == (char *)0)
		return(0);
	free((mall_t)dat.dptr);
	return(1);
}




int
dgdb_del(nam,flg)
char	*nam;
int	flg;
{
        datum key, dat;

	if(!db_initted)
		return(-1);

	key.dptr = nam;
	key.dsize = strlen(nam) + 1;
	dat = gdbm_fetch(dbp,key);

	if(dat.dptr == (char *)0)
		return(0);

	free((mall_t)dat.dptr);

	if( gdbm_delete(dbp,key) ) {
		logf("db_del: can't gdbm_delete ",nam," ",(char *)-1,"\n",(char *)0);
		return(1);
	}
	return(0);
}


static	int		startrav = 0;

int
dgdb_travstart()
{
	startrav = 0;
	return(0);
}



int
dgdb_traverse(obuf)
char	*obuf;
{
        char *dp;
	static datum key;

	if(!db_initted)
		return(0);

	if(!startrav) {
		key = gdbm_firstkey(dbp);
		startrav = 1;
	} else {
	        dp = key.dptr;
		key = gdbm_nextkey(dbp,key);
		free((mall_t)dp);
	}
	if(key.dptr == (char *)0)
		return(0);
	strncpy(obuf,(char *)key.dptr,MAXOID);
	return(1);
}


int
dgdb_travend()
{
	startrav = 0;
	return(0);
}

int
dgdb_backup(file)
char	*file;
{
	int fd;
	datum key, dat;
	char *dp;

	if(!db_initted) {
		logf("attempt to backup unopened database\n",(char *)0);
		return(1);
	}

	fd = open( file, O_WRONLY|O_TRUNC|O_CREAT, 0600 );

	if(fd == -1) {
		logf("Cannot open backup file ",file,"\n",(char *)0);
	    	return(1);
	}

	key = gdbm_firstkey(dbp);
	while(key.dptr != (char *)0) {
		dat = gdbm_fetch(dbp,key);
		if(write(fd,dat.dptr,dat.dsize-1) != (dat.dsize-1))
			logf("backup couldn't write object ",key.dptr,
			     "to ",file,"\n",(char *)0);
		free((mall_t)dat.dptr);
		dp = key.dptr;
		key = gdbm_nextkey(dbp,key);
		free((mall_t)dp);
	}
	
	close(fd);
	return(0);
}

#endif	DB_GDBMFILE