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

📄 ftpclnt.cpp

📁 Crimson编辑器的英文版,完成从韩文版变成英文版的移植,并且附带可执行文件和注册表文件,无需原先的安装包,是改写编辑器的最理想选择.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	case WSAEPROTONOSUPPORT: m_szResponseMessage = "The specified port is not supported."; break;
	case WSAEPROTOTYPE: m_szResponseMessage = "The specified port is the wrong type for this socket."; break;
	case WSAESOCKTNOSUPPORT: m_szResponseMessage = "The specified socket type is not supported in this address family."; break;
	default: m_szResponseMessage = lpszDefaultErrorMessage; break;
	}
	return TRUE;
}

BOOL CFtpClient::EstablishDataChannel(BOOL bPassive, LPCTSTR lpszCommand)
{
	CString szMessage, szString, szAddress; INT nPortNum;
	if( m_bIsDataChannelEstablished ) return FALSE; // data channel is established already

	if( ! bPassive ) { // active mode

		if( ! ListenServer(szAddress, nPortNum) ) return FALSE;

		if( ! StringFromAddress( szString, szAddress, nPortNum ) ) return FALSE;
		szMessage.Format("PORT %s\r\n", szString);
		if( ! WriteToControlChannel(szMessage) ) return FALSE;

		if( ! ReadFromControlChannel() ) return FALSE; // 200 PORT command successful.
		if( m_nResponseCode < 200 || m_nResponseCode >= 300 ) return FALSE;

		szMessage.Format("%s\r\n", lpszCommand);
		if( ! WriteToControlChannel(szMessage) ) return FALSE;

		if( ! ReadFromControlChannel() ) return FALSE; // 150 Opening ASCII mode data connection for file list.
		if( m_nResponseCode < 100 || m_nResponseCode >= 200 ) return FALSE;

		if( ! AcceptDataChannel() ) return FALSE;

	} else { // passive mode

		if( ! WriteToControlChannel("PASV\r\n") ) return FALSE;

		if( ! ReadFromControlChannel() ) return FALSE; // 227 Entering Passive Mode (xxx,xxx,xxx,xxx,xxx,xxx).
		if( m_nResponseCode < 200 || m_nResponseCode >= 300 ) return FALSE;

		INT i = m_szResponseMessage.Find('('); if( i < 0 ) return FALSE;
		INT j = m_szResponseMessage.Find(')'); if( j < 0 ) return FALSE;
		szString = m_szResponseMessage.Mid(i+1, (j-i)-1);

		szMessage.Format("%s\r\n", lpszCommand);
		if( ! WriteToControlChannel(szMessage) ) return FALSE;

		if( ! AddressFromString(szAddress, nPortNum, szString) ) return FALSE;
		if( ! ConnectDataChannel(szAddress, nPortNum) ) return FALSE;

		if( ! ReadFromControlChannel() ) return FALSE; // 150 Opening ASCII mode data connection for file list.
		if( m_nResponseCode < 100 || m_nResponseCode >= 200 ) return FALSE;

	}

	m_bIsDataChannelEstablished = TRUE;
	m_bPassiveModeDataChannel = bPassive;

	return TRUE;
}

BOOL CFtpClient::DestroyDataChannel()
{
	if( ! m_bIsDataChannelEstablished ) return FALSE; // no data chennel is established yet

	if( ! m_bPassiveModeDataChannel ) { // active mode

		if( ! CloseDataChannel() ) return FALSE;
		if( ! CloseServer() ) return FALSE;

		if( ! ReadFromControlChannel() ) return FALSE; // 226 Transfer complete
		if( m_nResponseCode < 200 || m_nResponseCode >= 300 ) return FALSE;

	} else { // passive mode

		if( ! CloseDataChannel() ) return FALSE;

		if( ! ReadFromControlChannel() ) return FALSE; // 226 Transfer complete.
		if( m_nResponseCode < 200 || m_nResponseCode >= 300 ) return FALSE;

	}

	m_bIsDataChannelEstablished = FALSE;
	m_bPassiveModeDataChannel = FALSE;

	return TRUE;
}

