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

📄 ftpcontrolsocket.cpp

📁 一个FTP下载的源代码。代码质量非常高
💻 CPP
📖 第 1 页 / 共 5 页
字号:
								}
							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;
								entries[i].bUnsure=FALSE;
								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 (Send( _T("CWD ") + pData->MKDCurrent.GetPath()))
							pData->nMKDOpState=MKD_MAKESUBDIRS;
						else
							return;
					}		
				}
				break;
			default: 
				ASSERT(FALSE);
			}
			
			break;
		case FILETRANSFER_CWD2:
			if (GetReplyCode()!=2 && GetReplyCode()!=3)
				if (GetReplyCode()==4)
					nReplyError=FZ_REPLY_ERROR;
				else
					nReplyError=FZ_REPLY_CRITICALERROR;
			else
				m_Operation.nOpState=FILETRANSFER_PWD;
			break;
		case FILETRANSFER_PWD:
			if (GetReplyCode()!=2 && GetReplyCode()!=2)
				nReplyError=FZ_REPLY_ERROR;
			else
			{
				int pos1=m_RecvBuffer.front().Find('"');
				int pos2=m_RecvBuffer.front().ReverseFind('"');
				if (pos1==-1 || (pos1+1)>=pos2)
					nReplyError=FZ_REPLY_ERROR;
				else
				{
					CServerPath path;
					path.SetServer(m_CurrentServer);
					if (!path.SetPath(m_RecvBuffer.front().Mid(pos1+1,pos2-pos1-1)))
						nReplyError=FZ_REPLY_ERROR;
					else
					{
						pData->rawpwd=m_RecvBuffer.front().Mid(pos1+1,pos2-pos1-1);
						m_pOwner->SetCurrentPath(path);
						if (path!=pData->transferfile.remotepath)
							nReplyError=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_PORTPASV;
										break;
									}
								}
								if (i==dir.num)
								{
									SetDirectoryListing(&dir);
									m_Operation.nOpState=FILETRANSFER_TYPE;
									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_PORTPASV;
						}
					}
				}
			}
			break;
		case FILETRANSFER_LIST_PORTPASV:
			if (GetReplyCode()!=3 && GetReplyCode()!=2)
			{
				if (!pData->bTriedPortPasvOnce)
				{
					pData->bTriedPortPasvOnce = TRUE;
					pData->bPasv = !pData->bPasv;
				}
				else
					nReplyError=FZ_REPLY_ERROR;
				break;
			}
			
			if (pData->bPasv)
			{
				int i=m_RecvBuffer.front().Find( _T("(") );
				int j=j=m_RecvBuffer.front().Find( _T(")") );
				// extract connect port number and IP from string returned by server
				if(i==-1 || j==-1 || (i+11)>=j)
				{
					if (!pData->bTriedPortPasvOnce)
					{
						pData->bTriedPortPasvOnce = TRUE;
						pData->bPasv = !pData->bPasv;
					}
					else
						nReplyError = FZ_REPLY_ERROR;
					break;
				}
					
				CString temp;
				temp=m_RecvBuffer.front().Mid(i+1,(j-i)-1);
				int count=0;
				int pos=0;
				//Convert commas to dots
				temp.Replace( _T(","), _T(".") );
				while(1)
				{
					pos=temp.Find(_T("."),pos);
					if (pos!=-1)
						count++;
					else
						break;
					pos++;
				}
				if (count!=5)
				{
					if (!pData->bTriedPortPasvOnce)
					{
						pData->bTriedPortPasvOnce = TRUE;
						pData->bPasv = !pData->bPasv;
					}
					else
						nReplyError = FZ_REPLY_ERROR;
					break;
				}
					
				i=temp.ReverseFind('.');
				pData->port=atol(  T2CA( temp.Right(temp.GetLength()-(i+1)) )  ); //get ls byte of server socket
				temp=temp.Left(i);
				i=temp.ReverseFind('.');
				pData->port+=256*atol(  T2CA( temp.Right(temp.GetLength()-(i+1)) )  ); // add ms byte to server socket
				pData->host=temp.Left(i);
				m_pTransferSocket = new CTransferSocket(this, CSMODE_LIST);
				if (m_pGssLayer && m_pGssLayer->AuthSuccessful())
					m_pTransferSocket->UseGSS(m_pGssLayer);
				m_pTransferSocket->m_nInternalMessageID = m_pOwner->m_nInternalMessageID;
				if (!m_pTransferSocket->Create(m_pSslLayer?TRUE:FALSE))
				{
					nReplyError = FZ_REPLY_ERROR;
					break;
				}
				
				VERIFY(m_pTransferSocket->AsyncSelect());
			}
			m_Operation.nOpState=FILETRANSFER_LIST_TYPE;
			break;
		case FILETRANSFER_LIST_TYPE:
			if (GetReplyCode()!=2 && GetReplyCode()!=3)
				nReplyError=FZ_REPLY_ERROR;
			else
				m_Operation.nOpState=FILETRANSFER_LIST_LIST;
			break;
		case FILETRANSFER_LIST_LIST:
			if (GetReplyCode()==4 || GetReplyCode()==5) //LIST failed, try getting file information using SIZE and MDTM
			{
				if (m_pTransferSocket)
					delete m_pTransferSocket;
				m_pTransferSocket=0;
				m_Operation.nOpState=FILETRANSFER_NOLIST_SIZE;
			}
			else if (GetReplyCode()!=1)
				nReplyError=FZ_REPLY_ERROR;
			else
				m_Operation.nOpState=FILETRANSFER_LIST_WAITFINISH;
			break;
		case FILETRANSFER_LIST_WAITFINISH:
			if (!bFinish)
			{
				if (GetReplyCode()!=2 && GetReplyCode()!=3)
					nReplyError=FZ_REPLY_ERROR;
				else
					pData->nGotTransferEndReply=1;
			}
			if (pData->nGotTransferEndReply && pData->pDirectoryListing)
			{
				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);
				delete m_pTransferSocket;
				m_pTransferSocket=0;
				m_Operation.nOpState=FILETRANSFER_TYPE;
				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);
							}
						}
					}
				}
				pData->nGotTransferEndReply=0;
			}
			break;
		case FILETRANSFER_NOLIST_SIZE:
			if (GetReplyCode()==2)
			{
				CString line=m_RecvBuffer.front();
				if ( line.GetLength()>4  &&  line.Left(4) == _T("213 ") )
				{
					__int64 size=_ttoi64(line.Mid(4));
					ASSERT(!pData->pFileSize);
					pData->pFileSize=new _int64;
					*pData->pFileSize=size;
				}
			}
			m_Operation.nOpState=FILETRANSFER_NOLIST_MDTM;
			break;
		case FILETRANSFER_NOLIST_MDTM:
			if (GetReplyCode()==2)
			{
				CString line=m_RecvBuffer.front();
				if ( line.GetLength()>4  &&  line.Left(4) == _T("213 ") )
				{
					int y=0, M=0, d=0, h=0, m=0;
					line=line.Mid(4);
					y=_ttoi(line.Left(4));
					if (y && line.GetLength()>4)
					{
						line=line.Mid(4);
						M=_ttoi(line.Left(2));
						if (M && line.GetLength()>2)
						{
							line=line.Mid(2);
							d=_ttoi(line.Left(2));
							if (d && line.GetLength()>2)
							{
								line=line.Mid(2);
								h=_ttoi(line.Left(2));
								if (h && line.GetLength()>2)
								{
									line=line.Mid(2);
									m=_ttoi(line.Left(2));
									if (m && line.GetLength()>2)
									{
										line=line.Mid(2);
									}
								}
							}
							if (M>0 && M<=12 && d>0 && d<=31 && h>=0 && h<24 && m>=0 && m<60)
							{
								ASSERT(!pData->pFileTime);
								pData->pFileTime=new CTime(y, M, d, h, m, 0);
							}
						}
					}
				}
			}
			m_Operation.nOpState=FILETRANSFER_TYPE;
			nReplyError=CheckOverwriteFile();
			break;
		case FILETRANSFER_TYPE:
			if (GetReplyCode()!=2 && GetReplyCode()!=3)
				nReplyError = FZ_REPLY_ERROR;
			m_Operation.nOpState = FILETRANSFER_PORTPASV;
			break;
		case FILETRANSFER_WAIT:
			if (!pData->nWaitNextOpState)
				nReplyError=FZ_REPLY_ERROR;
			else
				m_Operation.nOpState=pData->nWaitNextOpState;
			break;
		case FILETRANSFER_PORTPASV:
			if (GetReplyCode()==3 || GetReplyCode()==2)
			{
				if (pData->bPasv)
				{
					int i=m_RecvBuffer.front().Find( _T("(") );
					int j=j=m_RecvBuffer.front().Find( _T(")") );
					// extract connect port number and IP from string returned by server
					if(i==-1 || j==-1 || (i+11)>=j)
					{
						if (!pData->bTriedPortPasvOnce)
						{
							pData->bTriedPortPasvOnce = TRUE;
							pData->bPasv = !pData->bPasv;
						}
						else
							nReplyError = FZ_REPLY_ERROR;
						break;
					}

					CString temp;
					temp=m_RecvBuffer.front().Mid(i+1,(j-i)-1);
					int count=0;
					int pos=0;
					//Convert commas to dots
					temp.Replace( _T(","), _T(".") );
					while(1)
					{
						pos=temp.Find( _T("."), pos);
						if (pos!=-1)
							count++;
						else
							break;
						pos++;
					}
					if (count!=5)
					{
						if (!pData->bTriedPortPasvOnce)
						{
							pData->bTriedPortPasvOnce = TRUE;
							pData->bPasv = !pData->bPasv;
						}
						else
							nReplyError = FZ_REPLY_ERROR;
						break;
					}

					i=temp.ReverseFind('.');
					pData->port=atol(  T2CA( temp.Right(temp.GetLength()-(i+1)) )  ); //get ls byte of server socket
					temp=temp.Left(i);
					i=temp.ReverseFind('.');
					pData->port+=256*atol(  T2CA( temp.Right(temp.GetLength()-(i+1)) )  ); // add ms byte to server socket
					pData->host=temp.Left(i);
					m_pTransferSocket=new CTransferSocket(this, m_Operation.nOpMode);
					if (m_pGssLayer && m_pGssLayer->AuthSuccessful())
						m_pTransferSocket->UseGSS(m_pGssLayer);
					m_pTransferSocket->m_nInternalMessageID = m_pOwner->m_nInternalMessageID;
					if (!m_pTransferSocket->Create(m_pSslLayer?TRUE:FALSE))
					{
						nReplyError = FZ_REPLY_ERROR;
						break;
					}

					VERIFY(m_pTransferSocket->AsyncSelect());					
				}

				if (pData->transferdata.bResume && pData->transferfile.get)
					m_Operation.nOpState = FILETRANSFER_REST;
				else
					m_Operation.nOpState = FILETRANSFER_RETRSTOR;
				BOOL res = FALSE;
				if (!m_pDataFile)
					m_pDataFile = new CFile;
				if (pData->transferfile.get)
				{
					if (pData->transferdata.bResume)
						res = m_pDataFile->Open(pData->transferfile.localfile,CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate|CFile::shareDenyWrite);
					else
						res = m_pDataFile->Open(pData->transferfile.localfile,CFile::modeWrite|CFile::modeCreate|CFile::shareDenyWrite);
				}
				else
					res = m_pDataFile->Open(pData->transferfile.localfile,CFile::modeRead|CFile::shareDenyWrite);
				if (!res)
				{
					//Error opening the file
					CString str;
					str.Format(IDS_ERRORMSG_FILEOPENFAILED,pData->transferfile.localfile);
					ShowStatus(str,1);
					nReplyError = FZ_REPLY_ERROR;
					break;
				}

				if (!m_pTransferSocket)
				{
					nReplyError=FZ_REPLY_ERROR;
					break;
				}
				
				m_pTransferSocket->m_pFile=m_pDataFile;
				if (!pData->transferfile.get)
				{
					pData->transferdata.transfersize=GetLength64(*m_pDataFile);
					pData->transferdata.transferleft=pData->transferdata.transfersize;
					if (pData->transferdata.bResume)
					{
						CString remotefile=pData->transferfile.remotefile;
						if (m_pDirectoryListing)
							for (int i=0;i<m_pDirectoryListing->num;i++)
							{
								if (m_pDirectoryListing->direntry[i].name==remotefile)
								{
									pData->transferdata.transferleft-=m_pDirectoryListing->

⌨️ 快捷键说明

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