mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
550 lines
14 KiB
C++
550 lines
14 KiB
C++
//---------------------------------------------------------------------------
|
|
#include "FileZillaPCH.h"
|
|
#include "ServerPath.h"
|
|
#include "structures.h"
|
|
|
|
#define FTP_MVS_DOUBLE_QUOTA static_cast<TCHAR>(0xDC)
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Konstruktion/Destruktion
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CServerPath::CServerPath()
|
|
{
|
|
m_nServerType = 0;
|
|
m_bEmpty = TRUE;
|
|
}
|
|
|
|
CServerPath::CServerPath(CString path, bool trim)
|
|
{
|
|
m_nServerType = FZ_SERVERTYPE_FTP;
|
|
if (trim)
|
|
{
|
|
path.TrimLeft( L" " );
|
|
path.TrimRight( L" " );
|
|
}
|
|
if (path == L"")
|
|
{
|
|
m_bEmpty = TRUE;
|
|
return;
|
|
}
|
|
else
|
|
m_bEmpty = FALSE;
|
|
|
|
int pos1 = path.Find( L":[" );
|
|
if (pos1 != -1 && path.Right(1) == L"]" && pos1 != (path.GetLength()-1))
|
|
m_nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
|
|
else if (path.GetLength() >= 3 && _istalpha(path[0]) && path[1] == L':' && (path[2] == L'\\' || path[2] == L'/'))
|
|
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] == L'\'' && path.Right(1) == L"'" && path.Find(L'/') == -1 && path.Find(L'\\') == -1)
|
|
m_nServerType |= FZ_SERVERTYPE_SUB_FTP_MVS;
|
|
|
|
*this = CServerPath(path, m_nServerType, trim);
|
|
}
|
|
|
|
CServerPath::CServerPath(CString path, int nServerType, bool trim)
|
|
{
|
|
m_nServerType = nServerType;
|
|
if (trim)
|
|
{
|
|
path.TrimLeft( L" " );
|
|
path.TrimRight( L" " );
|
|
}
|
|
if (path == L"")
|
|
{
|
|
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(L'\'');
|
|
path.TrimRight(L'\'');
|
|
path.TrimLeft(L'.');
|
|
while (path.Replace(L"..", L"."));
|
|
|
|
int pos = path.Find(L".");
|
|
while (pos != -1)
|
|
{
|
|
m_Segments.push_back(path.Left(pos));
|
|
path = path.Mid(pos + 1);
|
|
pos = path.Find( L"." );
|
|
}
|
|
if (path != L"")
|
|
m_Segments.push_back(path);
|
|
else
|
|
m_Prefix = L".";
|
|
}
|
|
break;
|
|
case FZ_SERVERTYPE_SUB_FTP_VMS:
|
|
{
|
|
int pos1 = path.Find( L"[" );
|
|
if (pos1 == -1 || path.Right(1) != L"]")
|
|
{
|
|
DebugFail();
|
|
m_bEmpty = TRUE;
|
|
return;
|
|
}
|
|
path.TrimRight( L"]" );
|
|
if (pos1)
|
|
m_Prefix = path.Left(pos1);
|
|
path = path.Mid(pos1 + 1);
|
|
int pos = path.Find( L"." );
|
|
while (pos != -1)
|
|
{
|
|
m_Segments.push_back(path.Left(pos));
|
|
path = path.Mid(pos+1);
|
|
pos = path.Find( L"." );
|
|
}
|
|
if (path != L"")
|
|
m_Segments.push_back(path);
|
|
}
|
|
break;
|
|
default:
|
|
path.Replace( L"\\", L"/" );
|
|
while (path.Replace( L"//", L"/" ));
|
|
path.TrimLeft( L"/" );
|
|
path.TrimRight( L"/" );
|
|
int pos = path.Find( L"/" );
|
|
while (pos != -1)
|
|
{
|
|
m_Segments.push_back(path.Left(pos));
|
|
path = path.Mid(pos+1);
|
|
pos = path.Find( L"/" );
|
|
}
|
|
if (path != L"")
|
|
m_Segments.push_back(path);
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
DebugFail();
|
|
}
|
|
}
|
|
|
|
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( L" " );
|
|
path.TrimRight( L" " );
|
|
if (path != L"")
|
|
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( L":[" );
|
|
if (pos1!=-1 && pos1!=(path.GetLength()-2))
|
|
{
|
|
if (!bIsFile && path.Right(1)==L"]")
|
|
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] == L':' && (newpath[2] == L'\\' || newpath[2] == L'/'))
|
|
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;
|
|
}
|
|
m_Segments.clear();
|
|
m_Prefix = L"";
|
|
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(L'\'');
|
|
path.TrimRight(L'\'');
|
|
path.TrimLeft(L'.');
|
|
while (path.Replace(L"..", L"."));
|
|
|
|
int pos = path.Find(L".");
|
|
while (pos != -1)
|
|
{
|
|
m_Segments.push_back(path.Left(pos));
|
|
path = path.Mid(pos + 1);
|
|
pos = path.Find( L"." );
|
|
}
|
|
if (path != L"")
|
|
m_Segments.push_back(path);
|
|
else
|
|
m_Prefix = L".";
|
|
|
|
if (bIsFile)
|
|
{
|
|
if (m_Segments.empty())
|
|
return FALSE;
|
|
file = m_Segments.back();
|
|
m_Segments.pop_back();
|
|
|
|
if (file.Right(1) == L".")
|
|
return FALSE;
|
|
|
|
int pos = file.Find(L'(');
|
|
int pos2 = file.Find(L')');
|
|
if (pos != -1)
|
|
{
|
|
if (!pos || pos2 != file.GetLength() - 2)
|
|
return FALSE;
|
|
m_Prefix = L"";
|
|
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( L"[" );
|
|
if (pos1==-1)
|
|
return FALSE;
|
|
if (bIsFile)
|
|
{
|
|
int rpos=path.ReverseFind(L']');
|
|
if (rpos==-1)
|
|
return FALSE;
|
|
else if (rpos!=(path.GetLength()-1) )
|
|
{
|
|
file=path.Mid(rpos+1);
|
|
path=path.Left(rpos+1);
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
if (path.Right(1)!=L"]")
|
|
return FALSE;
|
|
path.TrimRight( L"]" );
|
|
if (pos1)
|
|
m_Prefix=path.Left(pos1);
|
|
path=path.Mid(pos1+1);
|
|
int pos=path.Find( L"." );
|
|
while(pos!=-1)
|
|
{
|
|
m_Segments.push_back(path.Left(pos));
|
|
path=path.Mid(pos+1);
|
|
pos=path.Find( L"." );
|
|
}
|
|
if (path!=L"")
|
|
m_Segments.push_back(path);
|
|
}
|
|
break;
|
|
default:
|
|
path.Replace( L"\\", L"/" );
|
|
while(path.Replace( L"//", L"/" ));
|
|
path.TrimLeft( L"/" );
|
|
if (bIsFile)
|
|
{
|
|
if (path.Right(1)!= L"/" )
|
|
{
|
|
int rpos=path.ReverseFind(L'/');
|
|
if (rpos==-1)
|
|
{
|
|
newpath=path;
|
|
m_bEmpty=TRUE;
|
|
return TRUE;
|
|
}
|
|
file=path.Mid(rpos+1);
|
|
path=path.Left(rpos);
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
path.TrimRight( L"/" );
|
|
int pos=path.Find( L"/" );
|
|
while(pos!=-1)
|
|
{
|
|
m_Segments.push_back(path.Left(pos));
|
|
path=path.Mid(pos+1);
|
|
pos=path.Find( L"/" );
|
|
}
|
|
if (path!=L"")
|
|
m_Segments.push_back(path);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
if (bIsFile)
|
|
newpath = file;
|
|
return TRUE;
|
|
}
|
|
|
|
const CString CServerPath::DoGetPath(bool unterminated) const
|
|
{
|
|
if (m_bEmpty)
|
|
return L"";
|
|
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 = L"'";
|
|
for (iter = m_Segments.begin(); iter != m_Segments.end(); iter++)
|
|
{
|
|
if (iter != m_Segments.begin())
|
|
path += L".";
|
|
path += *iter;
|
|
}
|
|
path += m_Prefix + L"'";
|
|
break;
|
|
case FZ_SERVERTYPE_SUB_FTP_VMS:
|
|
path = m_Prefix + L"[";
|
|
for (iter = m_Segments.begin(); iter != m_Segments.end(); iter++)
|
|
path += *iter + L".";
|
|
path.TrimRight( L"." );
|
|
path += L"]";
|
|
break;
|
|
default:
|
|
if (!(m_nServerType & FZ_SERVERTYPE_SUB_FTP_WINDOWS))
|
|
path=L"/";
|
|
for (iter=m_Segments.begin(); iter!=m_Segments.end(); iter++)
|
|
path+=*iter + L"/";
|
|
if (unterminated)
|
|
{
|
|
if (path.GetLength() >= 2)
|
|
{
|
|
path.Delete(path.GetLength() - 1, 1);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
DebugFail();
|
|
}
|
|
return path;
|
|
}
|
|
|
|
const CString CServerPath::GetPath() const
|
|
{
|
|
return DoGetPath(false);
|
|
}
|
|
|
|
const CString CServerPath::GetPathUnterminated() const
|
|
{
|
|
return DoGetPath(true);
|
|
}
|
|
|
|
CServerPath& CServerPath::operator=(const CServerPath &op)
|
|
{
|
|
if (this == &op)
|
|
return *this;
|
|
m_Segments.clear();
|
|
|
|
m_nServerType = op.m_nServerType;
|
|
|
|
m_Prefix = op.m_Prefix;
|
|
m_bEmpty = op.m_bEmpty;
|
|
|
|
m_Segments = op.m_Segments;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool CServerPath::operator==(const CServerPath &op) const
|
|
{
|
|
if (this == &op)
|
|
return true;
|
|
|
|
if (m_bEmpty != op.m_bEmpty)
|
|
return false;
|
|
if (m_Prefix != op.m_Prefix)
|
|
return false;
|
|
// excluding FZ_SERVERTYPE_LAYERMASK from comparison,
|
|
// as this part of server type is not set in TFileZillaIntf
|
|
const int CompareMask = FZ_SERVERTYPE_HIGHMASK | FZ_SERVERTYPE_SUBMASK;
|
|
if ((m_nServerType & CompareMask) != (op.m_nServerType & CompareMask))
|
|
return false;
|
|
tConstIter iter1 = m_Segments.begin();
|
|
tConstIter iter2 = op.m_Segments.begin();
|
|
while (iter1 != m_Segments.end())
|
|
{
|
|
if (iter2 == op.m_Segments.end())
|
|
return false;
|
|
if (*iter1 != *iter2)
|
|
return false;
|
|
iter1++;
|
|
iter2++;
|
|
}
|
|
if (iter2 != op.m_Segments.end())
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool CServerPath::operator!=(const CServerPath &op) const
|
|
{
|
|
if (*this == op)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
CString CServerPath::GetLastSegment() const
|
|
{
|
|
if (!HasParent())
|
|
return L"";
|
|
if (m_Segments.empty())
|
|
return L"";
|
|
else
|
|
return m_Segments.back();
|
|
}
|
|
|
|
CServerPath CServerPath::GetParent() const
|
|
{
|
|
DebugAssert(HasParent());
|
|
CServerPath path;
|
|
path = *this;
|
|
path.m_Segments.pop_back();
|
|
if (m_nServerType & (FZ_SERVERTYPE_SUB_FTP_MVS | FZ_SERVERTYPE_SUB_FTP_BS2000))
|
|
path.m_Prefix = L".";
|
|
return path;
|
|
}
|
|
|
|
BOOL CServerPath::HasParent() const
|
|
{
|
|
if (!m_Segments.empty())
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CServerPath::IsEmpty() const
|
|
{
|
|
return m_bEmpty;
|
|
}
|
|
|
|
BOOL CServerPath::AddSubdir(CString subdir)
|
|
{
|
|
if (subdir == L"")
|
|
return FALSE;
|
|
|
|
if (m_nServerType & (FZ_SERVERTYPE_SUB_FTP_MVS | FZ_SERVERTYPE_SUB_FTP_BS2000) && m_Prefix != L".")
|
|
return FALSE;
|
|
|
|
m_Segments.push_back(subdir);
|
|
|
|
if (m_nServerType & (FZ_SERVERTYPE_SUB_FTP_MVS | FZ_SERVERTYPE_SUB_FTP_BS2000) && !m_Segments.empty())
|
|
{
|
|
if (m_Segments.back().Right(1) == L".")
|
|
{
|
|
m_Segments.back().TrimRight(L'.');
|
|
m_Prefix = L".";
|
|
}
|
|
else
|
|
m_Prefix = L"";
|
|
}
|
|
|
|
m_bEmpty = FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CServerPath::SetPath(CString newpath)
|
|
{
|
|
return SetPath(newpath, FALSE);
|
|
}
|
|
|
|
CString CServerPath::FormatFilename(CString fn, bool omitPath /*=false*/) const
|
|
{
|
|
if (m_bEmpty)
|
|
return fn;
|
|
|
|
if (fn == L"")
|
|
return L"";
|
|
|
|
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:
|
|
if (omitPath && m_Prefix == L".")
|
|
return fn;
|
|
|
|
path = L"'";
|
|
for (iter = m_Segments.begin(); iter != m_Segments.end(); iter++)
|
|
path += *iter + L".";
|
|
if (m_Prefix != L".")
|
|
{
|
|
path.TrimRight(L'.');
|
|
path += L"(" + fn + L")";
|
|
}
|
|
else
|
|
path += fn;
|
|
path += L"'";
|
|
break;
|
|
case FZ_SERVERTYPE_SUB_FTP_VMS:
|
|
if (omitPath)
|
|
return fn;
|
|
|
|
path = m_Prefix + L"[";
|
|
for (iter = m_Segments.begin(); iter != m_Segments.end(); iter++)
|
|
path += *iter + L".";
|
|
path.TrimRight( L"." );
|
|
path += L"]";
|
|
path += fn;
|
|
break;
|
|
default:
|
|
if (omitPath)
|
|
return fn;
|
|
if (!(m_nServerType & FZ_SERVERTYPE_SUB_FTP_WINDOWS))
|
|
path=L"/";
|
|
for (iter = m_Segments.begin(); iter != m_Segments.end(); iter++)
|
|
path+=*iter + L"/";
|
|
path += fn;
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
DebugFail();
|
|
}
|
|
return path;
|
|
}
|