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