- /* We make it up in memory, then write it out if not internal */
- struct new_database newdb;
- unsigned int bucket, magic_off, dbsize;
-
- /* Don't want any extra padding! */
- dbsize = offsetof(struct new_database, tailer) + sizeof(newdb.tailer);
-
- /* Fill in the header */
- newdb.h.hdr.version = TDB_VERSION;
- newdb.h.hdr.hash_seed = random_number(tdb);
- newdb.h.hdr.hash_test = TDB_HASH_MAGIC;
- newdb.h.hdr.hash_test = tdb->khash(&newdb.h.hdr.hash_test,
- sizeof(newdb.h.hdr.hash_test),
- newdb.h.hdr.hash_seed,
- tdb->hash_priv);
- memset(newdb.h.hdr.reserved, 0, sizeof(newdb.h.hdr.reserved));
- newdb.h.hdr.v.generation = 0;
- /* Initial hashes are empty. */
- newdb.h.hdr.v.hash_bits = INITIAL_HASH_BITS;
- newdb.h.hdr.v.hash_off = offsetof(struct new_database, h.hash);
- set_header(tdb, &newdb.h.hrec, 0,
- sizeof(newdb.h.hash), sizeof(newdb.h.hash), 0,
- INITIAL_ZONE_BITS);
- memset(newdb.h.hash, 0, sizeof(newdb.h.hash));
-
- /* Create the single free entry. */
- newdb.h.frec.magic_and_meta = TDB_FREE_MAGIC | INITIAL_ZONE_BITS;
- newdb.h.frec.data_len = (sizeof(newdb.h.frec)
- - sizeof(struct tdb_used_record)
- + sizeof(newdb.space));
-
- /* Free is mostly empty... */
- newdb.h.zhdr.zone_bits = INITIAL_ZONE_BITS;
- memset(newdb.h.free, 0, sizeof(newdb.h.free));
-
- /* ... except for this one bucket. */
- bucket = size_to_bucket(INITIAL_ZONE_BITS, newdb.h.frec.data_len);
- newdb.h.free[bucket] = offsetof(struct new_database, h.frec);
- newdb.h.frec.next = newdb.h.frec.prev = 0;
-
- /* Clear free space to keep valgrind happy, and avoid leaking stack. */
- memset(newdb.space, 0, sizeof(newdb.space));
-
- /* Tailer contains maximum number of free_zone bits. */
- newdb.tailer = INITIAL_ZONE_BITS;
-
- /* Magic food */
- memset(newdb.h.hdr.magic_food, 0, sizeof(newdb.h.hdr.magic_food));
- strcpy(newdb.h.hdr.magic_food, TDB_MAGIC_FOOD);
-
- /* This creates an endian-converted database, as if read from disk */
- magic_off = offsetof(struct tdb_header, magic_food);
- tdb_convert(tdb,
- (char *)&newdb.h.hdr + magic_off,
- dbsize - 1 - magic_off);
-
- tdb->header = newdb.h.hdr;
-
- if (tdb->flags & TDB_INTERNAL) {
- tdb->map_size = dbsize;
- tdb->map_ptr = malloc(tdb->map_size);
- if (!tdb->map_ptr) {
- tdb->ecode = TDB_ERR_OOM;
- return -1;
- }
- memcpy(tdb->map_ptr, &newdb, tdb->map_size);
- return 0;
- }
- if (lseek(tdb->fd, 0, SEEK_SET) == -1)
- return -1;
-
- if (ftruncate(tdb->fd, 0) == -1)
- return -1;