tinymush-3.0b21/game/bin/
tinymush-3.0b21/game/data/
tinymush-3.0b21/src/tools/
/*
 * Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
 * 
 * $Id: udb_ochunk.c,v 1.14 1999/12/04 13:59:55 cvs Exp $
 */

/* configure all options BEFORE including system stuff. */
#include	"autoconf.h"
#include	"udb_defs.h"
#include	"db.h"
#include	"mudconf.h"

#ifdef VMS
#include	<malloc.h>
#include        <types.h>
#include        <file.h>
#include        <unixio.h>
#include        "vms_dbm.h"
#else
#include	<sys/param.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#include	<sys/file.h>

#include	"gdbm.h"
#endif /* VMS */

#include	"udb.h"
#include	"config.h"
#include	"externs.h"
#include	"alloc.h"

#ifndef STANDALONE
extern void FDECL(dump_database_internal, (int));
#endif

#define DEFAULT_DBMCHUNKFILE "mudDB"

static char *dbfile = DEFAULT_DBMCHUNKFILE;
static int db_initted = 0;

static GDBM_FILE dbp = (GDBM_FILE) 0;

static datum dat;
static datum key;

int FDECL(dddb_del, (Objname *));
int FDECL(dddb_put, (Obj *, Objname *));
extern int FDECL(obj_siz, (Obj *));
extern void VDECL(fatal, (char *, ...));
extern void VDECL(logf, (char *, ...));
extern void FDECL(log_db_err, (int, int, const char *));

/* gdbm_reorganize compresses unused space in the db */

int dddb_optimize()
{
	return (gdbm_reorganize(dbp));
}

static void gdbm_panic(mesg)
char *mesg;
{
	log_text(tprintf("GDBM panic: %s\n", mesg));
}

int dddb_init()
{
	static char *copen = "db_init cannot open ";
	char *gdbm_error;
	int block_size;
	int cache_size = 1;
	
	for (block_size = 1; block_size < LBUF_SIZE; block_size = block_size << 1) ;

	if ((dbp = gdbm_open(dbfile, block_size, GDBM_WRCREAT|GDBM_SYNC|GDBM_NOLOCK, 0600, gdbm_panic)) == (GDBM_FILE) 0) {
		gdbm_error = (char *)gdbm_strerror(gdbm_errno);
		logf(copen, dbfile, " ", (char *)-1, "\n", gdbm_error, "\n", (char *)0);
		return (1);
	}

	if (gdbm_setopt(dbp, GDBM_CACHESIZE, &cache_size, sizeof(int)) == -1) {
		gdbm_error = (char *)gdbm_strerror(gdbm_errno);
		logf(copen, dbfile, " ", (char *)-1, "\n", gdbm_error, "\n", (char *)0);
		return (1);
	}

	db_initted = 1;
	return (0);
}

int dddb_setfile(fil)
char *fil;
{
	char *xp;

	if (db_initted)
		return (1);

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

int dddb_close()
{
	if (dbp != (GDBM_FILE) 0) {
		gdbm_close(dbp);
		dbp = (GDBM_FILE) 0;
	}
	db_initted = 0;
	return (0);
}

Obj *dddb_get(nam)
Objname *nam;
{
	Obj *ret;
	
	if (!db_initted)
		return ((Obj *) 0);

	key.dptr = (char *)nam;
	key.dsize = sizeof(Objname);
	dat = gdbm_fetch(dbp, key);

	if (dat.dptr == (char *)0) {
		return ((Obj *) 0);
	}
	
	/* if the file is badly formatted, ret == Obj * 0 */
	if ((ret = objfromFILE(dat.dptr)) == (Obj *) 0) {
		logf("db_get: cannot decode ", nam, "\n", (char *)0);
		free(dat.dptr);
		return NULL;
	}
	
#ifndef STANDALONE	
	/* Check to make sure the requested name and stored name are the
	   same */
	
	if (*nam != ret->name) {
		STARTLOG(LOG_ALWAYS, "BUG", "CRUPT")
			log_text((char *)tprintf("Database is corrupt, object %d. Exiting.", (int)ret->name));
		ENDLOG
		raw_broadcast(0, "GAME: Database corruption detected, exiting.");
		exit(8);
	}
#endif
	free(dat.dptr);	
	return (ret);
}

int dddb_put(obj, nam)
Obj *obj;
Objname *nam;
{
	int nsiz;

	if (!db_initted)
		return (1);

	nsiz = obj_siz(obj);

	key.dptr = (char *)nam;
	key.dsize = sizeof(Objname);
	
	/* make table entry */
	dat.dptr = (char *)malloc(nsiz);
	dat.dsize = nsiz;

	if (objtoFILE(obj, dat.dptr) != 0) {
		logf("db_put: can't save ", nam, " ", (char *)-1, "\n", (char *)0);
		free(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(dat.dptr);
		return (1);
	}

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

int dddb_del(nam)
Objname *nam;
{

	if (!db_initted)
		return (-1);

	key.dptr = (char *)nam;
	key.dsize = sizeof(Objname);
	dat = gdbm_fetch(dbp, key);

	/* not there? */
	if (dat.dptr == (char *)0)
		return (0);

	free(dat.dptr);
	
	/* drop key from db */
	if (gdbm_delete(dbp, key)) {
		logf("db_del: can't delete key ", nam, "\n", (char *)0);
		return (1);
	}
	return (0);
}