controlsocket.cpp
来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 551 行 · 第 1/2 页
CPP
551 行
// FileZilla - a Windows ftp client
// Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// ControlSocket.cpp: Implementierung der Klasse CControlSocket.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ControlSocket.h"
#include "mainthread.h"
#include "AsyncProxySocketLayer.h"
#include "AsyncSslSocketLayer.h"
#include "AsyncGssSocketLayer.h"
#include "SpeedLimit.h"
#include <idna.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
std::list<CControlSocket::t_ActiveList> CControlSocket::m_DownloadInstanceList;
std::list<CControlSocket::t_ActiveList> CControlSocket::m_UploadInstanceList;
CTime CControlSocket::m_CurrentDownloadTime = CTime::GetCurrentTime();;
_int64 CControlSocket::m_CurrentDownloadLimit = 0;
CTime CControlSocket::m_CurrentUploadTime = CTime::GetCurrentTime();;
_int64 CControlSocket::m_CurrentUploadLimit = 0;
CCriticalSection CControlSocket::m_SpeedLimitSync;
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
CControlSocket::CControlSocket(CMainThread *pMainThread)
{
ASSERT(pMainThread);
m_pOwner=pMainThread;
m_Operation.nOpMode=0;
m_Operation.nOpState=-1;
m_Operation.pData=0;
m_pProxyLayer = NULL;
m_pSslLayer = NULL;
m_pGssLayer = NULL;
m_pDirectoryListing=0;
m_pIdentControl=0;
}
CControlSocket::~CControlSocket()
{
LogMessage(__FILE__, __LINE__, this, FZ_LOG_DEBUG, _T("~CControlSocket()"));
Close();
}
/////////////////////////////////////////////////////////////////////////////
// Member-Funktion CControlSocket
#define CONNECT_INIT -1
#define CONNECT_GSS -3
#define CONNECT_SSL_INIT -6
#define CONNECT_SSL_NEGOTIATE -5
#define CONNECT_SSL_WAITDONE -4
void CControlSocket::ShowStatus(UINT nID, int type) const
{
CString str;
str.LoadString(nID);
ShowStatus(str, type);
}
void CControlSocket::ShowStatus(CString status, int type) const
{
if ( status.Left(5)==_T("PASS ") )
{
int len=status.GetLength()-5;
status=_T("PASS ");
for (int i=0;i<len;i++)
status+="*";
}
else if ( status.Left(5)==_T("ACCT ") )
{
int len=status.GetLength()-5;
status=_T("ACCT ");
for (int i=0;i<len;i++)
status+="*";
}
status.Replace(_T("%"), _T("%%"));
LogMessage(type, (LPCTSTR)status);
}
t_server CControlSocket::GetCurrentServer()
{
return m_CurrentServer;
}
void CControlSocket::Close()
{
if(m_pIdentControl)
delete m_pIdentControl;
m_pIdentControl=0;
if (m_pDirectoryListing)
{
delete m_pDirectoryListing;
}
m_pDirectoryListing=0;
CAsyncSocketEx::Close();
delete m_pProxyLayer;
m_pProxyLayer = NULL;
delete m_pSslLayer;
m_pSslLayer = NULL;
delete m_pGssLayer;
m_pGssLayer = NULL;
}
BOOL CControlSocket::Connect(CString hostAddress, UINT nHostPort)
{
hostAddress = ConvertDomainName(hostAddress);
//Don't resolve host asynchronously when using proxies
if (m_pProxyLayer)
{
//If using proxies, we can't use ident -> won't be reachable from outside
return CAsyncSocketEx::Connect(hostAddress, nHostPort);
}
BOOL res = CAsyncSocketEx::Connect(hostAddress, nHostPort);
int nLastError = WSAGetLastError();
if (res || nLastError==WSAEWOULDBLOCK)
{
if (COptions::GetOptionVal(OPTION_IDENT))
m_pIdentControl = new CIdentServerControl(this);
WSASetLastError(nLastError);
}
return res;
}
void CControlSocket::SetDirectoryListing(t_directory *pDirectory, bool bSetWorkingDir /*=true*/)
{
if (m_pDirectoryListing)
delete m_pDirectoryListing;
m_CurrentServer=pDirectory->server;
m_pDirectoryListing=new t_directory;
*m_pDirectoryListing=*pDirectory;
if (bSetWorkingDir)
m_pOwner->SetWorkingDir(pDirectory);
}
int CControlSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
{
USES_CONVERSION;
for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
{
if (iter->nType == LAYERCALLBACK_STATECHANGE)
{
if (iter->pLayer == m_pProxyLayer)
LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("m_pProxyLayer changed state from %d to %d"), iter->nParam2, iter->nParam1);
else if (iter->pLayer == m_pGssLayer)
LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("m_pGssLayer changed state from %d to %d"), iter->nParam2, iter->nParam1);
else
LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("Layer @ %d changed state from %d to %d"), iter->pLayer, iter->nParam2, iter->nParam1);
}
else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC)
{
if (iter->pLayer == m_pProxyLayer)
{
switch (iter->nParam1)
{
case PROXYERROR_NOCONN:
ShowStatus(IDS_ERRORMSG_PROXY_NOCONN, 1);
break;
case PROXYERROR_REQUESTFAILED:
ShowStatus(IDS_ERRORMSG_PROXY_REQUESTFAILED, 1);
if (iter->str)
ShowStatus(A2T(iter->str), 1);
break;
case PROXYERROR_AUTHTYPEUNKNOWN:
ShowStatus(IDS_ERRORMSG_PROXY_AUTHTYPEUNKNOWN, 1);
break;
case PROXYERROR_AUTHFAILED:
ShowStatus(IDS_ERRORMSG_PROXY_AUTHFAILED, 1);
break;
case PROXYERROR_AUTHNOLOGON:
ShowStatus(IDS_ERRORMSG_PROXY_AUTHNOLOGON, 1);
break;
case PROXYERROR_CANTRESOLVEHOST:
ShowStatus(IDS_ERRORMSG_PROXY_CANTRESOLVEHOST, 1);
break;
default:
LogMessage(__FILE__, __LINE__, this, FZ_LOG_WARNING, _T("Unknown proxy error") );
}
}
else if (iter->pLayer == m_pGssLayer)
{
switch (iter->nParam1)
{
case GSS_INFO:
LogMessage(FZ_LOG_INFO, A2CT(iter->str));
break;
case GSS_ERROR:
LogMessage(FZ_LOG_APIERROR, A2CT(iter->str));
break;
case GSS_COMMAND:
ShowStatus(A2CT(iter->str), 2);
break;
case GSS_REPLY:
ShowStatus(A2CT(iter->str), 3);
break;
}
}
}
delete [] iter->str;
}
return 1;
}
_int64 CControlSocket::GetSpeedLimit(CTime &time, int valType, int valValue, SPEEDLIMITSLIST &list)
{
int type = COptions::GetOptionVal(valType);
if ( type == 1)
return ( _int64)COptions::GetOptionVal(valValue) * 1024;
if ( type == 2)
{
CSingleLock lock(&COptions::m_Sync, TRUE);
for ( unsigned int i = 0; i < list.size(); i++)
{
if ( list[ i]->IsItActive(time) && list[i]->m_Speed)
return list[ i]->m_Speed * 1024;
}
}
return ( _int64)1000000000000; //I hope that when there will be something with 1000GB/s then I'll change it :)
}
_int64 CControlSocket::GetDownloadSpeedLimit( CTime &time)
{
return GetSpeedLimit( time, OPTION_SPEEDLIMIT_DOWNLOAD_TYPE, OPTION_SPEEDLIMIT_DOWNLOAD_VALUE, COptions::m_DownloadSpeedLimits);
}
_int64 CControlSocket::GetUploadSpeedLimit( CTime &time)
{
return GetSpeedLimit( time, OPTION_SPEEDLIMIT_UPLOAD_TYPE, OPTION_SPEEDLIMIT_UPLOAD_VALUE, COptions::m_UploadSpeedLimits);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?