⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpcontrolsocket.cpp

📁 一个FTP下载的源代码。代码质量非常高
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if (GetReplyCode() == 2) // we're logged on
		{
			ShowStatus(IDS_STATUSMSG_CONNECTED,0);
			m_pOwner->SetConnected(TRUE);
			ResetOperation(FZ_REPLY_OK);
			return;
		}
		else
			//GSS authentication complete but we still have to go through the standard logon procedure
			m_Operation.nOpState = CONNECT_INIT;
	}
	
	if (m_Operation.nOpState==CONNECT_INIT)
	{
		if (logontype)
		{
		
			CString str;
			str.Format(IDS_STATUSMSG_FWCONNECT,hostname);
			ShowStatus(str,0);
		}
		m_Operation.nOpState++;
	}
	else if (!bSkipReply)
	{
		m_Operation.nOpState=logonseq[logontype][m_Operation.nOpState+GetReplyCode()-1]; //get next command from array
		switch(m_Operation.nOpState)
		{
		case ER: // ER means summat has gone wrong
			DoClose();
			return;
		case LO: //LO means we are logged on
			m_pOwner->SetConnected(TRUE);
			ShowStatus(IDS_STATUSMSG_CONNECTED,0);
			ResetOperation(FZ_REPLY_OK);
			return;
		}
	}
	
	// go through appropriate logon procedure
	int i = logonseq[logontype][m_Operation.nOpState];
	if (m_pGssLayer)
	{
		if ((i == 0 || i == 6 || i == 9 || i == 10) &&
			(m_CurrentServer.user == "anonymous" || m_CurrentServer.user == ""))
		{
			//Extract user from kerberos ticket
			char str[256];
			if (m_pGssLayer->GetUserFromKrbTicket(str))
				m_CurrentServer.user = str;
			if (m_CurrentServer.user == "")
			{
				CGssNeedUserRequestData *pData = new CGssNeedUserRequestData;
				pData->nRequestID = m_pOwner->GetNextAsyncRequestID();
				pData->nOldOpState = m_Operation.nOpState;
				m_Operation.nOpState = CONNECT_GSS_NEEDUSER;
				if (!PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_ASYNCREQUEST, FZ_ASYNCREQUEST_GSS_NEEDUSER), (LPARAM)pData))
					delete pData;
				return;
			}
		}
		else if ((i == 1 || i == 11) && (m_CurrentServer.pass == "anon@" || m_CurrentServer.pass == ""))
		{
			CGssNeedPassRequestData *pData=new CGssNeedPassRequestData;
			pData->nRequestID=m_pOwner->GetNextAsyncRequestID();
			pData->nOldOpState = m_Operation.nOpState;
			m_Operation.nOpState = CONNECT_GSS_NEEDPASS;
			if (!PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_ASYNCREQUEST, FZ_ASYNCREQUEST_GSS_NEEDPASS), (LPARAM)pData))
				delete pData;
			return;
		}
	}
	switch(logonseq[logontype][m_Operation.nOpState]) 
	{
		case 0:
			temp="USER "+m_CurrentServer.user;
			break;
		case 1:
			temp="PASS "+m_CurrentServer.pass;
			break;
		case 2:
			temp="ACCT "+CCrypt::decrypt(COptions::GetOption(OPTION_FWPASS));
			break;
		case 3:
			temp="USER "+COptions::GetOption(OPTION_FWUSER);
			break;
		case 4:
			temp="PASS "+CCrypt::decrypt(COptions::GetOption(OPTION_FWPASS));
			break;
		case 5:
			temp="SITE "+hostname;
			break;
		case 6:
			temp="USER "+m_CurrentServer.user+"@"+hostname;
			break;
		case 7:
			temp="OPEN "+hostname;
			break;
		case 8:
			temp="USER "+COptions::GetOption(OPTION_FWUSER)+"@"+hostname;
			break;
		case 9:
			temp="USER "+m_CurrentServer.user+"@"+hostname+" "+COptions::GetOption(OPTION_FWUSER);
			break;
		case 10:
			temp="USER "+m_CurrentServer.user+"@"+COptions::GetOption(OPTION_FWUSER)+"@"+hostname;
			break;
		case 11:
			temp="PASS "+m_CurrentServer.pass+"@"+CCrypt::decrypt(COptions::GetOption(OPTION_FWPASS));
			break;
	}
	// send command, get response
	if(!Send(temp))
		return;
}

