diff options
author | Tim Potter <tpot@samba.org> | 2000-02-29 22:52:28 +0000 |
---|---|---|
committer | Tim Potter <tpot@samba.org> | 2000-02-29 22:52:28 +0000 |
commit | a3c220a197576176b403c8597adc67b85c0a3b9b (patch) | |
tree | d95e1c89e668eded1e5d2a7b6fa5c0bdf541072b | |
parent | 9c37b6e754a9192251188803aeb013cff52daec6 (diff) | |
download | samba-a3c220a197576176b403c8597adc67b85c0a3b9b.tar.gz |
Merge of changes from HEAD branch.
-rw-r--r-- | source/tdb/.cvsignore | 8 | ||||
-rw-r--r-- | source/tdb/README | 10 | ||||
-rw-r--r-- | source/tdb/tdb.c | 231 | ||||
-rw-r--r-- | source/tdb/tdbtool.c | 17 |
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) { |