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