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

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


#ifdef  DB_GDBMFILE

#ifdef WIN32
#include        "gdbm.h"
#else
#include        <gdbm.h>
#endif
#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, S_IREAD | S_IWRITE, 0))
      == (GDBM_FILE) 0) {
    log_printf ("db_init cannot dbm_open ", dbfile, " ", (char *) -1, "\n",
      (char *) 0);
    return (1);
  }

  db_initted = 1;
  return (0);
}



int dgdb_initted ()
{
  return (db_initted);
}



int dgdb_setfile (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)
    log_printf ("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) {
    log_printf ("db_put: can't allocate mem for object ", nam, " ",
      (char *) -1, "\n", (char *) 0);
    return (1);
  }

  if (oiftoSTRING (obj, dat.dptr, nam, dat.dsize)) {
    log_printf ("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)) {
    log_printf ("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)) {
    log_printf ("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) {
    log_printf ("attempt to backup unopened database\n", (char *) 0);
    return (1);
  }

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

  if (fd == -1) {
    log_printf ("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))
      log_printf ("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