#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <ndbm.h>
#include "hash.h"
static DBM *_dbm_open(const char *, const char *, int, mode_t);
static DBM *
_dbm_open(const char *file, const char *suff, int flags, mode_t mode)
{
HASHINFO info;
char path[PATH_MAX];
int len;
len = snprintf(path, sizeof path, "%s%s", file, suff);
if (len < 0 || len >= sizeof path) {
errno = ENAMETOOLONG;
return (NULL);
}
if ((flags & O_ACCMODE) == O_WRONLY) {
flags &= ~O_WRONLY;
flags |= O_RDWR;
}
info.bsize = 4096;
info.ffactor = 40;
info.nelem = 1;
info.cachesize = 0;
info.hash = NULL;
info.lorder = 0;
return ((DBM *)__hash_open(path, -1, flags, mode, &info, 0));
}
DBM *
dbm_open(const char *file, int flags, mode_t mode)
{
return(_dbm_open(file, DBM_SUFFIX, flags, mode));
}
void
dbm_close(DBM *db)
{
(void)(db->close)(db);
}
DEF_WEAK(dbm_close);
datum
dbm_fetch(DBM *db, datum key)
{
datum retdata;
int status;
DBT dbtkey, dbtretdata;
dbtkey.data = key.dptr;
dbtkey.size = key.dsize;
status = (db->get)(db, &dbtkey, &dbtretdata, 0);
if (status) {
dbtretdata.data = NULL;
dbtretdata.size = 0;
}
retdata.dptr = dbtretdata.data;
retdata.dsize = dbtretdata.size;
return (retdata);
}
DEF_WEAK(dbm_fetch);
datum
dbm_firstkey(DBM *db)
{
int status;
datum retkey;
DBT dbtretkey, dbtretdata;
status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
if (status)
dbtretkey.data = NULL;
retkey.dptr = dbtretkey.data;
retkey.dsize = dbtretkey.size;
return (retkey);
}
DEF_WEAK(dbm_firstkey);
datum
dbm_nextkey(DBM *db)
{
int status;
datum retkey;
DBT dbtretkey, dbtretdata;
status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
if (status)
dbtretkey.data = NULL;
retkey.dptr = dbtretkey.data;
retkey.dsize = dbtretkey.size;
return (retkey);
}
DEF_WEAK(dbm_nextkey);
int
dbm_delete(DBM *db, datum key)
{
int status;
DBT dbtkey;
dbtkey.data = key.dptr;
dbtkey.size = key.dsize;
status = (db->del)(db, &dbtkey, 0);
if (status)
return (-1);
else
return (0);
}
DEF_WEAK(dbm_delete);
int
dbm_store(DBM *db, datum key, datum data, int flags)
{
DBT dbtkey, dbtdata;
dbtkey.data = key.dptr;
dbtkey.size = key.dsize;
dbtdata.data = data.dptr;
dbtdata.size = data.dsize;
return ((db->put)(db, &dbtkey, &dbtdata,
(flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
}
DEF_WEAK(dbm_store);
int
dbm_error(DBM *db)
{
HTAB *hp;
hp = (HTAB *)db->internal;
return (hp->err);
}
int
dbm_clearerr(DBM *db)
{
HTAB *hp;
hp = (HTAB *)db->internal;
hp->err = 0;
return (0);
}
int
dbm_dirfno(DBM *db)
{
return(((HTAB *)db->internal)->fp);
}
int
dbm_rdonly(DBM *dbp)
{
HTAB *hashp = (HTAB *)dbp->internal;
return ((hashp->flags & O_ACCMODE) == O_RDONLY);
}
DEF_WEAK(dbm_rdonly);