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); }
// 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
/* * 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); }