#define BUFFERSIZE 4096
void CFtpControlSocket::OnReceive(int nErrorCode) 
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("OnReceive(%d)  OpMode=%d OpState=%d"), nErrorCode, m_Operation.nOpMode, m_Operation.nOpState);

	m_LastRecvTime=CTime::GetCurrentTime();
	PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_SOCKETSTATUS, FZ_SOCKETSTATUS_RECV), 0);

	if (!m_pOwner->IsConnected())
	{
		if (!m_Operation.nOpMode)
		{
			LogMessage(__FILE__, __LINE__, this,FZ_LOG_INFO, _T("Socket has been closed, don't process receive") );
			return;
		}
		m_MultiLine=_T("");
		CString str;
		str.Format(IDS_STATUSMSG_CONNECTEDWITH,m_ServerName);
		ShowStatus(str,0);
		m_pOwner->SetConnected(TRUE);
	}
	char *buffer=new char[BUFFERSIZE];
	AsyncSelect(FD_CLOSE);
	int numread=Receive(buffer, BUFFERSIZE);
	while (numread!=SOCKET_ERROR && numread)
	{
		for (int i=0;i<numread;i++)
		{
			if ((buffer[i]=='\r')||(buffer[i]=='\n')||(buffer[i]==0))
			{
				if (!m_RecvBuffer.empty() && m_RecvBuffer.back()!=_T("") )
				{
					ShowStatus(m_RecvBuffer.back(), 3);
					//Check for multi-line responses
					if (m_RecvBuffer.back().GetLength()>3)
					{
						if (m_MultiLine!=_T(""))
						{
							if (m_RecvBuffer.back().Left(4)!=m_MultiLine)
	 							m_RecvBuffer.pop_back();
							else // end of multi-line found
 							{
 								m_MultiLine=_T("");
 								m_pOwner->PostThreadMessage(m_pOwner->m_nInternalMessageID,FZAPI_THREADMSG_PROCESSREPLY,0);
 							}
						}
						// start of new multi-line
						else if (m_RecvBuffer.back()[3]=='-')
						{
							// DDD<SP> is the end of a multi-line response
							m_MultiLine=m_RecvBuffer.back().Left(3)+' ';
							m_RecvBuffer.pop_back();
						}
						else
							m_pOwner->PostThreadMessage(m_pOwner->m_nInternalMessageID,FZAPI_THREADMSG_PROCESSREPLY,0);
					}
					else
						m_RecvBuffer.pop_back();
					m_RecvBuffer.push_back(_T(""));
				}
			}
			else
			{
				//The command may only be 2000 chars long. This ensures that a malicious user can't
				//send extremely large commands to fill the memory of the server
				if (m_RecvBuffer.empty())
					m_RecvBuffer.push_back(_T(""));
				if (m_RecvBuffer.back().GetLength()<2000)
					m_RecvBuffer.back()+=buffer[i];
			}
		}
		if (numread<BUFFERSIZE)
			break;
		numread=Receive(buffer,BUFFERSIZE);
		if (numread && numread!=SOCKET_ERROR)
		{
			m_LastRecvTime=CTime::GetCurrentTime();
			PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_SOCKETSTATUS, FZ_SOCKETSTATUS_RECV), 0);
		}
	}
	delete buffer;
	if (numread==SOCKET_ERROR)
		if (GetLastError()!=WSAEWOULDBLOCK)
		{
			ShowStatus(IDS_STATUSMSG_DISCONNECTED,1);
			DoClose();
			return;
		}
	AsyncSelect(FD_READ | FD_WRITE | FD_CLOSE);	
}

void CFtpControlSocket::ProcessReply()
{
	if (m_RecvBuffer.empty())
		return;
	CString reply=m_RecvBuffer.front();
	if ( reply==_T("") )
		return;
	if (m_bKeepAliveActive)
	{
		m_bKeepAliveActive=FALSE;
		m_pOwner->PostThreadMessage(m_pOwner->m_nInternalMessageID,FZAPI_THREADMSG_POSTKEEPALIVE,0);
	}
	else if (m_Operation.nOpMode&CSMODE_CONNECT)
		LogOnToServer();
	else if (m_Operation.nOpMode& (CSMODE_COMMAND|CSMODE_CHMOD) )
	{
		if (GetReplyCode()==2 || GetReplyCode()==3)
			ResetOperation(FZ_REPLY_OK);
		else
			ResetOperation(FZ_REPLY_ERROR);
	}
	else if (m_Operation.nOpMode&CSMODE_TRANSFER)
	{
		FileTransfer(0);
	}
	else if (m_Operation.nOpMode&CSMODE_LIST)
		List(FALSE);
	else if (m_Operation.nOpMode&CSMODE_DELETE)
		Delete( _T(""),CServerPath());
	else if (m_Operation.nOpMode&CSMODE_RMDIR)
		RemoveDir( _T(""),CServerPath());
	else if (m_Operation.nOpMode&CSMODE_MKDIR)
		MakeDir(CServerPath());
	else if (m_Operation.nOpMode&CSMODE_RENAME)
		Rename(_T(""), _T(""), CServerPath(), CServerPath());
	if (!m_RecvBuffer.empty())
		m_RecvBuffer.pop_front();
}

