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

📄 sftpcontrolsocket.cpp

📁 一个FTP下载的源代码。代码质量非常高
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		m_Operation.nOpMode=CSMODE_RMDIR;
		if (!m_pDataChannel->Send(SFTP_DATAID_STC_RMD, path.GetPath()+dirname))
		{
			DoClose();
			return;
		}
		CRemoveDirData *data=new CRemoveDirData;
		data->m_DirName=dirname;
		data->path=path;
		m_Operation.pData=data;
	}
	else
	{
		ASSERT(path.IsEmpty());
		ASSERT(m_Operation.nOpMode==CSMODE_RMDIR);
		ASSERT(m_Operation.nOpState==-1);
		ASSERT(m_Operation.pData);
		if (!m_bError)
		{ //Remove dir from cached dirs
			CRemoveDirData *pData=(CRemoveDirData *)m_Operation.pData;
			CDirectoryCache cache;
			cache.Lock();
			BOOL bCached=TRUE;
			t_directory dir;
			BOOL res=cache.Lookup(pData->path,m_CurrentServer,dir);
			if (!res)
				bCached=FALSE;
			if (!res && m_pDirectoryListing)
			{
				if (m_pDirectoryListing->path==pData->path)
				{
					dir=*m_pDirectoryListing;
					res=TRUE;
				}
			}
			t_directory WorkingDir;
			BOOL bFound=m_pOwner->GetWorkingDir(&WorkingDir);
			if (!res && bFound)
				if (WorkingDir.path==pData->path)
				{
					dir=WorkingDir;
					res=TRUE;
				}
			if (res)
			{
				BOOL found=FALSE;
				for (int i=0;i<dir.num;i++)
				{
					if (dir.direntry[i].name==pData->m_DirName)
					{
						ASSERT(dir.direntry[i].dir);
						found=TRUE;
						break;
					}
				}
				if (found)
				{
					t_directory::t_direntry *direntry=new t_directory::t_direntry[dir.num-1];
					int j=0;
					for (int i=0;i<dir.num;i++)
					{
						if (dir.direntry[i].name==pData->m_DirName)
							continue;
						direntry[j]=dir.direntry[i];
						j++;
					}
					delete [] dir.direntry;
					dir.direntry=direntry;
					dir.num--;
					cache.Store(dir, bCached);
					BOOL updated=FALSE;
					if (m_pDirectoryListing)
						if (m_pDirectoryListing->path==dir.path)
						{
							updated=TRUE;
							SetDirectoryListing(&dir);
						}
					if (!updated)
						if (WorkingDir.path==dir.path)
						{
							updated=TRUE;
							m_pOwner->SetWorkingDir(&dir);
						}
				}
			}
			if (cache.Lookup(pData->path,pData->m_DirName,m_CurrentServer,dir))
				cache.Purge(dir.path,dir.server);
			cache.Unlock();
			ResetOperation(FZ_REPLY_OK);
		}
		else
			ResetOperation(FZ_REPLY_ERROR);
	}
}

void CSFtpControlSocket::ProcessReply()
{
	if (m_Operation.nOpMode&CSMODE_TRANSFER)
		FileTransfer(0);
	else if (m_Operation.nOpMode&CSMODE_LIST)
		List(FALSE, m_bError);
	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());
	else if (m_Operation.nOpMode&CSMODE_CHMOD)
		ResetOperation(m_bError?FZ_REPLY_ERROR:FZ_REPLY_OK);
	else if (m_Operation.nOpMode&CSMODE_CONNECT)
		if (m_bError)
			DoClose();
}

void CSFtpControlSocket::TransferEnd(int nMode)
{
}

void CSFtpControlSocket::Cancel(BOOL bQuit /*=FALSE*/)
{
	if (bQuit)
		m_bQuit=TRUE;
	if (m_Operation.nOpMode!=CSMODE_NONE)
		DoClose(FZ_REPLY_CANCEL);
}

int CSFtpControlSocket::OnClientRequest(int nId, int &nDataLength, LPVOID pData)
{
	USES_CONVERSION;
	ASSERT(pData);
	ASSERT(nId);
	ASSERT(nDataLength>=0 && nDataLength<=20480);
	int i;
	switch(nId)
	{
	case SFTP_DATAID_CTS_TRACE:
		for (i=0;i<nDataLength;i++)
		{
			if (!reinterpret_cast<char *>(pData)[i])
			{
				char *str = (char *)pData;
				char *p = str;
				while (p=strstr(str, "\n"))
				{
					*p = 0;
					ShowStatus(str, 3);
					str = p+1;
				}
				LogMessage(FZ_LOG_INFO, _T("FzSFtp.exe: %s"), A2CT(str));
				break;
			}
		}
		break;
	case SFTP_DATAID_CTS_READ:
		{
			if (nDataLength!=4)
				ResetOperation(FZ_REPLY_ERROR);
			else
			{
				int len=*(int *)pData;
				if (len<0 || len>20476)
				{
					ShowStatus("SFTP_DATAID_CTS_READ called with invalid data", 1);
					DoClose();
					return 0;
				}
			
				LPVOID pBuffer = m_pDataChannel->GetBuffer();
				if (!pBuffer)
				{
					DoClose();
					return 0;
				}
				
				bool beenWaiting = FALSE;
				if (m_Operation.nOpMode & CSMODE_DOWNLOAD || m_Operation.nOpMode & CSMODE_UPLOAD)
					len = static_cast<int>(GetAbleToDownloadSize(beenWaiting, len));

				int res = Receive((int *)pBuffer+1, len);
				if (res==SOCKET_ERROR)
				{
					int error = WSAGetLastError();
					if (error==WSAEWOULDBLOCK)
						AsyncSelect(FD_READ | FD_WRITE | FD_CLOSE);
					res = 4;
					*(int *)pBuffer=0;
					*((int *)pBuffer+1)=error;
				}
				else
				{
					if (m_Operation.nOpMode & CSMODE_DOWNLOAD || m_Operation.nOpMode & CSMODE_UPLOAD)
						SpeedLimitAddDownloadedBytes(res);
					*(int *)pBuffer=res;
					m_LastRecvTime=CTime::GetCurrentTime();
					if (res!=0)
						PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_SOCKETSTATUS, FZ_SOCKETSTATUS_RECV), 0);
				}
				
				res+=4;
				if (!m_pDataChannel->ReleaseBuffer(SFTP_DATAID_STC_READ, res))
				{
					DoClose();
					return 0;
				}
			}
		}
		break;
	case SFTP_DATAID_CTS_WRITE:
		{
			int len=nDataLength;
			bool beenWaiting = FALSE;
			if (m_Operation.nOpMode & CSMODE_DOWNLOAD || m_Operation.nOpMode & CSMODE_UPLOAD)
				len = static_cast<int>(GetAbleToUploadSize(beenWaiting, len));

			int res=Send(pData, len);
			int error=0;
			if (res==SOCKET_ERROR)
			{
				res=0;
				error=WSAGetLastError();
			}
			else
			{
				if (m_Operation.nOpMode & CSMODE_DOWNLOAD || m_Operation.nOpMode & CSMODE_UPLOAD)
					SpeedLimitAddUploadedBytes(res);
				m_LastSendTime=CTime::GetCurrentTime();
				if (res!=0)
					PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_SOCKETSTATUS, FZ_SOCKETSTATUS_SEND), 0);
			}
			*((int *)pData)=res;
			*((int *)pData+1)=error;
			if (!m_pDataChannel->Send(SFTP_DATAID_STC_WRITE, 8, pData))
			{
				DoClose();
				return 0;
			}
		}
		break;
	case SFTP_DATAID_CTS_CONNECTED:
		m_pOwner->SetConnected(TRUE);
		PostMessage(m_pOwner->m_hOwnerWnd,m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_SECURESERVER, TRUE), 0);
		ShowStatus(IDS_STATUSMSG_CONNECTED,0);
		ResetOperation(FZ_REPLY_OK);
		break;
	case SFTP_DATAID_CTS_PWD:
	case SFTP_DATAID_CTS_CD:
		if (nDataLength<=1 || nDataLength!=static_cast<int>(strlen((char *)pData)+1))
			ResetOperation(FZ_REPLY_ERROR);
		else
		{
			m_Reply=(char *)pData;
			ProcessReply();
		}
		break;
	case SFTP_DATAID_CTS_LIST:
		if (nDataLength && nDataLength!=static_cast<int>(strlen((char *)pData)+1))
			ResetOperation(FZ_REPLY_ERROR);
		else
		{
			if (!nDataLength)
				m_Reply="";
			else
			{
				m_Reply=(char *)pData;
				ASSERT(m_Reply!="");
			}
			
			ProcessReply();
		}
		break;
	case SFTP_DATAID_CTS_ERROR:
		if (nDataLength && nDataLength==static_cast<int>(strlen((char *)pData)+1))
			ShowStatus((char *)pData, 3);
		m_bError=TRUE;
		ProcessReply();
		m_bError=FALSE;
		break;
	case SFTP_DATAID_CTS_STATUS:
		if (nDataLength && nDataLength==static_cast<int>(strlen((char *)pData)+1))
		{
			char *str = (char *)pData;
			char *p = str;
			while (p=strstr(str, "\n"))
			{
				*p = 0;
				ShowStatus(str, 3);
				str = p+1;
			}
			ShowStatus(str, 3);
		}
		break;
	case SFTP_DATAID_CTS_CRITICALERROR:
		if (nDataLength && nDataLength==static_cast<int>(strlen((char *)pData)+1))
		{
			char *str = (char *)pData;
			char *p = str;
			while (p=strstr(str, "\n"))
			{
				*p = 0;
				ShowStatus(str, 3);
				str = p+1;
			}
			ShowStatus(str, 3);
		}
		if (m_Operation.nOpMode&CSMODE_CONNECT)
			DoClose(FZ_REPLY_CRITICALERROR);
		else
			DoClose(FZ_REPLY_ERROR);
		break;
	case SFTP_DATAID_CTS_FATALERROR:
		if (nDataLength && nDataLength==static_cast<int>(strlen((char *)pData)+1))
		{
			char *str = (char *)pData;
			char *p = str;
			while (p=strstr(str, "\n"))
			{
				*p = 0;
				ShowStatus(str, 3);
				str = p+1;
			}
			ShowStatus(str, 3);
		}
		DoClose(FZ_REPLY_ERROR);
		break;
	case SFTP_DATAID_CTS_MKD:
	case SFTP_DATAID_CTS_DELE:
	case SFTP_DATAID_CTS_RMD:
	case SFTP_DATAID_CTS_RENAME:
	case SFTP_DATAID_CTS_CHMOD:
		if (nDataLength && nDataLength!=static_cast<int>(strlen((char *)pData)+1))
			ResetOperation(FZ_REPLY_ERROR);
		else
		{
			ShowStatus((char *)pData, 3);
			ProcessReply();
		}
		break;
	case SFTP_DATAID_CTS_GET:
	case SFTP_DATAID_CTS_PUT:
		ProcessReply();
		break;
	case SFTP_DATAID_CTS_TRANSFERSTATUS:
		if (nDataLength!=4)
			ResetOperation(FZ_REPLY_ERROR);
		else
			UpdateTransferstatus(*(int *)pData);
		break;
	case SFTP_DATAID_CTS_NEWHOSTKEY:
		{
			CNewHostKeyRequestData *pRequestData=new CNewHostKeyRequestData;
			pRequestData->nRequestID=m_pOwner->GetNextAsyncRequestID();
			pRequestData->Hostkey=(char *)pData;
			if (!PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_ASYNCREQUEST, FZ_ASYNCREQUEST_NEWHOSTKEY), (LPARAM)pRequestData))
			{
				delete pRequestData;
				DoClose();
			}				
		}
		break;
	case SFTP_DATAID_CTS_CHANGEDHOSTKEY:
		{
			CChangedHostKeyRequestData *pRequestData=new CChangedHostKeyRequestData;
			pRequestData->nRequestID=m_pOwner->GetNextAsyncRequestID();
			pRequestData->Hostkey=(char *)pData;
			if (!PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_ASYNCREQUEST, FZ_ASYNCREQUEST_CHANGEDHOSTKEY), (LPARAM)pRequestData))
			{
				delete pRequestData;
				DoClose();
			}				
		}
		break;
	case SFTP_DATAID_CTS_KEYBOARD_INTERACTIVE:
		{
			CKeyboardInteractiveRequestData *pRequestData = new CKeyboardInteractiveRequestData;
			pRequestData->nRequestID = m_pOwner->GetNextAsyncRequestID();
			pRequestData->nRequestType = FZ_ASYNCREQUEST_KEYBOARDINTERACTIVE;
			memcpy(pRequestData->data, pData, nDataLength);
			if (!PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_ASYNCREQUEST, FZ_ASYNCREQUEST_KEYBOARDINTERACTIVE), (LPARAM)pRequestData))
			{
				delete pRequestData;
				DoClose();
			}				
		}
		break;
	}
		
	return 0;
}

void CSFtpControlSocket::OnConnect(int nErrorCode)
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("OnConnect(%d)"), nErrorCode);
	USES_CONVERSION;
	if (!m_Operation.nOpMode)
	{
		if (!m_pOwner->IsConnected())
			DoClose();
		return;
	}
	if (!nErrorCode)
	{
		/* Set internal socket send buffer to 64k,
		 * this should fix the speed problems some users have reported
		 */
		DWORD value;
		int len = sizeof(value);
		GetSockOpt(SO_SNDBUF, &value, &len);
		if (value < 65536)
		{
			value = 65536;
			SetSockOpt(SO_SNDBUF, &value, sizeof(value));
		}
	    
		AsyncSelect(FD_WRITE | FD_CLOSE);
		if (!m_pOwner->IsConnected())
		{
			m_pOwner->SetConnected(TRUE);
			CString str;

			str.Format(IDS_STATUSMSG_CONNECTEDWITHSFTP, m_ServerName);
			ShowStatus(str,0);
			char *data=new char[m_CurrentServer.host.GetLength() + m_CurrentServer.user.GetLength() + m_CurrentServer.pass.GetLength() + 4 + 3 + 2];
			char *p=data;
			strcpy(p, T2CA(m_CurrentServer.host));
			p+=strlen(p)+1;
			*(int *)p=m_CurrentServer.port;
			p+=4;
			strcpy(p, T2CA(m_CurrentServer.user));
			p+=strlen(p)+1;
			strcpy(p, T2CA(m_CurrentServer.pass));
			p+=strlen(p)+1;
			*p++ = COptions::GetOptionVal(OPTION_SSHUSECOMPRESSION);
			*p++ = COptions::GetOptionVal(OPTION_SSHPROTOCOL);
			const BOOL bTrace=GetDebugLevel()>=3;
			if (!m_pDataChannel->Send(SFTP_DATAID_STC_TRACE, 4, (LPVOID)&bTrace))
			{
				delete [] data;
				DoClose();
				return;
			}
			if (!m_pDataChannel->Send(SFTP_DATAID_STC_CONNECT, p-data, data))
			{
				delete [] data;
				DoClose();
				return;
			}
			delete [] data;		
		}
	}
	else
	{
		if (nErrorCode == WSAHOST_NOT_FOUND)
			ShowStatus(IDS_ERRORMSG_CANTRESOLVEHOST, 1);
		DoClose();
	}
}

void CSFtpControlSocket::OnClientError(int nErrorCode)
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("OnClientError(%d)"), nErrorCode);
	switch(nErrorCode)
	{
	case 1:
		ShowStatus(IDS_ERRORMSG_SFTP_CLOSED,1);
		break;
	case 2:
		ShowStatus(IDS_ERRORMSG_SFTP_NORESPONSE,1);
		break;
	case 3:
	default:
		ShowStatus(IDS_ERRORMSG_SFTP_INVALIDDAT

⌨️ 快捷键说明

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