summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2000-02-29 22:52:28 +0000
committerTim Potter <tpot@samba.org>2000-02-29 22:52:28 +0000
commita3c220a197576176b403c8597adc67b85c0a3b9b (patch)
treed95e1c89e668eded1e5d2a7b6fa5c0bdf541072b
parent9c37b6e754a9192251188803aeb013cff52daec6 (diff)
downloadsamba-a3c220a197576176b403c8597adc67b85c0a3b9b.tar.gz
Merge of changes from HEAD branch.
-rw-r--r--source/tdb/.cvsignore8
-rw-r--r--source/tdb/README10
-rw-r--r--source/tdb/tdb.c231
-rw-r--r--source/tdb/tdbtool.c17
4 files changed, 200 insertions, 66 deletions
diff --git a/source/tdb/.cvsignore b/source/tdb/.cvsignore
index af9d6be961b..0480bc977f9 100644
--- a/source/tdb/.cvsignore
+++ b/source/tdb/.cvsignore
@@ -1 +1,7 @@
-*.lo \ No newline at end of file
+*.lo
+tdbtool
+tdbtest
+tdbtorture
+test.db
+test.gdbm
+test.tdb
diff --git a/source/tdb/README b/source/tdb/README
index 3b070bdc400..9eef521075a 100644
--- a/source/tdb/README
+++ b/source/tdb/README
@@ -66,6 +66,11 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open
----------------------------------------------------------------------
+char *tdb_error(TDB_CONTEXT *tdb);
+
+ return a error string for the last tdb error
+
+----------------------------------------------------------------------
int tdb_close(TDB_CONTEXT *tdb);
close a database
@@ -96,9 +101,10 @@ int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
----------------------------------------------------------------------
int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb,
- TDB_DATA key, TDB_DATA dbuf));
+ TDB_DATA key, TDB_DATA dbuf, void *state), void *state);
- traverse the entire database - calling fn(tdb, key, data) on each element.
+ traverse the entire database - calling fn(tdb, key, data, state) on each
+ element.
return -1 on error or the record count traversed
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index a754c583e60..c7b70aa1533 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -92,6 +92,8 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
#else
struct flock fl;
+ if (tdb->fd == -1) return 0; /* for in memory tdb */
+
if (tdb->read_only) return -1;
fl.l_type = set==LOCK_SET?rw_type:F_UNLCK;
@@ -194,7 +196,7 @@ static tdb_off tdb_hash_top(TDB_CONTEXT *tdb, unsigned hash)
static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset)
{
struct stat st;
- if (offset <= tdb->map_size) return 0;
+ if ((offset <= tdb->map_size) || (tdb->fd == -1)) return 0;
fstat(tdb->fd, &st);
if (st.st_size <= (ssize_t)offset) {
@@ -337,8 +339,10 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
length = ((tdb->map_size + length + TDB_PAGE_SIZE) & ~(TDB_PAGE_SIZE - 1)) - tdb->map_size;
/* expand the file itself */
- lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET);
- if (write(tdb->fd, &b, 1) != 1) goto fail;
+ if (tdb->fd != -1) {
+ lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET);
+ if (write(tdb->fd, &b, 1) != 1) goto fail;
+ }
/* form a new freelist record */
offset = FREELIST_TOP;
@@ -349,7 +353,7 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
}
#if HAVE_MMAP
- if (tdb->map_ptr) {
+ if (tdb->fd != -1 && tdb->map_ptr) {
munmap(tdb->map_ptr, tdb->map_size);
tdb->map_ptr = NULL;
}
@@ -357,6 +361,10 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
tdb->map_size += length;
+ if (tdb->fd == -1) {
+ tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size);
+ }
+
/* write it out */
if (rec_write(tdb, tdb->map_size - length, &rec) == -1) {
goto fail;
@@ -367,10 +375,13 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
if (ofs_write(tdb, offset, &ptr) == -1) goto fail;
#if HAVE_MMAP
- tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
- PROT_READ|PROT_WRITE,
- MAP_SHARED | MAP_FILE, tdb->fd, 0);
+ if (tdb->fd != -1) {
+ tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_FILE, tdb->fd, 0);
+ }
#endif
+
tdb_unlock(tdb, -1);
return 0;
@@ -478,37 +489,52 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
{
struct tdb_header header;
tdb_off offset;
- int i;
+ int i, size = 0;
tdb_off buf[16];
- /* create the header */
- memset(&header, 0, sizeof(header));
- memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
- header.version = TDB_VERSION;
- header.hash_size = hash_size;
- lseek(tdb->fd, 0, SEEK_SET);
- ftruncate(tdb->fd, 0);
-
- if (write(tdb->fd, &header, sizeof(header)) != sizeof(header)) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- }
+ /* create the header */
+ memset(&header, 0, sizeof(header));
+ memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
+ header.version = TDB_VERSION;
+ header.hash_size = hash_size;
+ lseek(tdb->fd, 0, SEEK_SET);
+ ftruncate(tdb->fd, 0);
+
+ if (tdb->fd != -1 && write(tdb->fd, &header, sizeof(header)) !=
+ sizeof(header)) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ } else size += sizeof(header);
- /* the freelist and hash pointers */
- offset = 0;
- memset(buf, 0, sizeof(buf));
- for (i=0;(hash_size+1)-i >= 16; i += 16) {
- if (write(tdb->fd, buf, sizeof(buf)) != sizeof(buf)) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- }
- }
- for (;i<hash_size+1; i++) {
- if (write(tdb->fd, buf, sizeof(tdb_off)) != sizeof(tdb_off)) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- }
- }
+ /* the freelist and hash pointers */
+ offset = 0;
+ memset(buf, 0, sizeof(buf));
+
+ for (i=0;(hash_size+1)-i >= 16; i += 16) {
+ if (tdb->fd != -1 && write(tdb->fd, buf, sizeof(buf)) !=
+ sizeof(buf)) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ } else size += sizeof(buf);
+ }
+
+ for (;i<hash_size+1; i++) {
+ if (tdb->fd != -1 && write(tdb->fd, buf, sizeof(tdb_off)) !=
+ sizeof(tdb_off)) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ } else size += sizeof(tdb_off);
+ }
+
+ if (tdb->fd == -1) {
+ tdb->map_ptr = calloc(size, 1);
+ tdb->map_size = size;
+ if (tdb->map_ptr == NULL) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ }
+ memcpy(&tdb->header, &header, sizeof(header));
+ }
#if TDB_DEBUG
printf("initialised database of hash_size %u\n",
@@ -597,6 +623,13 @@ int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
tdb_off rec_ptr;
int ret = -1;
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_update() called with null context\n");
+#endif
+ return -1;
+ }
+
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -634,6 +667,13 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
struct list_struct rec;
TDB_DATA ret = null_data;
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_fetch() called with null context\n");
+#endif
+ return null_data;
+ }
+
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -687,6 +727,13 @@ int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB
char *data;
TDB_DATA key, dbuf;
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_traverse() called with null context\n");
+#endif
+ return -1;
+ }
+
/* loop over all hash chains */
for (h = 0; h < tdb->header.hash_size; h++) {
tdb_lock(tdb, BUCKET(h));
@@ -749,6 +796,13 @@ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb)
unsigned hash;
TDB_DATA ret;
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_firstkey() called with null context\n");
+#endif
+ return null_data;
+ }
+
/* look for a non-empty hash chain */
for (hash = 0, rec_ptr = 0;
hash < tdb->header.hash_size;
@@ -794,6 +848,13 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key)
struct list_struct rec;
TDB_DATA ret;
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_nextkey() called with null context\n");
+#endif
+ return null_data;
+ }
+
/* find which hash bucket it is in */
hash = tdb_hash(&key);
hbucket = BUCKET(hash);
@@ -842,6 +903,13 @@ int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
struct list_struct rec, lastrec;
char *data = NULL;
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_delete() called with null context\n");
+#endif
+ return -1;
+ }
+
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -940,6 +1008,13 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
tdb_off rec_ptr, offset;
char *p = NULL;
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_store() called with null context\n");
+#endif
+ return -1;
+ }
+
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -1033,6 +1108,8 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
TDB_CONTEXT tdb, *ret;
struct stat st;
+ memset(&tdb, 0, sizeof(tdb));
+
tdb.fd = -1;
tdb.name = NULL;
tdb.map_ptr = NULL;
@@ -1043,14 +1120,14 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE;
- memset(&tdb, 0, sizeof(tdb));
-
tdb.read_only = ((open_flags & O_ACCMODE) == O_RDONLY);
- tdb.fd = open(name, open_flags, mode);
- if (tdb.fd == -1) {
+ if (name != NULL) {
+ tdb.fd = open(name, open_flags, mode);
+ if (tdb.fd == -1) {
goto fail;
- }
+ }
+ }
/* ensure there is only one process initialising at once */
tdb_brlock(&tdb, GLOBAL_LOCK, LOCK_SET, F_WRLCK, F_SETLKW);
@@ -1077,23 +1154,32 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
if (tdb_new_database(&tdb, hash_size) == -1) goto fail;
lseek(tdb.fd, 0, SEEK_SET);
- if (read(tdb.fd, &tdb.header, sizeof(tdb.header)) != sizeof(tdb.header)) goto fail;
+ if (tdb.fd != -1 && read(tdb.fd, &tdb.header,
+ sizeof(tdb.header)) !=
+ sizeof(tdb.header))
+ goto fail;
}
- fstat(tdb.fd, &st);
+ if (tdb.fd != -1) {
+ fstat(tdb.fd, &st);
+
+ /* map the database and fill in the return structure */
+ tdb.name = (char *)strdup(name);
+ tdb.map_size = st.st_size;
+ }
+
+ tdb.locked = (int *)calloc(tdb.header.hash_size+1,
+ sizeof(tdb.locked[0]));
+ if (!tdb.locked) {
+ goto fail;
+ }
- /* map the database and fill in the return structure */
- tdb.name = (char *)strdup(name);
- tdb.locked = (int *)calloc(tdb.header.hash_size+1,
- sizeof(tdb.locked[0]));
- if (!tdb.locked) {
- goto fail;
- }
- tdb.map_size = st.st_size;
#if HAVE_MMAP
- tdb.map_ptr = (void *)mmap(NULL, st.st_size,
- tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE,
- MAP_SHARED | MAP_FILE, tdb.fd, 0);
+ if (tdb.fd != -1) {
+ tdb.map_ptr = (void *)mmap(NULL, st.st_size,
+ tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_FILE, tdb.fd, 0);
+ }
#endif
ret = (TDB_CONTEXT *)malloc(sizeof(tdb));
@@ -1110,7 +1196,7 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
return ret;
fail:
- if (tdb.name) free(tdb.name);
+ if (tdb.name) free(tdb.name);
if (tdb.fd != -1) close(tdb.fd);
if (tdb.map_ptr) munmap(tdb.map_ptr, tdb.map_size);
@@ -1124,9 +1210,16 @@ int tdb_close(TDB_CONTEXT *tdb)
if (tdb->name) free(tdb->name);
if (tdb->fd != -1) close(tdb->fd);
- if (tdb->map_ptr) munmap(tdb->map_ptr, tdb->map_size);
if (tdb->locked) free(tdb->locked);
+ if (tdb->map_ptr) {
+ if (tdb->fd != -1) {
+ munmap(tdb->map_ptr, tdb->map_size);
+ } else {
+ free(tdb->map_ptr);
+ }
+ }
+
memset(tdb, 0, sizeof(*tdb));
free(tdb);
@@ -1136,12 +1229,26 @@ int tdb_close(TDB_CONTEXT *tdb)
/* lock the database. If we already have it locked then don't do anything */
int tdb_writelock(TDB_CONTEXT *tdb)
{
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_writelock() called with null context\n");
+#endif
+ return -1;
+ }
+
return tdb_lock(tdb, -1);
}
/* unlock the database. */
int tdb_writeunlock(TDB_CONTEXT *tdb)
{
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_writeunlock() called with null context\n");
+#endif
+ return -1;
+ }
+
return tdb_unlock(tdb, -1);
}
@@ -1149,6 +1256,13 @@ int tdb_writeunlock(TDB_CONTEXT *tdb)
contention - it cannot guarantee how many records will be locked */
int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key)
{
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_lockchain() called with null context\n");
+#endif
+ return -1;
+ }
+
return tdb_lock(tdb, BUCKET(tdb_hash(&key)));
}
@@ -1156,5 +1270,12 @@ int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key)
/* unlock one hash chain */
int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key)
{
+ if (tdb == NULL) {
+#ifdef TDB_DEBUG
+ printf("tdb_unlockchain() called with null context\n");
+#endif
+ return -1;
+ }
+
return tdb_unlock(tdb, BUCKET(tdb_hash(&key)));
}
diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c
index 43c7faf2bf1..317ad9b4fc5 100644
--- a/source/tdb/tdbtool.c
+++ b/source/tdb/tdbtool.c
@@ -134,12 +134,7 @@ static void delete_tdb(void)
}
}
-static int del_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void*)
-{
- tdb_delete(tdb, key);
-}
-
-static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void*)
+static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
printf("%*.*s : %*.*s\n",
(int)key.dsize, (int)key.dsize, key.dptr,
@@ -149,7 +144,7 @@ static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void*)
static int total_bytes;
-static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void*)
+static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
total_bytes += dbuf.dsize;
return 0;
@@ -175,6 +170,12 @@ static char *getline(char *prompt)
return p?line:NULL;
}
+static int do_delete_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
+ void *state)
+{
+ return tdb_delete(tdb, key);
+}
+
int main(int argc, char *argv[])
{
char *line;
@@ -204,7 +205,7 @@ int main(int argc, char *argv[])
} else if (strcmp(tok,"show") == 0) {
show_tdb();
} else if (strcmp(tok,"erase") == 0) {
- tdb_traverse(tdb, del_rec, NULL);
+ tdb_traverse(tdb, do_delete_fn, NULL);
} else if (strcmp(tok,"delete") == 0) {
delete_tdb();
} else if (strcmp(tok,"dump") == 0) {