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;
}
Beispiel #2
0
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
}	
Beispiel #3
0
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;
		}
	}
}
Beispiel #4
0
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
}