void CFtpControlSocket::OnConnect(int nErrorCode) 
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("OnConnect(%d)  OpMode=%d OpState=%d"), nErrorCode, m_Operation.nOpMode, m_Operation.nOpState);

	if (!m_Operation.nOpMode)
	{
		if (!m_pOwner->IsConnected())
			DoClose();
		return;
	}
	if (!nErrorCode)
	{
		if (!m_pOwner->IsConnected())
		{
			m_MultiLine=_T("");
			m_pOwner->SetConnected(TRUE);
			CString str;
			str.Format(m_pSslLayer ? IDS_STATUSMSG_CONNECTEDWITHSSL : IDS_STATUSMSG_CONNECTEDWITH, m_ServerName);
			ShowStatus(str,0);
		}
	}
	else
	{
		if (nErrorCode == WSAHOST_NOT_FOUND)
			ShowStatus(IDS_ERRORMSG_CANTRESOLVEHOST, 1);
		DoClose();
	}
}

BOOL CFtpControlSocket::Send(CString str)
{
	USES_CONVERSION;
	
	ShowStatus(str,2);
	str+="\r\n";
	LPCSTR lpszAsciiSend=T2CA(str);
	int res = CAsyncSocketEx::Send(lpszAsciiSend,strlen(lpszAsciiSend));
	if (!res)
	{
		if (GetLastError()!=WSAEWOULDBLOCK)
		{
			ShowStatus(IDS_ERRORMSG_CANTSENDCOMMAND,1);
			DoClose();
			return FALSE;
		}
	}
	m_LastSendTime=CTime::GetCurrentTime();
	PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_SOCKETSTATUS, FZ_SOCKETSTATUS_SEND), 0);
	return TRUE;
}

int CFtpControlSocket::GetReplyCode()
{
	if (m_RecvBuffer.empty())
		return 0;
	CString str = m_RecvBuffer.front();
	if (str == "")
		return 0;
	else
		return str[0]-'0';
}

void CFtpControlSocket::DoClose(int nError /*=0*/)
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("DoClose(%d)  OpMode=%d OpState=%d"), nError, m_Operation.nOpMode, m_Operation.nOpState);
	
	m_bCheckForTimeout=TRUE;
	m_pOwner->SetConnected(FALSE);
	m_bKeepAliveActive=FALSE;
	PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_SECURESERVER, FALSE), 0);
	if (nError & FZ_REPLY_CRITICALERROR)
		nError |= FZ_REPLY_ERROR;
	ResetOperation(FZ_REPLY_ERROR|FZ_REPLY_DISCONNECTED|nError);
	m_RecvBuffer.clear();
	m_MultiLine="";
	CControlSocket::Close();
}

void CFtpControlSocket::Disconnect()
{
	ASSERT(!m_Operation.nOpMode);
	m_Operation.nOpMode=CSMODE_DISCONNECT;
	DoClose();
	ShowStatus(IDS_STATUSMSG_DISCONNECTED,0); //Send the disconnected message to the message log		
}

void CFtpControlSocket::CheckForTimeout()
{
	if (!m_Operation.nOpMode && !m_bKeepAliveActive)
		return;
	if (!m_bCheckForTimeout)
		return;
	int delay=COptions::GetOptionVal(OPTION_TIMEOUTLENGTH);
	if (m_pTransferSocket)
	{
		int res=m_pTransferSocket->CheckForTimeout(delay);
		if (res)
			return;
	}
	CTimeSpan span=CTime::GetCurrentTime()-m_LastRecvTime;             
	if (span.GetTotalSeconds()>=delay)
	{
		ShowStatus(IDS_ERRORMSG_TIMEOUT, 1);
		DoClose();
	}
}

void CFtpControlSocket::FtpCommand(LPCTSTR pCommand)
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("FtpCommand(%s)  OpMode=%d OpState=%d"), pCommand, m_Operation.nOpMode, m_Operation.nOpState);
	m_Operation.nOpMode=CSMODE_COMMAND;
	Send(pCommand);
}

