📄 ftpcontrolsocket.cpp
字号:
}
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 + -