예제 #1
0
int CFileZillaEngine::Execute(const CCommand &command)
{
	if (command.GetId() != Command::cancel && IsBusy())
		return FZ_REPLY_BUSY;

	m_bIsInCommand = true;

	int res = FZ_REPLY_INTERNALERROR;
	switch (command.GetId())
	{
	case Command::connect:
		res = Connect(reinterpret_cast<const CConnectCommand &>(command));
		break;
	case Command::disconnect:
		res = Disconnect(reinterpret_cast<const CDisconnectCommand &>(command));
		break;
	case Command::cancel:
		res = Cancel(reinterpret_cast<const CCancelCommand &>(command));
		break;
	case Command::list:
		res = List(reinterpret_cast<const CListCommand &>(command));
		break;
	case Command::transfer:
		res = FileTransfer(reinterpret_cast<const CFileTransferCommand &>(command));
		break;
	case Command::raw:
		res = RawCommand(reinterpret_cast<const CRawCommand&>(command));
		break;
	case Command::del:
		res = Delete(reinterpret_cast<const CDeleteCommand&>(command));
		break;
	case Command::removedir:
		res = RemoveDir(reinterpret_cast<const CRemoveDirCommand&>(command));
		break;
	case Command::mkdir:
		res = Mkdir(reinterpret_cast<const CMkdirCommand&>(command));
		break;
	case Command::rename:
		res = Rename(reinterpret_cast<const CRenameCommand&>(command));
		break;
	case Command::chmod:
		res = Chmod(reinterpret_cast<const CChmodCommand&>(command));
		break;
	default:
		return FZ_REPLY_SYNTAXERROR;
	}

	if (res != FZ_REPLY_WOULDBLOCK)
		ResetOperation(res);

	m_bIsInCommand = false;

	if (command.GetId() != Command::disconnect)
		res |= m_nControlSocketError;
	else if (res & FZ_REPLY_DISCONNECTED)
		res = FZ_REPLY_OK;
	m_nControlSocketError = 0;

	return res;
}
예제 #2
0
void CCommandQueue::ProcessNextCommand()
{
	if (m_inside_commandqueue)
		return;

	if (m_exclusiveEngineLock)
		return;

	if (m_pEngine->IsBusy())
		return;

	m_inside_commandqueue = true;

	if (m_CommandList.empty()) {
		// Possible sequence of events:
		// - Engine emits listing and operation finished
		// - Connection gets terminated
		// - Interface cannot obtain listing since not connected
		// - Yet getting operation successful
		// To keep things flowing, we need to advance the recursive operation.
		m_pState->GetRecursiveOperationHandler()->NextOperation();
	}

	while (!m_CommandList.empty())
	{
		CCommand *pCommand = m_CommandList.front();

		int res = m_pEngine->Command(*pCommand);
		
		if (pCommand->GetId() != cmd_cancel &&
			pCommand->GetId() != cmd_connect &&
			pCommand->GetId() != cmd_disconnect)
		{
			if (res == FZ_REPLY_NOTCONNECTED)
			{
				// Try automatic reconnect
				const CServer* pServer = m_pState->GetServer();
				if (pServer)
				{
					CCommand *pCommand = new CConnectCommand(*pServer);
					m_CommandList.push_front(pCommand);
					continue;
				}
			}
		}

		if (res == FZ_REPLY_WOULDBLOCK)
			break;
		else if (res == FZ_REPLY_OK)
		{
			delete pCommand;
			m_CommandList.pop_front();
			continue;
		}
		else if (res == FZ_REPLY_ALREADYCONNECTED)
		{
			res = m_pEngine->Command(CDisconnectCommand());
			if (res == FZ_REPLY_WOULDBLOCK)
			{
				m_CommandList.push_front(new CDisconnectCommand);
				break;
			}
			else if (res != FZ_REPLY_OK)
			{
				wxBell();
				delete pCommand;
				m_CommandList.pop_front();
				continue;
			}
		}
		else
		{
			wxBell();
			
			if (pCommand->GetId() == cmd_list)
				m_pState->ListingFailed(res);

			m_CommandList.pop_front();
			delete pCommand;
		}
	}

	m_inside_commandqueue = false;

	if (m_CommandList.empty())
	{
		if (m_exclusiveEngineRequest)
			GrantExclusiveEngineRequest();
		else
			m_pState->NotifyHandlers(STATECHANGE_REMOTE_IDLE);

		if (!m_pState->SuccessfulConnect())
			m_pState->SetServer(0);
	}
}
예제 #3
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();
}
예제 #4
0
int CFileZillaEngine::Command(const CCommand &command)
{
    if (command.GetId() != cmd_cancel && IsBusy())
        return FZ_REPLY_BUSY;

    m_bIsInCommand = true;

    int res = FZ_REPLY_INTERNALERROR;

    printf("command id: %d\n", command.GetId());
    switch (command.GetId())
    {
    case cmd_connect:
        res = Connect(reinterpret_cast<const CConnectCommand &>(command));
        break;
    case cmd_disconnect:
        res = Disconnect(reinterpret_cast<const CDisconnectCommand &>(command));
        break;
    case cmd_cancel:
        res = Cancel(reinterpret_cast<const CCancelCommand &>(command));
        break;
    case cmd_list:
        res = List(reinterpret_cast<const CListCommand &>(command));
        break;
    case cmd_transfer:
        res = FileTransfer(reinterpret_cast<const CFileTransferCommand &>(command));
        break;
    case cmd_raw:
        res = RawCommand(reinterpret_cast<const CRawCommand&>(command));
        break;
    case cmd_delete:
        res = Delete(reinterpret_cast<const CDeleteCommand&>(command));
        break;
    case cmd_removedir:
        res = RemoveDir(reinterpret_cast<const CRemoveDirCommand&>(command));
        break;
    case cmd_mkdir:
        res = Mkdir(reinterpret_cast<const CMkdirCommand&>(command));
        break;
    case cmd_rename:
        res = Rename(reinterpret_cast<const CRenameCommand&>(command));
        break;
    case cmd_chmod:
        res = Chmod(reinterpret_cast<const CChmodCommand&>(command));
        break;
    case cmd_checksum:
        printf("recognized the checksum command\n");
        res = Checksum(reinterpret_cast<const CChecksumCommand&>(command));
        break;
    default:
        return FZ_REPLY_SYNTAXERROR;
    }

    if (res != FZ_REPLY_WOULDBLOCK)
        ResetOperation(res);

    m_bIsInCommand = false;

    if (command.GetId() != cmd_disconnect)
        res |= m_nControlSocketError;
    else if (res & FZ_REPLY_DISCONNECTED)
        res = FZ_REPLY_OK;
    m_nControlSocketError = 0;

    return res;
}