serverpath.cpp

来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 1,364 行 · 第 1/3 页

CPP
1,364
字号
// 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.

// ServerPath.cpp: Implementierung der Klasse CServerPath.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ServerPath.h"
#include "structures.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define FTP_MVS_DOUBLE_QUOTA (TCHAR)0xDC

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

CServerPath::CServerPath()
{
	m_nServerType = 0;
	m_bEmpty = TRUE;
}

CServerPath::CServerPath(int nServerType)
{
	m_nServerType = nServerType;
	m_bEmpty = TRUE;
}

CServerPath::CServerPath(CString path)
{
	m_nServerType = FZ_SERVERTYPE_FTP;
	path.TrimLeft( _T(" ") );
	path.TrimRight( _T(" ") );
	if (path == "")
	{
		m_bEmpty = TRUE;
		return;
	}
	else
		m_bEmpty = FALSE;

	int pos1 = path.Find( _T(":[") );
	if (pos1 != -1 && path.Right(1) == "]" && pos1 != (path.GetLength()-1))
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
	else if (path.GetLength() >= 3 && _istalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/'))
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_WINDOWS;
	else if (path[0] == FTP_MVS_DOUBLE_QUOTA && path[path.GetLength() - 1] == FTP_MVS_DOUBLE_QUOTA)
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS;
	else if (path.GetLength() > 2 && path[0] == '\'' && path.Right(1) == _T("'") && path.Find('/') == -1 && path.Find('\\') == -1)
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS;
	else if (path.GetLength() >= 2 && path[0] != '/' && path.Right(1) == _T("."))
		m_nServerType |= FZ_SERVERTYPE_SUB_FTP_UNKNOWN;

	*this = CServerPath(path, m_nServerType);
}

CServerPath::CServerPath(CString path, int nServerType)
{
	m_nServerType = nServerType;
	path.TrimLeft( _T(" ") );
	path.TrimRight( _T(" ") );
	if (path == "")
	{
		m_bEmpty = TRUE;
		return;
	}
	else
		m_bEmpty = FALSE;
	
	switch (m_nServerType&FZ_SERVERTYPE_HIGHMASK)
	{
	case FZ_SERVERTYPE_FTP:
		switch(m_nServerType&FZ_SERVERTYPE_SUBMASK)
		{
		case FZ_SERVERTYPE_SUB_FTP_MVS:
		case FZ_SERVERTYPE_SUB_FTP_BS2000:
			{
				path.TrimLeft(FTP_MVS_DOUBLE_QUOTA);
				path.TrimRight(FTP_MVS_DOUBLE_QUOTA);
				path.TrimLeft('\'');
				path.TrimRight('\'');
				path.TrimLeft('.');
				while (path.Replace(_T(".."), _T(".")));

				int pos = path.Find(_T("."));
				while (pos != -1)
				{
					m_Segments.push_back(path.Left(pos));
					path = path.Mid(pos + 1);
					pos = path.Find( _T(".") );
				}
				if (path != _T(""))
					m_Segments.push_back(path);
				else
					m_Prefix = _T(".");
			}
			break;
		case FZ_SERVERTYPE_SUB_FTP_VMS:
			{
				int pos1 = path.Find( _T("[") );
				if (pos1 == -1 || path.Right(1) != _T("]"))
				{
					ASSERT(FALSE);
					m_bEmpty = TRUE;
					return;
				}
				path.TrimRight( _T("]") );
				if (pos1)
					m_Prefix = path.Left(pos1);
				path = path.Mid(pos1 + 1);
				int pos = path.Find( _T(".") );
				while (pos != -1)
				{
					m_Segments.push_back(path.Left(pos));
					path = path.Mid(pos+1);
					pos = path.Find( _T(".") );
				}
				if (path != "")
					m_Segments.push_back(path);
			}
			break;
		case FZ_SERVERTYPE_SUB_FTP_UNKNOWN:
			while (path.Replace('.', '/'));
		default:
			path.Replace( _T("\\"), _T("/") );
			while (path.Replace( _T("//"), _T("/") ));
			path.TrimLeft( _T("/") );
			path.TrimRight( _T("/") );
			int pos = path.Find( _T("/") );
			while (pos != -1)
			{
				m_Segments.push_back(path.Left(pos));
				path = path.Mid(pos+1);
				pos = path.Find( _T("/") );
			}
			if (path != "")
				m_Segments.push_back(path);
			break;
		}
		break;
	case FZ_SERVERTYPE_LOCAL:
		{
			path.TrimRight( _T("\\") );
			while (path.Replace( _T("\\\\"), _T("\\") ));
			int pos = path.Find( _T("\\") );
			if (pos == -1)
			{
				m_Prefix = path;
				return;
			}
			ASSERT(pos == 2);
			m_Prefix = path.Left(pos);
			path = path.Mid(pos + 1);
			pos = path.Find( _T("\\") );
			while (pos != -1)
			{
				m_Segments.push_back(path.Left(pos));
				path=path.Mid(pos + 1);
				pos=path.Find( _T("\\") );
			}
			if (path != "")
				m_Segments.push_back(path);			
		}
		break;
	default:
		ASSERT(FALSE);
	}	
}

CServerPath::CServerPath(const CServerPath &path)
{
	m_nServerType = path.m_nServerType;
	m_Prefix = path.m_Prefix;
	m_bEmpty = path.m_bEmpty;
	m_Segments = path.m_Segments;
}

CServerPath::~CServerPath()
{

}

void CServerPath::SetServer(const t_server &server)
{
	m_nServerType=server.nServerType;
}

BOOL CServerPath::SetPath(CString &newpath, BOOL bIsFile /*=FALSE*/)
{
	CString file;
	CString path=newpath;

	path.TrimLeft( _T(" ") );
	path.TrimRight( _T(" ") );
	if (path != "")
		m_bEmpty = FALSE;
	else
		m_bEmpty = TRUE;
	if (!(m_nServerType & FZ_SERVERTYPE_HIGHMASK))
		m_nServerType = FZ_SERVERTYPE_FTP;
	if (!(m_nServerType&FZ_SERVERTYPE_SUBMASK) && (m_nServerType&FZ_SERVERTYPE_HIGHMASK)==FZ_SERVERTYPE_FTP)
	{
		int pos1 = path.Find( _T(":[") );
		if (pos1!=-1 && pos1!=(path.GetLength()-2))
		{
			if (!bIsFile && path.Right(1)==_T("]"))
				m_nServerType|=FZ_SERVERTYPE_SUB_FTP_VMS;
			else if (bIsFile && path.ReverseFind(']')>(pos1+1))
				m_nServerType|=FZ_SERVERTYPE_SUB_FTP_VMS;
		}
		if (newpath.GetLength() >= 3 && _istalpha(newpath[0]) && newpath[1] == ':' && (newpath[2] == '\\' || newpath[2] == '/'))
			m_nServerType |= FZ_SERVERTYPE_SUB_FTP_WINDOWS;
		else if (path[0] == FTP_MVS_DOUBLE_QUOTA && path[path.GetLength() - 1] == FTP_MVS_DOUBLE_QUOTA)
			m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS;
		else if (path.GetLength() >= 2 && path[0] != '/' && path.Right(1) == _T("."))
			m_nServerType |= FZ_SERVERTYPE_SUB_FTP_UNKNOWN;
	}
	m_Segments.clear();
	m_Prefix = "";
	switch (m_nServerType&FZ_SERVERTYPE_HIGHMASK)
	{
		case FZ_SERVERTYPE_FTP:
			switch (m_nServerType&FZ_SERVERTYPE_SUBMASK)
			{
			case FZ_SERVERTYPE_SUB_FTP_MVS:
			case FZ_SERVERTYPE_SUB_FTP_BS2000:
				{
					path.TrimLeft(FTP_MVS_DOUBLE_QUOTA);
					path.TrimRight(FTP_MVS_DOUBLE_QUOTA);
					path.TrimLeft('\'');
					path.TrimRight('\'');
					path.TrimLeft('.');
					while (path.Replace(_T(".."), _T(".")));

					int pos = path.Find(_T("."));
					while (pos != -1)
					{
						m_Segments.push_back(path.Left(pos));
						path = path.Mid(pos + 1);
						pos = path.Find( _T(".") );
					}
					if (path != "")
						m_Segments.push_back(path);
					else
						m_Prefix = _T(".");

					if (bIsFile)
					{
						if (m_Segments.empty())
							return FALSE;
						file = m_Segments.back();
						m_Segments.pop_back();

						if (file.Right(1) == _T("."))
							return FALSE;

						int pos = file.Find('(');
						int pos2 = file.Find(')');
						if (pos != -1)
						{
							if (!pos || pos2 != file.GetLength() - 2)
								return FALSE;
							m_Prefix = _T("");
							m_Segments.push_back(file.Left(pos));
							file = file.Mid(pos + 1, pos2 - pos - 1);
						}
						else if (pos2 != -1)
							return FALSE;
					}
				}
				break;
			case FZ_SERVERTYPE_SUB_FTP_VMS:
				{
					int pos1=path.Find( _T("[") );
					if (pos1==-1)
						return FALSE;
					if (bIsFile)
					{
						int rpos=path.ReverseFind(']');
						if (rpos==-1)
							return FALSE;
						else if (rpos!=(path.GetLength()-1) )
						{
							file=file.Mid(rpos+1);
							path=path.Left(rpos+1);
						}
						else
							return FALSE;
					}
					if (path.Right(1)!="]")
						return FALSE;
					path.TrimRight( _T("]") );
					if (pos1)
						m_Prefix=path.Left(pos1);
					path=path.Mid(pos1+1);
					int pos=path.Find( _T(".") );
					while(pos!=-1)
					{
						m_Segments.push_back(path.Left(pos));
						path=path.Mid(pos+1);
						pos=path.Find( _T(".") );
					}
					if (path!="")
						m_Segments.push_back(path);
				}
				break;
			case FZ_SERVERTYPE_SUB_FTP_UNKNOWN:
				while (path.Replace('.', '/'));
			default:
				path.Replace( _T("\\"), _T("/") );
				while(path.Replace( _T("//"), _T("/") ));
				path.TrimLeft( _T("/") );
				if (bIsFile)
				{
					if (path.Right(1)!= _T("/") )
					{
						int rpos=path.ReverseFind('/');
						if (rpos==-1)
						{
							newpath=path;
							m_bEmpty=TRUE;
							return TRUE;
						}
						file=path.Mid(rpos+1);
						path=path.Left(rpos);
					}
					else
						return FALSE;
				}
				path.TrimRight( _T("/") );
				int pos=path.Find( _T("/") );
				while(pos!=-1)
				{
					m_Segments.push_back(path.Left(pos));
					path=path.Mid(pos+1);
					pos=path.Find( _T("/") );
				}
				if (path!="")
					m_Segments.push_back(path);
				break;
			}
			break;
		case FZ_SERVERTYPE_LOCAL:
		{
			if (bIsFile)
			{
				if (path.Right(1)!= _T("\\") )
				{
					int rpos=path.ReverseFind('\\');
					if (rpos==-1)
						return FALSE;
					
					file=path.Mid(rpos+1);
					path=path.Left(rpos);
				}
				else
					return FALSE;
			}
			path.TrimRight( _T("\\") );
			while (path.Replace( _T("\\\\"), _T("\\") ));
			int pos=path.Find( _T(":\\") );
			if (pos==-1 || pos!=1)
				return FALSE;
			else
			{
				m_Prefix=path.Left(pos+1);
				path=path.Mid(pos+2);
			}
			pos=path.Find( _T("\\") );
			while (pos!=-1)
			{
				m_Segments.push_back(path.Left(pos));
				path=path.Mid(pos+1);
				pos=path.Find( _T("\\") );
			}
			if (path!="")
				m_Segments.push_back(path);			
		}
		break;
	}
	if (bIsFile)
		newpath = file;
	return TRUE;
}

const CString CServerPath::GetPath() const
{
	if (m_bEmpty)
		return "";
	CString path;
	tConstIter iter;
	switch (m_nServerType&FZ_SERVERTYPE_HIGHMASK)
	{
	case FZ_SERVERTYPE_FTP:
		switch (m_nServerType&FZ_SERVERTYPE_SUBMASK)
		{
		case FZ_SERVERTYPE_SUB_FTP_MVS:
		case FZ_SERVERTYPE_SUB_FTP_BS2000:
			path = "'";
			for (iter = m_Segments.begin(); iter != m_Segments.end(); iter++)
			{
				if (iter != m_Segments.begin())
					path += _T(".");
				path += *iter;
			}
			path += m_Prefix + "'";
			break;
		case FZ_SERVERTYPE_SUB_FTP_VMS:
			path = m_Prefix + "[";
			for (iter = m_Segments.begin(); iter != m_Segments.end(); iter++)
				path += *iter + _T(".");
			path.TrimRight( _T(".") );
			path += "]";
			break;
		case FZ_SERVERTYPE_SUB_FTP_UNKNOWN:
			for (iter=m_Segments.begin(); iter!=m_Segments.end(); iter++)
				path+=*iter + _T(".");
			break;
		default:
			if (!(m_nServerType & FZ_SERVERTYPE_SUB_FTP_WINDOWS))
				path="/";
			for (iter=m_Segments.begin(); iter!=m_Segments.end(); iter++)
				path+=*iter + _T("/");
			break;
		}
		break;
	case FZ_SERVERTYPE_LOCAL:
		path=m_Prefix;
		if (!m_Segments.empty())
			path+="\\";
		for (iter=m_Segments.begin(); iter!=m_Segments.end(); iter++)
			path+=*iter + _T("\\");
				

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?