Exemple #1
0
static int btreeCleanupEnv(const char *home)
{
	DB_ENV *tmp_env;
	int count, i, ret;
	char **names, buf[512];

	log_msg(LOG_DEBUG, "btreeCleanupEnv removing existing env.");
	/*
	 * If there is a directory (environment), but no
	 * database file. Clear the environment to avoid
	 * carrying over information from earlier sessions.
	 */
	if ((ret = db_env_create(&tmp_env, 0)) != 0)
		return ret;

	/* Remove log files */
	if ((ret = __os_dirlist(tmp_env->env, home, 0, &names, &count)) != 0) {
		(void)tmp_env->close(tmp_env, 0);
		return ret;
	}

	for (i = 0; i < count; i++) {
		if (strncmp(names[i], "log.", 4) != 0)
			continue;
		sqlite3_snprintf(sizeof(buf), buf, "%s%s%s",
		    home, "/", names[i]);
		/*
		 * Use Berkeley DB __os_unlink (not sqlite3OsDelete) since
		 * this file has always been managed by Berkeley DB.
		 */
		(void)__os_unlink(NULL, buf, 0);
	}

	__os_dirfree(tmp_env->env, names, count);

	/*
	 * TODO: Do we want force here? Ideally all handles
	 * would always be closed on exit, so DB_FORCE would
	 * not be necessary.  The world is not currently ideal.
	 */
	return tmp_env->remove(tmp_env, home, DB_FORCE);
}
Exemple #2
0
// Create test directory.
inline int dir_setup(const char *testdir)
{
	int ret;

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 3
	if ((ret = __os_mkdir(NULL, testdir, 0755)) != 0) {
#else
	if ((ret = mkdir(testdir, 0755)) != 0) {
#endif
		fprintf(stderr,
		    "dir_setup: Creating directory %s: %s\n", 
		    testdir, db_strerror(ret));
		return (1);
	}
	return (0);
}

inline int os_unlink(const char *path)
{
#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 7
	return (__os_unlink(NULL, path));
#else
	return (__os_unlink(NULL, path, 0));
#endif
}

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 4
#define	OS_EXISTS(a, b, c)	__os_exists(a, b, c)
#else
#define	OS_EXISTS(a, b, c)	__os_exists(b, c)
#endif

// Remove contents in specified directory recursively(in DB versions earlier 
// than 4.6, don't recursively), and optionally remove the directory itself.
int rmdir_rcsv(const char *dir, bool keep_this_dir)
{
	int cnt, i, isdir, ret;
	char buf[1024], **names;

	ret = 0;

	/* If the directory doesn't exist, we're done. */
	if (OS_EXISTS(NULL, dir, &isdir) != 0)
		return (0);

	/* Get a list of the directory contents. */
#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 6
	if ((ret = __os_dirlist(NULL, dir, 1, &names, &cnt)) != 0)
		return (ret);
#else
	if ((ret = __os_dirlist(NULL, dir, &names, &cnt)) != 0)
		return (ret);
#endif
	/* Go through the file name list, remove each file in the list */
	for (i = 0; i < cnt; ++i) {
		(void)snprintf(buf, sizeof(buf),
		    "%s%c%s", dir, PATH_SEPARATOR[0], names[i]);
		if ((ret = OS_EXISTS(NULL, buf, &isdir)) != 0)
			goto file_err;
		if (!isdir && (ret = os_unlink(buf)) != 0) {
file_err:		fprintf(stderr, 
			    "os_unlink: Error unlinking file: %s: %s\n",
			    buf, db_strerror(ret));
			break;
		}
		if (isdir && rmdir_rcsv(buf, false) != 0)
			goto file_err;
	}

	__os_dirfree(NULL, names, cnt);

	/*
	 * If we removed the contents of the directory and we don't want to
	 * keep this directory, remove the directory itself.
	 */
	if (i == cnt && !keep_this_dir && (ret = rmdir(dir)) != 0)
		fprintf(stderr,
		    "rmdir_rcsv(%s): %s\n", dir, db_strerror(errno));
	return (ret);
} // rmdir_rcsv
Exemple #3
0
/*
 * Deletes all data and environment files of the given Btree.  Requires
 * that there are no other handles using the BtShared when this function
 * is called.
 */
int btreeDeleteEnvironment(Btree *p, const char *home, int rename)
{
	BtShared *pBt;
	int rc, ret, iDb, storage;
	sqlite3 *db;
	DB_ENV *tmp_env;
	char path[512];
#ifdef BDBSQL_FILE_PER_TABLE
	int numFiles;
	char **files;
#endif

	rc = SQLITE_OK;
	ret = 0;
	tmp_env = NULL;

	if (p != NULL) {
		if ((rc = btreeUpdateBtShared(p, 1)) != SQLITE_OK)
			goto err;
		pBt = p->pBt;
		if (pBt->nRef > 1)
			return SQLITE_BUSY;

		storage = pBt->dbStorage;
		db = p->db;
		for (iDb = 0; iDb < db->nDb; iDb++) {
			if (db->aDb[iDb].pBt == p)
				break;
		}
		if ((rc = sqlite3BtreeClose(p)) != SQLITE_OK)
			goto err;
		pBt = NULL;
		p = NULL;
		db->aDb[iDb].pBt = NULL;
	}
	if (home == NULL)
		goto done;

	ret = btreeCleanupEnv(path);
	/* EFAULT can be returned on Windows when the file does not exist.*/
	if (ret == ENOENT || ret == EFAULT)
		ret = 0;
	else if (ret != 0)
		goto err;

	if ((ret = db_env_create(&tmp_env, 0)) != 0)
		goto err;

	if (rename) {
		if (!(ret = __os_exists(tmp_env->env, home, 0))) {
			sqlite3_snprintf(sizeof(path), path,
			    "%s%s", home, BACKUP_SUFFIX);
			ret = __os_rename(tmp_env->env, home, path, 0);
		}
	} else {
#ifdef BDBSQL_FILE_PER_TABLE
		ret = __os_dirlist(tmp_env->env, home, 0, &files, &numFiles);
		if (ret == 0) {
			int i, ret2;
			for (i = 0; i < numFiles; i++) {
				sqlite3_snprintf(sizeof(path), path, "%s/%s",
				    home, files[i]);
				if ((ret2 = __os_unlink (tmp_env->env, path, 0))
				    != 0)
					ret = ret2;
			}
		}
		__os_dirfree(tmp_env->env, files, numFiles);
		if (ret == 0)
			ret = __os_unlink(tmp_env->env, home, 0);

#else
		if (!(ret = __os_exists(tmp_env->env, home, 0)))
			ret = __os_unlink(tmp_env->env, home, 0);
#endif
	}
	/* EFAULT can be returned on Windows when the file does not exist.*/
	if (ret == ENOENT || ret == EFAULT)
		ret = 0;
	else if (ret != 0)
		goto err;

err:
done:	if (tmp_env != NULL)
		tmp_env->close(tmp_env, 0);

	return MAP_ERR(rc, ret);
}