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 + -
显示快捷键?