- int fd;
- uint64_t ret = 0;
- struct timeval now;
-
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0) {
- if (read_all(fd, &ret, sizeof(ret))) {
- tdb_logerr(tdb, TDB_SUCCESS, TDB_DEBUG_TRACE,
- "tdb_open: random from /dev/urandom");
- close(fd);
- return ret;
- }
- close(fd);
- }
- /* FIXME: Untested! Based on Wikipedia protocol description! */
- fd = open("/dev/egd-pool", O_RDWR);
- if (fd >= 0) {
- /* Command is 1, next byte is size we want to read. */
- char cmd[2] = { 1, sizeof(uint64_t) };
- if (write(fd, cmd, sizeof(cmd)) == sizeof(cmd)) {
- char reply[1 + sizeof(uint64_t)];
- int r = read(fd, reply, sizeof(reply));
- if (r > 1) {
- tdb_logerr(tdb, TDB_SUCCESS, TDB_DEBUG_TRACE,
- "tdb_open: %u random bytes from"
- " /dev/egd-pool", r-1);
- /* Copy at least some bytes. */
- memcpy(&ret, reply+1, r - 1);
- if (reply[0] == sizeof(uint64_t)
- && r == sizeof(reply)) {
- close(fd);
- return ret;
- }
- }
- }
- close(fd);
- }
-
- /* Fallback: pid and time. */
- gettimeofday(&now, NULL);
- ret = getpid() * 100132289ULL + now.tv_sec * 1000000ULL + now.tv_usec;
- tdb_logerr(tdb, TDB_SUCCESS, TDB_DEBUG_TRACE,
- "tdb_open: random from getpid and time");
- return ret;
-}
-
-struct new_database {
- struct tdb_header hdr;
- struct tdb_freetable ftable;
-};
-
-/* initialise a new database */
-static int tdb_new_database(struct tdb_context *tdb,
- struct tdb_attribute_seed *seed,
- struct tdb_header *hdr)
-{
- /* We make it up in memory, then write it out if not internal */
- struct new_database newdb;
- unsigned int magic_len;
- ssize_t rlen;
-
- /* Fill in the header */
- newdb.hdr.version = TDB_VERSION;
- if (seed)
- newdb.hdr.hash_seed = seed->seed;
- else
- newdb.hdr.hash_seed = random_number(tdb);
- newdb.hdr.hash_test = TDB_HASH_MAGIC;
- newdb.hdr.hash_test = tdb->khash(&newdb.hdr.hash_test,
- sizeof(newdb.hdr.hash_test),
- newdb.hdr.hash_seed,
- tdb->hash_priv);
- newdb.hdr.recovery = 0;
- memset(newdb.hdr.reserved, 0, sizeof(newdb.hdr.reserved));
- /* Initial hashes are empty. */
- memset(newdb.hdr.hashtable, 0, sizeof(newdb.hdr.hashtable));
-
- /* Free is empty. */
- newdb.hdr.free_table = offsetof(struct new_database, ftable);
- memset(&newdb.ftable, 0, sizeof(newdb.ftable));
- set_header(NULL, &newdb.ftable.hdr, TDB_FTABLE_MAGIC, 0,
- sizeof(newdb.ftable) - sizeof(newdb.ftable.hdr),
- sizeof(newdb.ftable) - sizeof(newdb.ftable.hdr), 0);
-
- /* Magic food */
- memset(newdb.hdr.magic_food, 0, sizeof(newdb.hdr.magic_food));
- strcpy(newdb.hdr.magic_food, TDB_MAGIC_FOOD);
-
- /* This creates an endian-converted database, as if read from disk */
- magic_len = sizeof(newdb.hdr.magic_food);
- tdb_convert(tdb,
- (char *)&newdb.hdr + magic_len, sizeof(newdb) - magic_len);
-
- *hdr = newdb.hdr;