BOOL CFtpClient::StringFromAddress(CString & rString, LPCTSTR lpszAddress, INT nPortNum)
{
	CString szAddress = lpszAddress;

	INT i, len = szAddress.GetLength();
	for( i = 0; i < len; i++ ) if( szAddress.GetAt(i) == '.' ) szAddress.SetAt(i, ',');
	rString.Format("%s,%d,%d", szAddress, nPortNum / 256, nPortNum % 256);

	return TRUE;
}

BOOL CFtpClient::AddressFromString(CString & rAddress, INT & rPortNum, LPCTSTR lpszString)
{
	INT i; CString szString = lpszString;
	i = szString.ReverseFind(',');
	rPortNum = atoi( szString.Mid(i+1) );

	szString = szString.Left(i);
	i = szString.ReverseFind(',');
	rPortNum += 256 * atoi( szString.Mid(i+1) );

	rAddress = szString.Left(i); INT len = rAddress.GetLength();
	for( i = 0; i < len; i++ ) if( rAddress.GetAt(i) == ',' ) rAddress.SetAt(i, '.');

	return TRUE;
}

BOOL CFtpClient::WriteToControlChannel(LPCTSTR lpszString)
{
	if( ! m_pControlWriteArchive ) return FALSE;

	m_pControlWriteArchive->WriteString(lpszString);
	m_pControlWriteArchive->Flush();

	// lpszString already contains linefeed
	TRACE1("FTP-SEND: %s", lpszString);

	return TRUE;
}

BOOL CFtpClient::ReadFromControlChannel()
{
	CString szResponseMessage, szCode;
	if( ! m_pControlReadArchive ) return FALSE;

	// The client can identify the last line of the response as follows:
	// it begins with three ASCII digits and a space;
	// previous lines do not. The three digits form a code.
	if( ! m_pControlReadArchive->ReadString(szResponseMessage) ) return FALSE;
	m_szResponseMessage = szResponseMessage;
	szCode = szResponseMessage.Mid(0,3); m_nResponseCode = atoi(szCode);

	// Codes between 100 and 199 indicate marks;
	// codes between 200 and 399 indicate acceptance;
	// codes between 400 and 599 indicate rejection.
	while( szResponseMessage[3] != ' ' || szCode.Compare("100") < 0 || szCode.Compare("999") > 0 ) {
		if( ! m_pControlReadArchive->ReadString(szResponseMessage) ) return FALSE;
		m_szResponseMessage += CString("\n") + szResponseMessage;
		szCode = szResponseMessage.Mid(0,3); m_nResponseCode = atoi(szCode);
	}

	TRACE1("FTP-RECV: %s\n", m_szResponseMessage);

	return TRUE;
}

BOOL CFtpClient::ReadFromDataChannel(CString & rString)
{
	if( ! m_pDataReadArchive ) return FALSE;
	return m_pDataReadArchive->ReadString(rString);
}

UINT CFtpClient::ReadFromDataChannel(VOID * lpBuf, UINT nMax)
{
	if( ! m_pDataReadArchive ) return 0;
	return m_pDataReadArchive->Read(lpBuf, nMax);
}

BOOL CFtpClient::WriteToDataChannel(VOID * lpBuf, UINT nMax)
{
	if( ! m_pDataReadArchive ) return FALSE;
	m_pDataWriteArchive->Write(lpBuf, nMax); return TRUE;
}

BOOL CFtpClient::OpenControlChannel(LPCTSTR lpszServer, INT nPortNum)
{
	if( ! (m_pControlSocket = new CSocket) ) return FALSE;

	if( ! m_pControlSocket->Create() ) {
		SetSocketErrorMessage( m_pControlSocket->GetLastError(), "An error occured in creating socket object." );
		return FALSE;
	}
	if( ! m_pControlSocket->Connect(lpszServer, nPortNum) ) {
		SetSocketErrorMessage( m_pControlSocket->GetLastError(), "An error occured in connecting control channel." );
		return FALSE;
	}

	if( ! (m_pControlSocketFile = new CSocketFile(m_pControlSocket)) ) return FALSE;
	if( ! (m_pControlReadArchive = new CArchive(m_pControlSocketFile, CArchive::load)) ) return FALSE;
	if( ! (m_pControlWriteArchive = new CArchive(m_pControlSocketFile, CArchive::store)) ) return FALSE;

	return TRUE;
}

