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() && command.GetSubDir().IsEmpty()) path = command.GetPath(); 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()); }
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(); }
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(); }