CServerPath CRemoteTreeView::GetPathFromItem(const wxTreeItemId& item) const
{
	std::list<wxString> segments;

	wxTreeItemId i = item;
	while (i != GetRootItem())
	{
		const CItemData* const pData = (const CItemData*)GetItemData(i);
		if (pData)
		{
			CServerPath path = pData->m_path;
			for (std::list<wxString>::const_iterator iter = segments.begin(); iter != segments.end(); ++iter)
			{
				if (!path.AddSegment(*iter))
					return CServerPath();
			}
			return path;
		}

		segments.push_front(GetItemText(i));
		i = GetItemParent(i);
	}

	return CServerPath();
}
	CServerPath DisplayDropHighlight(wxPoint point)
	{
		wxTreeItemId hit = GetHit(point);
		if (!hit)
		{
			ClearDropHighlight();
			return CServerPath();
		}

		const CServerPath& path = m_pRemoteTreeView->GetPathFromItem(hit);

		if (path.IsEmpty())
		{
			ClearDropHighlight();
			return CServerPath();
		}

		const wxTreeItemId dropHighlight = m_pRemoteTreeView->m_dropHighlight;
		if (dropHighlight != wxTreeItemId())
			m_pRemoteTreeView->SetItemDropHighlight(dropHighlight, false);

		m_pRemoteTreeView->SetItemDropHighlight(hit, true);
		m_pRemoteTreeView->m_dropHighlight = hit;

		return path;
	}