BOOL CFtpClient::CloseControlChannel()
{
	try {
		if( m_pControlReadArchive ) delete m_pControlReadArchive;
		m_pControlReadArchive = NULL;
		if( m_pControlWriteArchive ) delete m_pControlWriteArchive;
		m_pControlWriteArchive = NULL;
		if( m_pControlSocketFile ) delete m_pControlSocketFile;
		m_pControlSocketFile = NULL;
		if( m_pControlSocket ) delete m_pControlSocket;
		m_pControlSocket = NULL;
	} catch( CException * ex ) {
		ex->ReportError(MB_OK | MB_ICONSTOP);
		ex->Delete(); return FALSE;
	}

	return TRUE;
}

BOOL CFtpClient::ListenServer(CString & rAddress, INT & rPortNum)
{
	CString szAddress; UINT nPortNum;

	if( ! m_pControlSocket ) return FALSE;
	if( ! m_pControlSocket->GetSockName(rAddress, nPortNum) ) return FALSE;

	if( ! (m_pServerSocket = new CSocket) ) return FALSE;
	if( ! m_pServerSocket->Create() ) return FALSE;
	if( ! m_pServerSocket->Listen() ) return FALSE;

	if( ! m_pServerSocket->GetSockName(szAddress, nPortNum) ) return FALSE;
	rPortNum = (INT)nPortNum;

	return TRUE;
}

BOOL CFtpClient::CloseServer()
{
	try {
		if( m_pServerSocket ) delete m_pServerSocket;
		m_pServerSocket = NULL;
	} catch( CException * ex ) {
		ex->ReportError(MB_OK | MB_ICONSTOP);
		ex->Delete(); return FALSE;
	}

	return TRUE;
}

BOOL CFtpClient::AcceptDataChannel()
{
	if( ! m_pServerSocket || m_pDataSocket ) return FALSE;
	if( ! (m_pDataSocket = new CSocket) ) return FALSE;
	if( ! m_pServerSocket->Accept( * m_pDataSocket ) ) return FALSE;

	if( ! (m_pDataSocketFile = new CSocketFile(m_pDataSocket)) ) return FALSE;
	if( ! (m_pDataReadArchive = new CArchive(m_pDataSocketFile, CArchive::load)) ) return FALSE;
	if( ! (m_pDataWriteArchive = new CArchive(m_pDataSocketFile, CArchive::store)) ) return FALSE;

	return TRUE;
}

BOOL CFtpClient::ConnectDataChannel(LPCTSTR lpszServer, INT nPortNum)
{
	if( m_pDataSocket ) return FALSE;
	if( ! (m_pDataSocket = new CSocket) ) return FALSE;
	if( ! m_pDataSocket->Create() ) return FALSE;
	m_pDataSocket->Connect(lpszServer, nPortNum); /* WSAEWOULDBLOCK error for CAsyncSocket */

	if( ! (m_pDataSocketFile = new CSocketFile(m_pDataSocket)) ) return FALSE;
	if( ! (m_pDataReadArchive = new CArchive(m_pDataSocketFile, CArchive::load)) ) return FALSE;
	if( ! (m_pDataWriteArchive = new CArchive(m_pDataSocketFile, CArchive::store)) ) return FALSE;

	return TRUE;
}

BOOL CFtpClient::CloseDataChannel()
{
	try {
		if( m_pDataReadArchive ) delete m_pDataReadArchive;
		m_pDataReadArchive = NULL;
		if( m_pDataWriteArchive ) delete m_pDataWriteArchive;
		m_pDataWriteArchive = NULL;
		if( m_pDataSocketFile ) delete m_pDataSocketFile;
		m_pDataSocketFile = NULL;
		if( m_pDataSocket ) delete m_pDataSocket;
		m_pDataSocket = NULL;
	} catch( CException * ex ) {
		ex->ReportError(MB_OK | MB_ICONSTOP);
		ex->Delete(); return FALSE;
	}

	return TRUE;
}

⌨️ 快捷键说明

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