
#include <syslog.h>
#include <ndbm.h>
#include <sys/file.h>
#include "server.h"

/*
 * database --- store and retreive server records
 */

static DBM *database, *hostdb;
static datum statistics_key = { ".statistics", 11 };



open_database(init_database)
     int init_database;			/* pass TRUE to cause the database to be */
					/* created if not found */
{
  if (!(database = dbm_open (database_path, O_RDWR)) ||
      !(hostdb = dbm_open (hostdb_path, O_RDWR)))
    if (init_database) {
      Statistics s;
      if (!database &&
	  !(database = dbm_open (database_path, O_RDWR | O_CREAT, 0644))) {
	syslog (LOG_ALERT, "Cannot create database: %m");
	exit (1);
      }
      bzero (&s, sizeof(s));
      write_statistics (&s);

      /* make host database */
      if(!(hostdb = dbm_open(hostdb_path, O_RDWR | O_CREAT, 0644))) {
	syslog(LOG_ALERT, "Cannot create host database: %m");
	exit(1);
      }

    } else {
      syslog (LOG_ALERT, "Cannot open database: %m");
      exit(1);
    }
  syslog (LOG_DEBUG, "opened databases");
}


read_statistics (s)
     Statistics *s;
{
  datum sd;
  
  sd = dbm_fetch (database, statistics_key);
  if (!sd.dptr) {
    syslog (LOG_ERR, "Cannot find statistics in database");
    bzero (s, sizeof(Statistics));
  } else
    bcopy (sd.dptr, s, sizeof(Statistics));
}



write_statistics (s)
     Statistics *s;
{
  dbm_store (database, statistics_key, s, sizeof(Statistics), DBM_REPLACE);
}



int read_freeload (username, freeload)	/* Returns 0 for OK, */
     char *username;			/* or -1 if username is not in database */
     Freeload *freeload;
{
  datum fdat;
  
  fdat = dbm_fetch (database, username, strlen(username));
  if (fdat.dptr) {
    bcopy (fdat.dptr, freeload, sizeof(Freeload));
    return 0;
  } else
    return -1;
}




add_freeload (freeload)			/* Stores it according to username, NEVER replacing */
     Freeload *freeload;		/* any existing entry! */
{
  datum key, val;

  key.dsize = strlen(freeload->username);
  key.dptr = freeload->username;
  val.dsize = sizeof(Freeload);
  val.dptr = (char *) freeload;
  if (dbm_store (database, key, val, DBM_INSERT))
    syslog (LOG_ERR, "could not dbm_store %d bytes making new freeloader: %m",
	    key.dsize + val.dsize);
}

remove_freeload (freeload)
     Freeload *freeload;
{
  char keybuf[MAXUSERNAME];		/* copy is made in case the given freeload */
  strcpy(keybuf, freeload->username);	/* is in ndbm's work space */
  dbm_delete (database, keybuf, strlen(keybuf));
}

Freeload *next_freeload();
Freeload *first_freeload ()		/* Returns NULL for end of list */
{
  datum key, val;

  key = dbm_firstkey(database);
  if (key.dptr)
    if (key.dptr[0] == '.')
      return next_freeload();
    else {
      val = dbm_fetch(database, key);
      return (Freeload *) val.dptr;
    }
  else
    return NULL;
}


Freeload *next_freeload ()		/* Returns NULL for end of list */
{
  datum key, val;
  do {
    key = dbm_nextkey(database);
    if (key.dptr && key.dptr[0] != '.') {
      val = dbm_fetch(database, key);
      return (Freeload *) val.dptr;
    }
  } while (key.dptr);
  return NULL;
}

add_server_down(server)
     Server *server;
{
  dbm_store(hostdb, server, sizeof(Server), server, sizeof(server), DBM_INSERT);
}

int db_is_server_down(server)
     Server *server;
{

  datum fdat;
  fdat = dbm_fetch(hostdb, server, sizeof(Server));
  return fdat.dptr ? 1: 0;
  
}

delete_server_down(server)
     Server *server;
{
  dbm_delete(hostdb, server, sizeof(Server));
}

Server *first_server_down()
{
  datum d;
  d = dbm_firstkey(hostdb);
  return (Server*)(d.dptr);
}

Server *next_server_down()
{
  datum d;
  d = dbm_nextkey(hostdb);
  return (Server*)(d.dptr);
}