CServerPath::CServerPath(CString path)
{
	m_nServerType = FZ_SERVERTYPE_FTP;
	path.TrimLeft( _T(" ") );
	path.TrimRight( _T(" ") );
	if (path == _MPT(""))
	{
		m_bEmpty = TRUE;
		return;
	}
	else
		m_bEmpty = FALSE;

	int pos1 = path.Find( _T(":[") );
	if (pos1 != -1 && path.Right(1) == _MPT("]") && pos1 != (path.GetLength()-1))
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
	else if (path.GetLength() >= 3 && _istalpha(path[0]) && path[1] == _MPT(':') && (path[2] == _MPT('\\') || path[2] == _MPT('/')))
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_WINDOWS;
	else if (path[0] == FTP_MVS_DOUBLE_QUOTA && path[path.GetLength() - 1] == FTP_MVS_DOUBLE_QUOTA)
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS;
	else if (path.GetLength() > 2 && path[0] == _MPT('\'') && path.Right(1) == _T("'") && path.Find(_MPT('/')) == -1 && path.Find(_MPT('\\')) == -1)
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS;
	else if (path.GetLength() >= 2 && path[0] != _MPT('/') && path.Right(1) == _T("."))
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_UNKNOWN;

	*this = CServerPath(path, m_nServerType);
}
void CRemoteTreeView::OnContextMenu(wxTreeEvent& event)
{
	m_contextMenuItem = event.GetItem();
	wxMenu* pMenu = wxXmlResource::Get()->LoadMenu(_T("ID_MENU_REMOTETREE"));
	if (!pMenu)
		return;

	const CServerPath& path = m_contextMenuItem ? GetPathFromItem(m_contextMenuItem) : CServerPath();
	if (!m_pState->IsRemoteIdle() || path.empty())
	{
		pMenu->Enable(XRCID("ID_DOWNLOAD"), false);
		pMenu->Enable(XRCID("ID_ADDTOQUEUE"), false);
		pMenu->Enable(XRCID("ID_MKDIR"), false);
		pMenu->Enable(XRCID("ID_MKDIR_CHGDIR"), false);
		pMenu->Enable(XRCID("ID_DELETE"), false);
		pMenu->Enable(XRCID("ID_CHMOD"), false);
		pMenu->Enable(XRCID("ID_RENAME"), false);
		pMenu->Enable(XRCID("ID_GETURL"), false);
	}
	else if (!path.HasParent())
		pMenu->Enable(XRCID("ID_RENAME"), false);

	if (!m_pState->GetLocalDir().IsWriteable())
	{
		pMenu->Enable(XRCID("ID_DOWNLOAD"), false);
		pMenu->Enable(XRCID("ID_ADDTOQUEUE"), false);
	}

	PopupMenu(pMenu);
	delete pMenu;
}
const CServerPath CState::GetRemotePath() const
{
	if (!m_pDirectoryListing)
		return CServerPath();

	return m_pDirectoryListing->path;
}
Exemple #6
0
CServerPath CPathCache::Lookup(const tServerCache &serverCache, const CServerPath& source, const wxString subdir)
{
	CSourcePath sourcePath;
	sourcePath.source = source;
	sourcePath.subdir = subdir;

	tServerCacheConstIterator serverIter = serverCache.find(sourcePath);
	if (serverIter == serverCache.end())
		return CServerPath();

	return serverIter->second;
}
bool CClearPrivateDataDialog::ClearReconnect()
{
	COptions::Get()->SetLastServer(CServer());
	COptions::Get()->SetOption(OPTION_LASTSERVERPATH, _T(""));

	const std::vector<CState*> *states = CContextManager::Get()->GetAllStates();
	for (std::vector<CState*>::const_iterator iter = states->begin(); iter != states->end(); ++iter)
	{
		CState* pState = *iter;

		pState->SetLastServer(CServer(), CServerPath());
	}

	return true;
}
Exemple #8
0
CServerPath CServerPath::GetParent() const
{
	if (empty() || !HasParent())
		return CServerPath();

	CServerPath parent(*this);
	CServerPathData& parent_data = parent.m_data.Get();

	parent_data.m_segments.pop_back();

	if (m_type == MVS)
		parent_data.m_prefix = CSparseOptional<wxString>(_T("."));

	return parent;
}
Exemple #9
0
CServerPath CPathCache::Lookup(const CServer& server, const CServerPath& source, const wxString subdir /*=_T("")*/)
{
	const tCacheConstIterator iter = m_cache.find(server);
	if (iter == m_cache.end())
		return CServerPath();

	CServerPath result = Lookup(*iter->second, source, subdir);

	if (result.IsEmpty())
		m_misses++;
	else
		m_hits++;

	return result;
}
Exemple #10
0
CServerPath CServerPath::GetParent() const
{
	if (!HasParent())
		return CServerPath();

	CServerPath parent(*this);
	CServerPathData& parent_data = parent.m_data.Get();

	parent_data.m_segments.pop_back();

	if (m_type == MVS)
		parent_data.m_prefix = _T(".");

	return parent;
}
Exemple #11
0
CServerPath CPathCache::Lookup(CServer const& server, CServerPath const& source, wxString const& subdir)
{
	scoped_lock lock(mutex_);

	const tCacheConstIterator iter = m_cache.find(server);
	if (iter == m_cache.end())
		return CServerPath();

	CServerPath result = Lookup(iter->second, source, subdir);

	if (result.empty())
		m_misses++;
	else
		m_hits++;

	return result;
}
CServerPath CServerPath::GetParent() const
{
	if (empty() || !HasParent()) {
		return CServerPath();
	}

	CServerPath parent(*this);
	CServerPathData& parent_data = parent.m_data.get();

	parent_data.m_segments.pop_back();

	if (m_type == MVS) {
		parent_data.m_prefix = fz::sparse_optional<std::wstring>(L".");
	}

	return parent;
}
CServerPath CState::GetSynchronizedDirectory(CLocalPath local_path)
{
	std::list<wxString> segments;
	while (local_path.HasParent() && local_path != m_sync_browse.local_root)
	{
		wxString last;
		local_path.MakeParent(&last);
		segments.push_front(last);
	}
	if (local_path != m_sync_browse.local_root)
		return CServerPath();

	CServerPath remote_path = m_sync_browse.remote_root;
	for (std::list<wxString>::const_iterator iter = segments.begin(); iter != segments.end(); ++iter)
		remote_path.AddSegment(*iter);

	return remote_path;
}
//---------------------------------------------------------------------------
bool TFileZillaIntf::FileTransfer(const wchar_t * LocalFile,
  const wchar_t * RemoteFile, const wchar_t * RemotePath, bool Get, __int64 Size,
  int Type, void * UserData)
{
  t_transferfile Transfer;

  Transfer.localfile = LocalFile;
  Transfer.remotefile = RemoteFile;
  Transfer.remotepath = CServerPath(RemotePath);
  Transfer.get = Get;
  Transfer.size = Size;
  Transfer.server = *FServer;
  // 1 = ascii, 2 = binary
  Transfer.nType = Type;
  Transfer.nUserData = UserData;

  return Check(FFileZillaApi->FileTransfer(Transfer), L"filetransfer");
}
// Help-Function to create a new Directory
// Returns the name of the new directory
CServerPath CRemoteTreeView::MenuMkdir()
{
	if (!m_pState->IsRemoteIdle())
		return CServerPath();

	if (!m_contextMenuItem)
		return CServerPath();

	const CServerPath& path = GetPathFromItem(m_contextMenuItem);
	if (path.empty())
		return CServerPath();

	CInputDialog dlg;
	if (!dlg.Create(this, _("Create directory"), _("Please enter the name of the directory which should be created:")))
		return CServerPath();

	CServerPath newPath = path;

	// Append a long segment which does (most likely) not exist in the path and
	// replace it with "New directory" later. This way we get the exact position of
	// "New directory" and can preselect it in the dialog.
	wxString tmpName = _T("25CF809E56B343b5A12D1F0466E3B37A49A9087FDCF8412AA9AF8D1E849D01CF");
	if (newPath.AddSegment(tmpName))
	{
		wxString pathName = newPath.GetPath();
		int pos = pathName.Find(tmpName);
		wxASSERT(pos != -1);
		wxString newName = _("New directory");
		pathName.Replace(tmpName, newName);
		dlg.SetValue(pathName);
		dlg.SelectText(pos, pos + newName.Length());
	}

	if (dlg.ShowModal() != wxID_OK)
		return CServerPath();

	newPath = path;
	if (!newPath.ChangePath(dlg.GetValue()))
	{
		wxBell();
		return CServerPath();
	}

	m_pState->m_pCommandQueue->ProcessCommand(new CMkdirCommand(newPath));

	return newPath;
}
void CRemoteRecursiveOperation::ProcessDirectoryListing(const CDirectoryListing* pDirectoryListing)
{
	if (!pDirectoryListing) {
		StopRecursiveOperation();
		return;
	}

	if (m_operationMode == recursive_none || recursion_roots_.empty())
		return;

	if (pDirectoryListing->failed()) {
		// Ignore this.
		// It will get handled by the failed command in ListingFailed
		return;
	}

	auto & root = recursion_roots_.front();
	wxASSERT(!root.m_dirsToVisit.empty());

	if (!m_state.IsRemoteConnected() || root.m_dirsToVisit.empty()) {
		StopRecursiveOperation();
		return;
	}

	recursion_root::new_dir dir = root.m_dirsToVisit.front();
	root.m_dirsToVisit.pop_front();

	if (!BelowRecursionRoot(pDirectoryListing->path, dir)) {
		NextOperation();
		return;
	}

	if (m_operationMode == recursive_delete && dir.doVisit && !dir.subdir.empty()) {
		// After recursing into directory to delete its contents, delete directory itself
		// Gets handled in NextOperation
		recursion_root::new_dir dir2 = dir;
		dir2.doVisit = false;
		root.m_dirsToVisit.push_front(dir2);
	}

	if (dir.link && !dir.recurse) {
		NextOperation();
		return;
	}

	// Check if we have already visited the directory
	if (!root.m_visitedDirs.insert(pDirectoryListing->path).second) {
		NextOperation();
		return;
	}

	++m_processedDirectories;

	const CServer* pServer = m_state.GetServer();
	wxASSERT(pServer);

	if (!pDirectoryListing->GetCount()) {
		if (m_operationMode == recursive_transfer) {
			wxFileName::Mkdir(dir.localDir.GetPath(), 0777, wxPATH_MKDIR_FULL);
			m_state.RefreshLocalFile(dir.localDir.GetPath());
		}
		else if (m_operationMode == recursive_addtoqueue) {
			m_pQueue->QueueFile(true, true, _T(""), _T(""), dir.localDir, CServerPath(), *pServer, -1);
			m_pQueue->QueueFile_Finish(false);
		}
	}

	CFilterManager filter;

	// Is operation restricted to a single child?
	bool const restrict = static_cast<bool>(dir.restrict);

	std::deque<wxString> filesToDelete;

	const wxString path = pDirectoryListing->path.GetPath();

	bool added = false;

	for (int i = pDirectoryListing->GetCount() - 1; i >= 0; --i) {
		const CDirentry& entry = (*pDirectoryListing)[i];

		if (restrict) {
			if (entry.name != *dir.restrict)
				continue;
		}
		else if (filter.FilenameFiltered(m_filters, entry.name, path, entry.is_dir(), entry.size, 0, entry.time))
			continue;

		if (!entry.is_dir()) {
			++m_processedFiles;
		}

		if (entry.is_dir() && (!entry.is_link() || m_operationMode != recursive_delete)) {
			if (dir.recurse) {
				recursion_root::new_dir dirToVisit;
				dirToVisit.parent = pDirectoryListing->path;
				dirToVisit.subdir = entry.name;
				dirToVisit.localDir = dir.localDir;
				dirToVisit.start_dir = dir.start_dir;

				if (m_operationMode == recursive_transfer || m_operationMode == recursive_addtoqueue) {
					// Non-flatten case
					dirToVisit.localDir.AddSegment(CQueueView::ReplaceInvalidCharacters(entry.name));
				}
				if (entry.is_link()) {
					dirToVisit.link = 1;
					dirToVisit.recurse = false;
				}
				root.m_dirsToVisit.push_front(dirToVisit);
			}
		}
		else {
			switch (m_operationMode)
			{
			case recursive_transfer:
			case recursive_transfer_flatten:
				{
					wxString localFile = CQueueView::ReplaceInvalidCharacters(entry.name);
					if (pDirectoryListing->path.GetType() == VMS && COptions::Get()->GetOptionVal(OPTION_STRIP_VMS_REVISION))
						localFile = StripVMSRevision(localFile);
					m_pQueue->QueueFile(m_operationMode == recursive_addtoqueue, true,
						entry.name, (entry.name == localFile) ? wxString() : localFile,
						dir.localDir, pDirectoryListing->path, *pServer, entry.size);
					added = true;
				}
				break;
			case recursive_addtoqueue:
			case recursive_addtoqueue_flatten:
				{
					wxString localFile = CQueueView::ReplaceInvalidCharacters(entry.name);
					if (pDirectoryListing->path.GetType() == VMS && COptions::Get()->GetOptionVal(OPTION_STRIP_VMS_REVISION))
						localFile = StripVMSRevision(localFile);
					m_pQueue->QueueFile(true, true,
						entry.name, (entry.name == localFile) ? wxString() : localFile,
						dir.localDir, pDirectoryListing->path, *pServer, entry.size);
					added = true;
				}
				break;
			case recursive_delete:
				filesToDelete.push_back(entry.name);
				break;
			default:
				break;
			}
		}

		if (m_operationMode == recursive_chmod && m_pChmodDlg) {
			const int applyType = m_pChmodDlg->GetApplyType();
			if (!applyType ||
				(!entry.is_dir() && applyType == 1) ||
				(entry.is_dir() && applyType == 2))
			{
				char permissions[9];
				bool res = m_pChmodDlg->ConvertPermissions(*entry.permissions, permissions);
				wxString newPerms = m_pChmodDlg->GetPermissions(res ? permissions : 0, entry.is_dir());
				m_state.m_pCommandQueue->ProcessCommand(new CChmodCommand(pDirectoryListing->path, entry.name, newPerms), CCommandQueue::recursiveOperation);
			}
		}
	}
	if (added)
		m_pQueue->QueueFile_Finish(m_operationMode != recursive_addtoqueue && m_operationMode != recursive_addtoqueue_flatten);

	if (m_operationMode == recursive_delete && !filesToDelete.empty())
		m_state.m_pCommandQueue->ProcessCommand(new CDeleteCommand(pDirectoryListing->path, std::move(filesToDelete)), CCommandQueue::recursiveOperation);

	m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS);

	NextOperation();
}
Exemple #17
0
CFolderItem::CFolderItem(CServerItem* parent, bool queued, const CLocalPath& localPath)
	: CFileItem(parent, queued, true, wxEmptyString, wxEmptyString, localPath, CServerPath(), -1)
{
}
Exemple #18
0
CFolderItem::CFolderItem(CServerItem* parent, bool queued, const wxString& localFile)
	: CFileItem(parent, queued, true, localFile, _T(""), CServerPath(), -1)
{
}
void CRemoteRecursiveOperation::ProcessDirectoryListing(const CDirectoryListing* pDirectoryListing)
{
	if (!pDirectoryListing) {
		StopRecursiveOperation();
		return;
	}

	if (m_operationMode == recursive_none || recursion_roots_.empty())
		return;

	if (pDirectoryListing->failed()) {
		// Ignore this.
		// It will get handled by the failed command in ListingFailed
		return;
	}

	auto & root = recursion_roots_.front();
	wxASSERT(!root.m_dirsToVisit.empty());

	if (!m_state.IsRemoteConnected() || root.m_dirsToVisit.empty()) {
		StopRecursiveOperation();
		return;
	}

	recursion_root::new_dir dir = root.m_dirsToVisit.front();
	root.m_dirsToVisit.pop_front();

	if (!BelowRecursionRoot(pDirectoryListing->path, dir)) {
		NextOperation();
		return;
	}

	if (m_operationMode == recursive_delete && dir.doVisit && !dir.subdir.empty()) {
		// After recursing into directory to delete its contents, delete directory itself
		// Gets handled in NextOperation
		recursion_root::new_dir dir2 = dir;
		dir2.doVisit = false;
		root.m_dirsToVisit.push_front(dir2);
	}

	if (dir.link && !dir.recurse) {
		NextOperation();
		return;
	}

	// Check if we have already visited the directory
	if (!root.m_visitedDirs.insert(pDirectoryListing->path).second) {
		NextOperation();
		return;
	}

	++m_processedDirectories;

	const CServer* pServer = m_state.GetServer();
	wxASSERT(pServer);

	if (!pDirectoryListing->GetCount() && m_operationMode == recursive_transfer) {
		if (m_immediate) {
			wxFileName::Mkdir(dir.localDir.GetPath(), 0777, wxPATH_MKDIR_FULL);
			m_state.RefreshLocalFile(dir.localDir.GetPath());
		}
		else {
			m_pQueue->QueueFile(true, true, _T(""), _T(""), dir.localDir, CServerPath(), *pServer, -1);
			m_pQueue->QueueFile_Finish(false);
		}
	}

	CFilterManager filter;

	// Is operation restricted to a single child?
	bool const restrict = static_cast<bool>(dir.restrict);

	std::deque<std::wstring> filesToDelete;

	std::wstring const remotePath = pDirectoryListing->path.GetPath();

	if (m_operationMode == recursive_synchronize_download && !dir.localDir.empty()) {
		// Step one in synchronization: Delete local files not on the server
		fz::local_filesys fs;
		if (fs.begin_find_files(fz::to_native(dir.localDir.GetPath()))) {
			std::list<fz::native_string> paths_to_delete;

			bool isLink{};
			fz::native_string name;
			bool isDir{};
			int64_t size{};
			fz::datetime time;
			int attributes{};
			while (fs.get_next_file(name, isLink, isDir, &size, &time, &attributes)) {
				if (isLink) {
					continue;
				}
				auto const wname = fz::to_wstring(name);
				if (filter.FilenameFiltered(m_filters.first, wname, dir.localDir.GetPath(), isDir, size, attributes, time)) {
					continue;
				}

				// Local item isn't filtered

				int remoteIndex = pDirectoryListing->FindFile_CmpCase(fz::to_wstring(name));
				if (remoteIndex != -1) {
					CDirentry const& entry = (*pDirectoryListing)[remoteIndex];
					if (!filter.FilenameFiltered(m_filters.second, entry.name, remotePath, entry.is_dir(), entry.size, 0, entry.time)) {
						// Both local and remote items exist

						if (isDir == entry.is_dir() || entry.is_link()) {
							// Normal item, nothing we should do
							continue;
						}
					}
				}

				// Local item should be deleted if reaching this point
				paths_to_delete.push_back(fz::to_native(dir.localDir.GetPath()) + name);
			}

			fz::recursive_remove r;
			r.remove(paths_to_delete);
		}
	}

	bool added = false;

	for (int i = pDirectoryListing->GetCount() - 1; i >= 0; --i) {
		const CDirentry& entry = (*pDirectoryListing)[i];

		if (restrict) {
			if (entry.name != *dir.restrict)
				continue;
		}
		else if (filter.FilenameFiltered(m_filters.second, entry.name, remotePath, entry.is_dir(), entry.size, 0, entry.time))
			continue;

		if (!entry.is_dir()) {
			++m_processedFiles;
		}

		if (entry.is_dir() && (!entry.is_link() || m_operationMode != recursive_delete)) {
			if (dir.recurse) {
				recursion_root::new_dir dirToVisit;
				dirToVisit.parent = pDirectoryListing->path;
				dirToVisit.subdir = entry.name;
				dirToVisit.localDir = dir.localDir;
				dirToVisit.start_dir = dir.start_dir;

				if (m_operationMode == recursive_transfer || m_operationMode == recursive_synchronize_download) {
					// Non-flatten case
					dirToVisit.localDir.AddSegment(CQueueView::ReplaceInvalidCharacters(entry.name));
				}
				if (entry.is_link()) {
					dirToVisit.link = 1;
					dirToVisit.recurse = false;
				}
				root.m_dirsToVisit.push_front(dirToVisit);
			}
		}
		else {
			switch (m_operationMode)
			{
			case recursive_transfer:
			case recursive_transfer_flatten:
			case recursive_synchronize_download:
				{
					std::wstring localFile = CQueueView::ReplaceInvalidCharacters(entry.name);
					if (pDirectoryListing->path.GetType() == VMS && COptions::Get()->GetOptionVal(OPTION_STRIP_VMS_REVISION)) {
						localFile = StripVMSRevision(localFile);
					}
					m_pQueue->QueueFile(!m_immediate, true,
						entry.name, (entry.name == localFile) ? std::wstring() : localFile,
						dir.localDir, pDirectoryListing->path, *pServer, entry.size);
					added = true;
				}
				break;
			case recursive_delete:
				filesToDelete.push_back(entry.name);
				break;
			default:
				break;
			}
		}

		if (m_operationMode == recursive_chmod && m_pChmodDlg) {
			const int applyType = m_pChmodDlg->GetApplyType();
			if (!applyType ||
				(!entry.is_dir() && applyType == 1) ||
				(entry.is_dir() && applyType == 2))
			{
				char permissions[9];
				bool res = m_pChmodDlg->ConvertPermissions(*entry.permissions, permissions);
				std::wstring newPerms = m_pChmodDlg->GetPermissions(res ? permissions : 0, entry.is_dir()).ToStdWstring();
				m_state.m_pCommandQueue->ProcessCommand(new CChmodCommand(pDirectoryListing->path, entry.name, newPerms), CCommandQueue::recursiveOperation);
			}
		}
	}
	if (added) {
		m_pQueue->QueueFile_Finish(m_immediate);
	}

	if (m_operationMode == recursive_delete && !filesToDelete.empty()) {
		m_state.m_pCommandQueue->ProcessCommand(new CDeleteCommand(pDirectoryListing->path, std::move(filesToDelete)), CCommandQueue::recursiveOperation);
	}

	m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS);

	NextOperation();
}
Exemple #20
0
CServerPath CServerPath::GetCommonParent(const CServerPath& path) const
{
	if (*this == path)
		return *this;

	if (m_bEmpty || path.m_bEmpty)
		return CServerPath();

	if (m_type != path.m_type ||
		(!traits[m_type].prefixmode && m_data->m_prefix != path.m_data->m_prefix))
	{
		return CServerPath();
	}

	if (!HasParent())
	{
		if (path.IsSubdirOf(*this, false))
			return *this;
		else
			return CServerPath();
	}
	else if (!path.HasParent())
	{
		if (IsSubdirOf(path, false))
			return path;
		else
			return CServerPath();
	}

	CServerPath parent;
	parent.m_bEmpty = false;
	parent.m_type = m_type;

	CServerPathData& parentData = parent.m_data.Get();
	
	std::list<wxString>::const_iterator last = m_data->m_segments.end();
	std::list<wxString>::const_iterator last2 = path.m_data->m_segments.end();
	if (traits[m_type].prefixmode == 1)
	{
		if (m_data->m_prefix.empty())
			last--;
		if (path.m_data->m_prefix.empty())
			last2--;
		parentData.m_prefix = GetParent().m_data->m_prefix;
	}
	else
		parentData.m_prefix = m_data->m_prefix;

	std::list<wxString>::const_iterator iter = m_data->m_segments.begin();
	std::list<wxString>::const_iterator iter2 = path.m_data->m_segments.begin();
	while (iter != last && iter2 != last2)
	{
		if (*iter != *iter2)
		{
			if (!traits[m_type].has_root && parentData.m_segments.empty())
				return CServerPath();
			else
				return parent;
		}

		parentData.m_segments.push_back(*iter);

		iter++;
		iter2++;
	}

	return parent;
}
CServerPath CServerPath::GetCommonParent(const CServerPath& path) const
{
	if (*this == path) {
		return *this;
	}

	if (empty() || path.empty()) {
		return CServerPath();
	}

	if (m_type != path.m_type ||
		(!traits[m_type].prefixmode && m_data->m_prefix != path.m_data->m_prefix))
	{
		return CServerPath();
	}

	if (!HasParent()) {
		if (path.IsSubdirOf(*this, false)) {
			return *this;
		}
		else {
			return CServerPath();
		}
	}
	else if (!path.HasParent()) {
		if (IsSubdirOf(path, false)) {
			return path;
		}
		else {
			return CServerPath();
		}
	}

	CServerPath parent;
	parent.m_type = m_type;

	CServerPathData& parentData = parent.m_data.get();

	tConstSegmentIter last = m_data->m_segments.end();
	tConstSegmentIter last2 = path.m_data->m_segments.end();
	if (traits[m_type].prefixmode == 1) {
		if (!m_data->m_prefix) {
			--last;
		}
		if (!path.m_data->m_prefix) {
			--last2;
		}
		parentData.m_prefix = GetParent().m_data->m_prefix;
	}
	else
		parentData.m_prefix = m_data->m_prefix;

	tConstSegmentIter iter = m_data->m_segments.begin();
	tConstSegmentIter iter2 = path.m_data->m_segments.begin();
	while (iter != last && iter2 != last2) {
		if (*iter != *iter2) {
			if (!traits[m_type].has_root && parentData.m_segments.empty()) {
				return CServerPath();
			}
			else {
				return parent;
			}
		}

		parentData.m_segments.push_back(*iter);

		++iter;
		++iter2;
	}

	return parent;
}
void CRecursiveOperation::ProcessDirectoryListing(const CDirectoryListing* pDirectoryListing)
{
	if (!pDirectoryListing)
	{
		StopRecursiveOperation();
		return;
	}

	if (m_operationMode == recursive_none)
		return;

	wxASSERT(!m_dirsToVisit.empty());

	if (!m_pState->IsRemoteConnected() || m_dirsToVisit.empty())
	{
		StopRecursiveOperation();
		return;
	}

	CNewDir dir = m_dirsToVisit.front();
	m_dirsToVisit.pop_front();

	if (!pDirectoryListing->path.IsSubdirOf(m_startDir, false))
	{
		// In some cases (chmod from tree for example) it is neccessary to list the
		// parent first
		if (pDirectoryListing->path != m_startDir || !m_allowParent)
		{
			NextOperation();
			return;
		}
	}

	if (m_operationMode == recursive_delete && dir.doVisit && dir.subdir != _T(""))
	{
		// After recursing into directory to delete its contents, delete directory itself
		// Gets handled in NextOperation
		CNewDir dir2 = dir;
		dir2.doVisit = false;
		m_dirsToVisit.push_front(dir2);
	}

	// Check if we have already visited the directory
	for (std::list<CServerPath>::const_iterator iter = m_visitedDirs.begin(); iter != m_visitedDirs.end(); iter++)
	{
		if (*iter == pDirectoryListing->path)
		{
			NextOperation();
			return;
		}
	}
	m_visitedDirs.push_back(pDirectoryListing->path);

	const CServer* pServer = m_pState->GetServer();
	wxASSERT(pServer);

	if (!pDirectoryListing->GetCount())
	{
		wxFileName fn(dir.localDir, _T(""));
		if (m_operationMode == recursive_download)
		{
			wxFileName::Mkdir(fn.GetPath(), 0777, wxPATH_MKDIR_FULL);
			m_pState->RefreshLocalFile(fn.GetFullPath());
		}
		else if (m_operationMode == recursive_addtoqueue)
			m_pQueue->QueueFile(true, true, fn.GetFullPath(), _T(""), CServerPath(), *pServer, -1);
	}

	CFilterDialog filter;

	// Is operation restricted to a single child?
	bool restrict = !dir.restrict.IsEmpty();

	for (int i = pDirectoryListing->GetCount() - 1; i >= 0; i--)
	{
		const CDirentry& entry = (*pDirectoryListing)[i];

		if (restrict)
		{
			if (entry.name != dir.restrict)
				continue;
		}
		else if (filter.FilenameFiltered(entry.name, entry.dir, entry.size, false))
			continue;

		if (entry.dir && !entry.link)
		{
			if (dir.recurse)
			{
				CNewDir dirToVisit;
				wxFileName fn(dir.localDir, _T(""));
				fn.AppendDir(entry.name);
				dirToVisit.parent = pDirectoryListing->path;
				dirToVisit.subdir = entry.name;
				dirToVisit.localDir = fn.GetFullPath();
				dirToVisit.doVisit = true;
				m_dirsToVisit.push_front(dirToVisit);
			}
		}
		else
		{
			switch (m_operationMode)
			{
			case recursive_addtoqueue:
			case recursive_download:
				{
					wxFileName fn(dir.localDir, entry.name);
					m_pQueue->QueueFile(m_operationMode == recursive_addtoqueue, true, fn.GetFullPath(), entry.name, pDirectoryListing->path, *pServer, entry.size);
				}
				break;
			case recursive_delete:
				m_pState->m_pCommandQueue->ProcessCommand(new CDeleteCommand(pDirectoryListing->path, entry.name));
				break;
			default:
				break;
			}
		}

		if (m_operationMode == recursive_chmod && m_pChmodDlg)
		{
			const int applyType = m_pChmodDlg->GetApplyType();
			if (!applyType ||
				(!entry.dir && applyType == 1) ||
				(entry.dir && applyType == 2))
			{
				char permissions[9];
				bool res = m_pChmodDlg->ConvertPermissions(entry.permissions, permissions);
				wxString newPerms = m_pChmodDlg->GetPermissions(res ? permissions : 0);
				m_pState->m_pCommandQueue->ProcessCommand(new CChmodCommand(pDirectoryListing->path, entry.name, newPerms));
			}
		}
	}

	NextOperation();
}
Exemple #23
0
bool CServer::ParseUrl(wxString host, unsigned int port, wxString user, wxString pass, wxString &error, CServerPath &path)
{
	m_type = DEFAULT;

	if (host == _T(""))
	{
		error = _("No host given, please enter a host.");
		return false;
	}

	int pos = host.Find(_T("://"));
	if (pos != -1)
	{
		wxString protocol = host.Left(pos).Lower();
		host = host.Mid(pos + 3);
		if (protocol.Left(3) == _T("fz_"))
			protocol = protocol.Mid(3);
		m_protocol = GetProtocolFromPrefix(protocol.Lower());
		if (m_protocol == UNKNOWN)
		{
			// TODO: http:// once WebDAV is officially supported
			error = _("Invalid protocol specified. Valid protocols are:\nftp:// for normal FTP,\nsftp:// for SSH file transfer protocol,\nftps:// for FTP over SSL (implicit) and\nftpes:// for FTP over SSL (explicit).");
			return false;
		}
	}

	pos = host.Find('@');
	if (pos != -1)
	{
		// Check if it's something like
		//   user@name:password@host:port/path
		// => If there are multiple at signs, username/port ends at last at before
		// the first slash. (Since host and port never contain any at sign)

		int slash = host.Mid(pos + 1).Find('/');
		if (slash != -1)
			slash += pos + 1;

		int next_at = host.Mid(pos + 1).Find('@');
		while (next_at != -1)
		{
			next_at += pos + 1;
			if (slash != -1 && next_at > slash)
				break;

			pos = next_at;
			next_at = host.Mid(pos + 1).Find('@');
		}

		user = host.Left(pos);
		host = host.Mid(pos + 1);

		// Extract password (if any) from username
		pos = user.Find(':');
		if (pos != -1)
		{
			pass = user.Mid(pos + 1);
			user = user.Left(pos);
		}

		// Remove leading and trailing whitespace
		user.Trim(true);
		user.Trim(false);

		if (user == _T(""))
		{
			error = _("Invalid username given.");
			return false;
		}
	}
	else
	{
		// Remove leading and trailing whitespace
		user.Trim(true);
		user.Trim(false);

		if (user == _T(""))
		{
			user = _T("anonymous");
			pass = _T("*****@*****.**");
		}
	}

	pos = host.Find('/');
	if (pos != -1)
	{
		path = CServerPath(host.Mid(pos));
		host = host.Left(pos);
	}

	pos = host.Find(':');
	if (pos != -1)
	{
		if (!pos)
		{
			error = _("No host given, please enter a host.");
			return false;
		}

		long tmp;
		if (!host.Mid(pos + 1).ToLong(&tmp) || tmp < 1 || tmp > 65535)
		{
			error = _("Invalid port given. The port has to be a value from 1 to 65535.");
			return false;
		}
		port = tmp;

		host = host.Left(pos);
	}
	else
	{
		if (!port)
			port = GetDefaultPort(m_protocol);
		else if (port > 65535)
		{
			error = _("Invalid port given. The port has to be a value from 1 to 65535.");
			return false;
		}
	}

	host.Trim(true);
	host.Trim(false);

	if (host == _T(""))
	{
		error = _("No host given, please enter a host.");
		return false;
	}

	m_host = host;
	m_port = port;
	m_user = user;
	m_pass = pass;
	m_account = _T("");
	if (m_user == _T("") || m_user == _T("anonymous"))
		m_logonType = ANONYMOUS;
	else
		m_logonType = NORMAL;

	if (m_protocol == UNKNOWN)
		m_protocol = GetProtocolFromPort(port);

	return true;
}
Exemple #24
0
CFolderItem::CFolderItem(CServerItem* parent, bool queued, CLocalPath const& localPath)
    : CFileItem(parent, queued, true, std::wstring(), std::wstring(), localPath, CServerPath(), -1)
{
}