Пример #1
0
void CCommandQueue::Finish(COperationNotification *pNotification)
{
	if (pNotification->nReplyCode & FZ_REPLY_DISCONNECTED)
	{
		if (pNotification->commandId == cmd_none && !m_CommandList.empty())
		{
			// Pending event, has no relevance during command execution
			delete pNotification;
			return;
		}
		if (pNotification->nReplyCode & FZ_REPLY_PASSWORDFAILED)
			CLoginManager::Get().CachedPasswordFailed(*m_pState->GetServer());
	}

	if (m_exclusiveEngineLock)
	{
		m_pMainFrame->GetQueue()->ProcessNotification(pNotification);
		return;
	}

	if (m_CommandList.empty())
	{
		delete pNotification;
		return;
	}

	wxASSERT(!m_inside_commandqueue);
	m_inside_commandqueue = true;

	CCommand* pCommand = m_CommandList.front();

	if (pCommand->GetId() == cmd_list && pNotification->nReplyCode != FZ_REPLY_OK)
	{
		if (pNotification->nReplyCode & FZ_REPLY_LINKNOTDIR)
		{
			// Symbolic link does not point to a directory. Either points to file
			// or is completely invalid
			CListCommand* pListCommand = (CListCommand*)pCommand;
			wxASSERT(pListCommand->GetFlags() & LIST_FLAG_LINK);

			m_pState->LinkIsNotDir(pListCommand->GetPath(), pListCommand->GetSubDir());
		}
		else
			m_pState->ListingFailed(pNotification->nReplyCode);
		m_CommandList.pop_front();
	}
	else if (pCommand->GetId() == cmd_connect && pNotification->nReplyCode != FZ_REPLY_OK)
	{
		// Remove pending events
		m_CommandList.pop_front();
		while (!m_CommandList.empty())
		{
			CCommand* pPendingCommand = m_CommandList.front();
			if (pPendingCommand->GetId() == cmd_connect)
				break;
			m_CommandList.pop_front();
			delete pPendingCommand;
		}

		// If this was an automatic reconnect during a recursive
		// operation, stop the recursive operation
		m_pState->GetRecursiveOperationHandler()->StopRecursiveOperation();
	}
	else if (pCommand->GetId() == cmd_connect && pNotification->nReplyCode == FZ_REPLY_OK)
	{
		m_pState->SetSuccessfulConnect();
		m_CommandList.pop_front();
	}
	else
		m_CommandList.pop_front();
	
	delete pCommand;
	
	delete pNotification;

	m_inside_commandqueue = false;

	ProcessNextCommand();
}
Пример #2
0
int CFileZillaEnginePrivate::List(const CListCommand &command)
{
	if (!IsConnected())
		return FZ_REPLY_NOTCONNECTED;

	if (command.GetPath().IsEmpty() && command.GetSubDir() != _T(""))
		return FZ_REPLY_SYNTAXERROR;

	if (command.GetFlags() & LIST_FLAG_LINK && command.GetSubDir() == _T(""))
		return FZ_REPLY_SYNTAXERROR;

	bool refresh = (command.GetFlags() & LIST_FLAG_REFRESH) != 0;
	bool avoid = (command.GetFlags() & LIST_FLAG_AVOID) != 0;
	if (refresh && avoid)
		return FZ_REPLY_SYNTAXERROR;

	if (!refresh && !command.GetPath().IsEmpty())
	{
		const CServer* pServer = m_pControlSocket->GetCurrentServer();
		if (pServer)
		{
			CServerPath path(CPathCache::Lookup(*pServer, command.GetPath(), command.GetSubDir()));
			if (!path.IsEmpty())
			{
				CDirectoryListing *pListing = new CDirectoryListing;
				CDirectoryCache cache;
				bool is_outdated = false;
				bool found = cache.Lookup(*pListing, *pServer, path, true, is_outdated);
				if (found && !is_outdated)
				{
					if (pListing->m_hasUnsureEntries)
						refresh = true;
					else
					{
						if (!avoid)
						{
							m_lastListDir = pListing->path;
							m_lastListTime = wxDateTime::Now();
							CDirectoryListingNotification *pNotification = new CDirectoryListingNotification(pListing->path);
							AddNotification(pNotification);
						}
						delete pListing;
						return FZ_REPLY_OK;
					}
				}
				if (is_outdated)
					refresh = true;
				delete pListing;
			}
		}
	}
	if (IsBusy())
		return FZ_REPLY_BUSY;

	m_pCurrentCommand = command.Clone();
	return m_pControlSocket->List(command.GetPath(), command.GetSubDir(), command.GetFlags());
}
Пример #3
0
void CCommandQueue::ProcessReply(int nReplyCode, Command commandId)
{
	if (nReplyCode == FZ_REPLY_WOULDBLOCK) {
		return;
	}
	if (nReplyCode & FZ_REPLY_DISCONNECTED) {
		if (commandId == Command::none && !m_CommandList.empty()) {
			// Pending event, has no relevance during command execution
			return;
		}
		if (nReplyCode & FZ_REPLY_PASSWORDFAILED)
			CLoginManager::Get().CachedPasswordFailed(*m_state.GetServer());
	}

	if (m_CommandList.empty()) {
		return;
	}

	if (commandId != Command::connect &&
		commandId != Command::disconnect &&
		(nReplyCode & FZ_REPLY_CANCELED) != FZ_REPLY_CANCELED)
	{
		bool reconnect = false;
		if (nReplyCode == FZ_REPLY_NOTCONNECTED) {
			reconnect = true;
		}
		else if (nReplyCode & FZ_REPLY_DISCONNECTED) {
			auto & info = m_CommandList.front();
			if (!info.didReconnect) {
				info.didReconnect = true;
				reconnect = true;
			}
		}

		if (reconnect) {
			// Try automatic reconnect
			const CServer* pServer = m_state.GetServer();
			if (pServer) {
				m_CommandList.emplace_front(normal, std::make_unique<CConnectCommand>(*pServer));
				ProcessNextCommand();
				return;
			}
		}
	}

	++m_inside_commandqueue;

	auto const& commandInfo = m_CommandList.front();

	if (commandInfo.command->GetId() == Command::list && nReplyCode != FZ_REPLY_OK) {
		if (nReplyCode & FZ_REPLY_LINKNOTDIR) {
			// Symbolic link does not point to a directory. Either points to file
			// or is completely invalid
			CListCommand* pListCommand = static_cast<CListCommand*>(commandInfo.command.get());
			wxASSERT(pListCommand->GetFlags() & LIST_FLAG_LINK);

			m_state.LinkIsNotDir(pListCommand->GetPath(), pListCommand->GetSubDir());
		}
		else {
			if (commandInfo.origin == recursiveOperation) {
				// Let the recursive operation handler know if a LIST command failed,
				// so that it may issue the next command in recursive operations.
				m_state.GetRemoteRecursiveOperation()->ListingFailed(nReplyCode);
			}
			else {
				m_state.ListingFailed(nReplyCode);
			}
		}
		m_CommandList.pop_front();
	}
	else if (nReplyCode == FZ_REPLY_ALREADYCONNECTED && commandInfo.command->GetId() == Command::connect) {
		m_CommandList.emplace_front(normal, std::make_unique<CDisconnectCommand>());
	}
	else if (commandInfo.command->GetId() == Command::connect && nReplyCode != FZ_REPLY_OK) {
		// Remove pending events
		auto it = ++m_CommandList.begin();
		while (it != m_CommandList.end() && it->command->GetId() != Command::connect) {
			++it;
		}
		m_CommandList.erase(m_CommandList.begin(), it);

		// If this was an automatic reconnect during a recursive
		// operation, stop the recursive operation
		m_state.GetRemoteRecursiveOperation()->StopRecursiveOperation();
	}
	else if (commandInfo.command->GetId() == Command::connect && nReplyCode == FZ_REPLY_OK) {
		m_state.SetSuccessfulConnect();
		m_CommandList.pop_front();
	}
	else
		m_CommandList.pop_front();

	--m_inside_commandqueue;

	ProcessNextCommand();
}