/***** **** *** ** *  *   *    *     *       *     *   *  * ** *** **** *****\

    logresolve 2.0 - http://www.uunet.ca/~tomr/progs/logresolve/

    lr-dbm.c - persistent DBM (pDBM) cache 2.0d0

    Tom Rathborne - tomr@uunet.ca - http://www.uunet.ca/~tomr/

\***** **** *** ** *  *   *    *     *       *     *   *  * ** *** **** *****/

#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>

#include "lr-dbm.h"

/*
 * pdbm_lookup - gets record from pDBM
 */

struct nsrec *
pdbm_lookup(db, ipnum)
    struct nsdbm *db;
    unsigned char ipnum[4];
{
    char temp[MAXLINE];
    struct nsrec *rec;

    datum data, key;

    if (db->mode != LR_READ)
	return (0);

    key.dptr = ipnum;
    key.dsize = 4;

    data = dbm_fetch(db->dbf, key);

    if (data.dptr) {		/*
				 * it was found 
				 */
	rec = nsrec_new();
	ip_cpy(rec->ipnum, ipnum);

	sscanf(data.dptr, "%s %d %d %d ",
	       temp, &(rec->noname), &(rec->lookuptime), &(rec->usagecount));

	rec->hostname = (char *) malloc(sizeof(char) * (strlen(temp) + 1));

	strcpy(rec->hostname, temp);
	rec->usagecount++;

	return (rec);

    } else
	return (0);
}

/*
 * pdbm_insert - inserts record into pDBM - ignored if mode is not LR_WRITE
 */

void
pdbm_insert(db, record)
    struct nsdbm *db;
    struct nsrec *record;
{
    char strdat[MAXLINE];
    datum data, key;

    if (db->mode != LR_WRITE)
	return;

    key.dptr = record->ipnum;
    key.dsize = 4;

    sprintf(strdat, "%s %d %d %d ", record->hostname, record->noname,
	    record->lookuptime, record->usagecount);

    data.dptr = strdat;
    data.dsize = strlen(strdat) + 2;

    dbm_store(db->dbf, key, data, DBM_REPLACE);
}

/*
 * pdbm_open - open a logresolve pDBM
 */

struct nsdbm *
pdbm_open(dbfname, lockname, mode)
    char *dbfname;
    char *lockname;
    int mode;
{
    struct nsdbm *db;

    db = (struct nsdbm *) malloc(sizeof(struct nsdbm));

    db->mode = mode;

/*** db->lockfile = open(lockname, O_RDWR | O_CREAT); ***/

    switch (mode) {
	case LR_READ:
/*** flock(db->lockfile, LOCK_SH); ***/
	    db->dbf = dbm_open(dbfname, O_RDONLY | O_CREAT, 0644);
	    break;
	case LR_WRITE:
/*** flock(db->lockfile, LOCK_EX); ***/
	    db->dbf = dbm_open(dbfname, O_RDWR | O_CREAT, 0644);
	    break;
    }

    if (!db->dbf) {
	/*** flock(db->lockfile, LOCK_UN);
	close(db->lockfile); ***/
	db->mode = LR_CLOSED;
    }
    return (db);
}

/*
 * pdbm_close - close a logresolve pDBM
 */

int
pdbm_close(db)
    struct nsdbm *db;
{
    if (db->mode != LR_CLOSED) {
	dbm_close(db->dbf);
	/*** flock(db->lockfile, LOCK_UN);
	close(db->lockfile); ***/
	free(db);
    }
    return (0);
}

/*** end of lr-dbm.c ***/
