bool os_remove_nonempty_dir(const std::wstring &path) { WIN32_FIND_DATAW wfd; HANDLE hf=FindFirstFileW((path+L"\\*").c_str(), &wfd); BOOL b=true; while( b ) { if( (std::wstring)wfd.cFileName!=L"." && (std::wstring)wfd.cFileName!=L".." ) { if( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { os_remove_nonempty_dir(path+L"\\"+wfd.cFileName); } else { DeleteFileW((path+L"\\"+wfd.cFileName).c_str()); } } b=FindNextFileW(hf,&wfd); } FindClose(hf); RemoveDirectoryW(path.c_str()); return true; }
bool remove_subvolume(std::string subvolume_folder) { #ifdef _WIN32 return os_remove_nonempty_dir(widen(subvolume_folder)); #else int rc=system((btrfs_cmd+" subvolume delete \""+subvolume_folder+"\"").c_str()); return rc==0; #endif }
void BackupServer::operator()(void) { IDatabase *db=Server->getDatabase(Server->getThreadID(),URBACKUPDB_SERVER); ISettingsReader *settings=Server->createDBSettingsReader(Server->getDatabase(Server->getThreadID(),URBACKUPDB_SERVER), "settings_db.settings"); #ifdef _WIN32 std::wstring tmpdir; if(settings->getValue(L"tmpdir", &tmpdir) && !tmpdir.empty()) { os_remove_nonempty_dir(tmpdir+os_file_sep()+L"urbackup_tmp"); if(!os_create_dir(tmpdir+os_file_sep()+L"urbackup_tmp")) { Server->wait(5000); os_create_dir(tmpdir+os_file_sep()+L"urbackup_tmp"); } Server->setTemporaryDirectory(tmpdir+os_file_sep()+L"urbackup_tmp"); } else { wchar_t tmpp[MAX_PATH]; DWORD l; if((l=GetTempPathW(MAX_PATH, tmpp))==0 || l>MAX_PATH ) { wcscpy_s(tmpp,L"C:\\"); } std::wstring w_tmp=tmpp; if(!w_tmp.empty() && w_tmp[w_tmp.size()-1]=='\\') { w_tmp.erase(w_tmp.size()-1, 1); } os_remove_nonempty_dir(w_tmp+os_file_sep()+L"urbackup_tmp"); if(!os_create_dir(w_tmp+os_file_sep()+L"urbackup_tmp")) { Server->wait(5000); os_create_dir(tmpdir+os_file_sep()+L"urbackup_tmp"); } Server->setTemporaryDirectory(w_tmp+os_file_sep()+L"urbackup_tmp"); } #endif if( settings->getValue("use_tmpfiles", "")!="true" ) { std::wstring backupfolder; if( settings->getValue(L"backupfolder", &backupfolder) ) { std::wstring tmpfile_path=backupfolder+os_file_sep()+L"urbackup_tmp_files"; Server->Log("Removing temporary files..."); os_remove_nonempty_dir(tmpfile_path); Server->Log("Recreating temporary folder..."); if(!os_create_dir(tmpfile_path)) { Server->wait(5000); os_create_dir(tmpfile_path); } } } testSnapshotAvailability(db); q_get_extra_hostnames=db->Prepare("SELECT id,hostname FROM settings_db.extra_clients"); q_update_extra_ip=db->Prepare("UPDATE settings_db.extra_clients SET lastip=? WHERE id=?"); FileClient fc; Server->wait(1000); while(true) { findClients(fc); startClients(fc); if(!ServerStatus::isActive() && settings->getValue("autoshutdown", "false")=="true") { writestring("true", "urbackup/shutdown_now"); #ifdef _WIN32 ExitWindowsEx(EWX_POWEROFF|EWX_FORCEIFHUNG, SHTDN_REASON_MAJOR_APPLICATION|SHTDN_REASON_MINOR_OTHER ); #endif } std::string r; exitpipe->Read(&r, 20000); if(r=="exit") { removeAllClients(); exitpipe->Write("ok"); Server->destroy(settings); db->destroyAllQueries(); delete this; return; } } }
bool remove_subvolume(int mode, std::string subvolume_folder, bool quiet=false) { #ifdef _WIN32 return os_remove_nonempty_dir(widen(subvolume_folder)); #else if(mode==mode_btrfs) { int compat_rc = exec_wait(find_btrfs_cmd(), false, "subvolume", "delete", "-c", NULL); if(compat_rc==1) { compat_rc = exec_wait("/bin/sh", false, "-c", (find_btrfs_cmd() + " subvolume delete -c 2>&1 | grep \"ERROR: error accessing '-c'\"").c_str(), NULL); if(compat_rc==0) { compat_rc=12; } } int rc; if(compat_rc==12) { rc=exec_wait(find_btrfs_cmd(), !quiet, "subvolume", "delete", subvolume_folder.c_str(), NULL); } else { rc=exec_wait(find_btrfs_cmd(), !quiet, "subvolume", "delete", "-c", subvolume_folder.c_str(), NULL); } return rc==0; } else if(mode==mode_zfs) { zfs_elevate(); exec_wait(find_zfs_cmd(), false, "destroy", (subvolume_folder+"@ro").c_str(), NULL); int rc = exec_wait(find_zfs_cmd(), false, "destroy", subvolume_folder.c_str(), NULL); if(rc!=0) { std::cout << "Destroying subvol " << subvolume_folder << " failed. Promoting dependencies..." << std::endl; std::string rename_name = ExtractFileName(subvolume_folder); if(exec_wait(find_zfs_cmd(), true, "rename", (subvolume_folder+"@ro").c_str(), (subvolume_folder+"@"+rename_name).c_str(), NULL)!=0 && is_subvolume(mode, subvolume_folder+"@ro") ) { return false; } std::vector<std::string> dependencies; if(!promote_dependencies(subvolume_folder+"@"+rename_name, dependencies)) { return false; } rc = exec_wait(find_zfs_cmd(), true, "destroy", subvolume_folder.c_str(), NULL); if(rc==0) { for(size_t i=0;i<dependencies.size();++i) { if(is_subvolume(mode, dependencies[i]+"@"+rename_name)) { rc = exec_wait(find_zfs_cmd(), true, "destroy", (dependencies[i]+"@"+rename_name).c_str(), NULL); if(rc!=0) { break; } } } } } return rc==0; } return false; #endif }