void CFtpControlSocket::Cancel(BOOL bQuit/*=FALSE*/)
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("Cancel(%s)  OpMode=%d OpState=%d"), bQuit?_T("TRUE"):_T("FALSE"), m_Operation.nOpMode, m_Operation.nOpState);
	int nOpMode=m_Operation.nOpMode;
	if (m_Operation.nOpMode&CSMODE_LIST || m_Operation.nOpMode&CSMODE_TRANSFER)
	{
		Send("ABOR");
		if (m_pTransferSocket)
		{
			m_pTransferSocket->Close();
			delete m_pTransferSocket;
			m_pTransferSocket=0;
		}
	}
	if (m_Operation.nOpMode==CSMODE_CONNECT)
		DoClose(FZ_REPLY_CANCEL);
	else if (m_Operation.nOpMode&CSMODE_TRANSFER)
		ResetOperation(FZ_REPLY_ERROR|FZ_REPLY_CANCEL|FZ_REPLY_ABORTED);
	else if (m_Operation.nOpMode!=CSMODE_NONE)
		ResetOperation(FZ_REPLY_ERROR|FZ_REPLY_CANCEL);
		
	if (nOpMode!=CSMODE_NONE && !bQuit)
		ShowStatus(IDS_ERRORMSG_INTERRUPTED,1);
}

void CFtpControlSocket::List(BOOL bFinish, int nError /*=FALSE*/, CServerPath path /*=CServerPath()*/, CString subdir /*=""*/,int nListMode/*=0*/)
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("List(%s,%d,\"%s\",\"%s\",%d)  OpMode=%d OpState=%d"), bFinish?_T("TRUE"):_T("FALSE"), nError, path.GetPath(), subdir, nListMode,
				m_Operation.nOpMode, m_Operation.nOpState);

	USES_CONVERSION;

	#define LIST_INIT	-1
	#define LIST_PWD	0
	#define LIST_CWD	1
	#define LIST_PWD2	2
	#define LIST_CWD2	3
	#define LIST_PWD3	4
	#define LIST_PORT_PASV	5
	#define LIST_TYPE	6
	#define LIST_LIST	7
	#define LIST_WAITFINISH	8

	ASSERT(!m_Operation.nOpMode || m_Operation.nOpMode&CSMODE_LIST);
	
	m_Operation.nOpMode|=CSMODE_LIST;

	if (!m_pOwner->IsConnected())
	{
		ResetOperation(FZ_REPLY_ERROR|FZ_REPLY_NOTCONNECTED);
		return;
	}

	if (bFinish || nError)
		if (m_Operation.nOpMode!=CSMODE_LIST)
			return; //Old message coming in
	
	if (nError)
	{
		delete m_pTransferSocket;
		m_pTransferSocket=0;
		if (nError&CSMODE_TRANSFERTIMEOUT)
			DoClose();
		else
			ResetOperation(FZ_REPLY_ERROR);
		return;
	}

	CListData *pData = static_cast<CListData *>(m_Operation.pData);

	if (bFinish)
	{
		if (!m_pTransferSocket || m_pTransferSocket->m_bListening)
		{
			delete m_pDirectoryListing;
			m_pDirectoryListing=0;
			delete m_pTransferSocket;
			m_pTransferSocket=0;			
			ResetOperation(FZ_REPLY_ERROR);
			return;
		}

		int num=0;
		pData->pDirectoryListing=new t_directory;
		if (COptions::GetOptionVal(OPTION_DEBUGSHOWLISTING))
			m_pTransferSocket->m_pListResult->SendToMessageLog(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID);
		pData->pDirectoryListing->direntry=m_pTransferSocket->m_pListResult->getList(num, pData->ListStartTime);
		pData->pDirectoryListing->num=num;
		if (m_pTransferSocket->m_pListResult->m_server.nServerType&FZ_SERVERTYPE_SUB_FTP_VMS && m_CurrentServer.nServerType&FZ_SERVERTYPE_FTP)
			m_CurrentServer.nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
		pData->pDirectoryListing->server = m_CurrentServer;
		pData->pDirectoryListing->path.SetServer(pData->pDirectoryListing->server);
		if (pData->rawpwd != "")
		{
			if (!pData->pDirectoryListing->path.SetPath(pData->rawpwd))
			{
				delete m_pDirectoryListing;
				m_pDirectoryListing=0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -