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

📄 sftpcontrolsocket.cpp

📁 一个FTP下载的源代码。代码质量非常高
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					if (path2.HasParent())
					{
						CString name=path2.GetLastSegment();
						path2=path2.GetParent();
						CDirectoryCache cache;
						cache.Lock();
						BOOL bCached=FALSE;
						t_directory dir;
						BOOL res=cache.Lookup(path2,m_CurrentServer,dir);
						if (!res)
							bCached=FALSE;
						if (!res && m_pDirectoryListing)
						{
							if (m_pDirectoryListing->path==path2)
							{
								dir=*m_pDirectoryListing;
								res=TRUE;
							}
						}
						t_directory WorkingDir;
						BOOL bFound=m_pOwner->GetWorkingDir(&WorkingDir);
						if (!res && bFound)
							if (WorkingDir.path==path2)
							{
								dir=WorkingDir;
								res=TRUE;
							}
						if (!res)
						{
							dir.path==path2;
							dir.server=m_CurrentServer;
						}
							
						int i;
						for (i=0; i<dir.num; i++)
							if (dir.direntry[i].name==name)
							{
								LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Dir already exists in cache!"));
									break;
							}
						if (i == dir.num)
						{
							t_directory::t_direntry *entries = new t_directory::t_direntry[dir.num+1];
							for (i=0; i<dir.num; i++)
								entries[i] = dir.direntry[i];
							entries[i].name=name;
							entries[i].lName=name;
							entries[i].lName.MakeLower();
							entries[i].dir=TRUE;
							entries[i].date.hasdate=FALSE;
							entries[i].size=-1;
							delete [] dir.direntry;
							dir.direntry=entries;
							dir.num++;
							cache.Store(dir, bCached);
							BOOL updated=FALSE;
							if (m_pDirectoryListing && m_pDirectoryListing->path==dir.path)
							{
								updated=TRUE;
								SetDirectoryListing(&dir);
							}
							if (!updated)
								if (WorkingDir.path==dir.path)
								{
									updated=TRUE;
									m_pOwner->SetWorkingDir(&dir);
								}
						}
						cache.Unlock();
					}
				}

				//Continue operation even if MKD failed, maybe another thread did create this directory for us
				if (pData->MKDSegments.empty())
					m_Operation.nOpState=FILETRANSFER_CWD2;
				else
				{
					if (m_pDataChannel->Send(SFTP_DATAID_STC_CD, pData->MKDCurrent.GetPath()))
						pData->nMKDOpState=MKD_MAKESUBDIRS;
					else
					{
						DoClose();
						return;
					}
				}		
				break;
			default: 
				ASSERT(FALSE);
			}
			
			break;
		case FILETRANSFER_CWD2:
			if (m_bError)
				nReplyError=FZ_REPLY_ERROR | FZ_REPLY_CRITICALERROR;
			else
			{
				CServerPath path;
				path.SetServer(m_CurrentServer);
				if (!path.SetPath(m_Reply))
				{
					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path"));
					nReplyError=FZ_REPLY_ERROR;
				}
				else
				{
					pData->rawpwd=m_Reply;
					m_pOwner->SetCurrentPath(path);
					if (path!=pData->transferfile.remotepath)
						nReplyError=FZ_REPLY_ERROR | FZ_REPLY_CRITICALERROR;
					else
					{
						CDirectoryCache cache;
						t_server server;
						m_pOwner->GetCurrentServer(server);
						t_directory dir;
						BOOL res=cache.Lookup(pData->transferfile.remotepath, server,dir);
						if (res)
						{
							CString remotefile=pData->transferfile.remotefile;
							int i;
							for (i=0; i<dir.num; i++)
							{
								if (dir.direntry[i].name==remotefile &&
									( dir.direntry[i].bUnsure || dir.direntry[i].size==-1 ))
								{
										m_Operation.nOpState=FILETRANSFER_LIST;
										break;
								}
							}
							if (i == dir.num)
							{
								SetDirectoryListing(&dir);
								m_Operation.nOpState=FILETRANSFER_RETRSTOR;
								nReplyError=CheckOverwriteFile();
								if (!nReplyError)
								{
									if (pData->transferfile.get)
									{
										CString path=pData->transferfile.localfile;
										if (path.ReverseFind('\\')!=-1)
										{
											path=path.Left(path.ReverseFind('\\')+1);
											CString path2;
											while (path!="")
											{
												path2+=path.Left(path.Find( _T("\\") )+1);
												path=path.Mid(path.Find( _T("\\") )+1);
												int res=CreateDirectory(path2,0);
											}
										}
									}
								}
							}
						}
						else
							m_Operation.nOpState=FILETRANSFER_LIST;
					}
				}
			}
			break;
		case FILETRANSFER_LIST:
			if (m_bError)
			{
				m_Operation.nOpState = FILETRANSFER_RETRSTOR;
				nReplyError = CheckOverwriteFile();
				if (!nReplyError)
				{
					if (pData->transferfile.get)
					{
						CString path = pData->transferfile.localfile;
						if (path.ReverseFind('\\')!=-1)
						{
							path=path.Left(path.ReverseFind('\\')+1);
							CString path2;
							while (path!="")
							{
								path2+=path.Left(path.Find( _T("\\") )+1);
								path=path.Mid(path.Find( _T("\\") )+1);
								int res=CreateDirectory(path2,0);
							}
						}
					}
				}
			}
			else
			{
				if (m_Reply != "")
				{
					char *data=new char[m_Reply.GetLength()+2+1];
					strcpy(data, T2CA(m_Reply+"\r\n"));
					pData->pParser->AddData(data, m_Reply.GetLength()+2);
					return;
				}
				else
				{
					int num = 0;
					delete pData->pDirectoryListing;
					pData->pDirectoryListing = new t_directory;
					if (COptions::GetOptionVal(OPTION_DEBUGSHOWLISTING))
						pData->pParser->SendToMessageLog(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID);
					pData->pDirectoryListing->direntry=pData->pParser->getList(num, pData->ListStartTime);
					pData->pDirectoryListing->num=num;
					if (pData->pParser->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;
							ResetOperation(FZ_REPLY_ERROR);
							return;
						}
					}
					else
						pData->pDirectoryListing->path=pData->transferfile.remotepath;
					ShowStatus(IDS_STATUSMSG_DIRLISTSUCCESSFUL,0);
					CDirectoryCache cache;
					t_directory dir;
					cache.Lock();
					if (cache.Lookup(pData->pDirectoryListing->path, pData->pDirectoryListing->server, dir, TRUE))
					{
						pData->pDirectoryListing->Merge(dir, pData->ListStartTime);
					}
					cache.Store(*pData->pDirectoryListing);
					cache.Unlock();
					SetDirectoryListing(pData->pDirectoryListing);
				}
				m_Operation.nOpState = FILETRANSFER_RETRSTOR;
				nReplyError = CheckOverwriteFile();
				if (!nReplyError)
				{
					if (pData->transferfile.get)
					{
						CString path = pData->transferfile.localfile;
						if (path.ReverseFind('\\')!=-1)
						{
							path=path.Left(path.ReverseFind('\\')+1);
							CString path2;
							while (path!="")
							{
								path2+=path.Left(path.Find( _T("\\") )+1);
								path=path.Mid(path.Find( _T("\\") )+1);
								int res=CreateDirectory(path2,0);
							}
						}
					}
				}
			}
			break;
		case FILETRANSFER_WAIT:
			if (!pData->nWaitNextOpState)
				nReplyError=FZ_REPLY_ERROR;
			else
				m_Operation.nOpState=pData->nWaitNextOpState;
			break;
		case FILETRANSFER_RETRSTOR:
			if (m_bError)
				nReplyError=FZ_REPLY_ERROR;
			else
			{
				if (COptions::GetOptionVal(OPTION_PRESERVEDOWNLOADFILETIME))
				{
					if (pData->pFileTime)
					{
						SYSTEMTIME stime;
						FILETIME ftime;
						HANDLE hFile=CreateFile(pData->transferfile.localfile, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
						if (hFile!=INVALID_HANDLE_VALUE)
						{
							if (pData->pFileTime->GetAsSystemTime(stime))
								if (SystemTimeToFileTime(&stime, &ftime))
									SetFileTime(hFile, &ftime, &ftime, &ftime);
							CloseHandle(hFile);
						}
					}
				}
				//Transfer successful
				ResetOperation(FZ_REPLY_OK);
			}
			break;
		}
		if (nReplyError)
		{ //Error transferring the file	
			ResetOperation(nReplyError);
			return;
		}
	}
	/////////////////
	//Send commands//
	/////////////////
	BOOL bError=FALSE;
	switch(m_Operation.nOpState)
	{
	case FILETRANSFER_CWD:
		if (!m_pDataChannel->Send(SFTP_DATAID_STC_CD, pData->transferfile.remotepath.GetPath()))
			bError=TRUE;
		break;
	case FILETRANSFER_MKD:
		if (pData->nMKDOpState==MKD_INIT)
		{
			if (!m_pDataChannel->Send(SFTP_DATAID_STC_CD, pData->transferfile.remotepath.GetParent().GetPath()))
				bError=TRUE;
			else
			{
				pData->MKDCurrent=pData->transferfile.remotepath.GetParent();
				pData->MKDSegments.push_front(pData->transferfile.remotepath.GetLastSegment());
				pData->nMKDOpState=MKD_FINDPARENT;
			}
		}
		break;
	case FILETRANSFER_CWD2:
		if (!m_pDataChannel->Send(SFTP_DATAID_STC_CD, pData->transferfile.remotepath.GetPath()))
			bError=TRUE;
		break;
	case FILETRANSFER_LIST:
		if (!m_pDataChannel->Send(SFTP_DATAID_STC_LIST, 0))
			bError=TRUE;
		else
			pData->ListStartTime=CTime::GetCurrentTime();
		break;
	case FILETRANSFER_RETRSTOR:
		if (m_pDirectoryListing)
			for (int i=0;i<m_pDirectoryListing->num;i++)
			{
				CString remotefile=pData->transferfile.remotefile;
				if (m_pDirectoryListing->direntry[i].name==remotefile)
				{
					if (pData->transferfile.get)
					{
						if (m_pDirectoryListing->direntry[i].date.hasdate)
						{
							ASSERT(!pData->pFileTime);
							pData->pFileTime=new CTime(m_pDirectoryListing->direntry[i].date.year,
							m_pDirectoryListing->direntry[i].date.month,
							m_pDirectoryListing->direntry[i].date.day,
							m_pDirectoryListing->direntry[i].date.hastime?m_pDirectoryListing->direntry[i].date.hour:0,
							m_pDirectoryListing->direntry[i].date.hastime?m_pDirectoryListing->direntry[i].date.minute:0,
							0,-1);
							TIME_ZONE_INFORMATION tzInfo={0};
							BOOL res=GetTimeZoneInformation(&tzInfo);
							CTimeSpan span(0, 0, tzInfo.Bias+((res==TIME_ZONE_ID_DAYLIGHT)?tzInfo.DaylightBias:tzInfo.StandardBias), 0);
							*pData->pFileTime+=span;
						}
						pData->transferdata.transfersize=m_pDirectoryListing->direntry[i].size;
					}
					else if (pData->transferdata.bResume)
						pData->transferdata.nTransferStart=m_pDirectoryListing->direntry[i].size;
					break;
				}
			}
		if (pData->transferfile.get)
			if (pData->transferdata.bResume)
			{
				VERIFY(GetLength64(pData->transferfile.localfile, pData->transferdata.nTransferStart));
			}
			else
				pData->transferdata.nTransferStart=0;
		else
			VERIFY(GetLength64(pData->transferfile.localfile, pData->transferdata.transfersize));

		if (pData->transferdata.transfersize>=0)
			pData->transferdata.transferleft=pData->transferdata.transfersize-pData->transferdata.nTransferStart;

		CString filename;
		if (!pData->bUseAbsolutePaths)
			filename = pData->transferfile.remotefile;
		else
			filename = pData->transferfile.remotepath.GetPath() + pData->transferfile.remotefile;
		int nLen1=filename.GetLength() + 1;
		int nLen2=pData->transferfile.localfile.GetLength()+1;
		char *pCmd=new char[nLen1+nLen2+4];
		strcpy(pCmd, T2CA(filename));
		strcpy(pCmd+nLen1, T2CA(pData->transferfile.localfile));
		memcpy(pCmd+nLen1+nLen2, &pData->transferdata.bResume, 4);
		pData->pStartTime = new CTime;
		*pData->pStartTime = CTime::GetCurrentTime();
		if (pData->transferfile.get)
		{
			if (!m_pDataChannel->Send(SFTP_DATAID_STC_GET, nLen1+nLen2+4, pCmd))
				bError=TRUE;
		}
		else
			if (!m_pDataChannel->Send(SFTP_DATAID_STC_PUT, nLen1+nLen2+4, pCmd))
				bError=TRUE;


		delete [] pCmd;
		break;
	}
	if (bError)
	{ //Error transferring the file	
		DoClose();
		return;
	}
}


void CSFtpControlSocket::Delete(CString filename, const CServerPath &path)
{
	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("Delete(\"%s\", \"%s\")"),filename,path.GetPath());
	
	class CDeleteData : public CSFtpControlSocket::t_operation::COpData
	{
	public:
		CDeleteData() {}
		virtual ~CDeleteData() {}
		CString m_FileName;
		CServerPath path;
	};	
	
	if (filename!="")
	{
		ASSERT(!path.IsEmpty());
		ASSERT(m_Operation.nOpMode==CSMODE_NONE);
		ASSERT(m_Operation.nOpState==-1);
		ASSERT(!m_Operation.pData);
		m_Operation.nOpMode=CSMODE_DELETE;
		if (!m_pDataChannel->Send(SFTP_DATAID_STC_DELE, path.GetPath()+filename))
		{
			DoClose();
			return;
		}
		CDeleteData *data=new CDeleteData;
		data->m_FileName=filename;
		data->path=path;
		m_Operation.pData=data;
	}
	else
	{
		ASSERT(path.IsEmpty());
		ASSERT(m_Operation.nOpMode==CSMODE_DELETE);
		ASSERT(m_Operation.nOpState==-1);
		ASSERT(m_Operation.pData);
		if (m_bError)
		{
			ResetOperation(FZ_REPLY_ERROR);
			return;
		}
		else
		{ //Remove file from cached dirs
			CDeleteData *pData=(CDeleteData *)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_FileName)
					{
						ASSERT(!dir.direntry[i].dir || dir.direntry[i].bLink);

⌨️ 快捷键说明

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