/* * 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); }