📄 ftplistparse.cpp
字号:
if( !IsUNIXStyleListing(pszLine) )
return false;
switch( *pszLine )
{
case _T('d'): ftpFileStatus.m_fTryCwd = true; break;
case _T('-'): ftpFileStatus.m_fTryRetr = true; break;
case _T('l'): ftpFileStatus.m_fTryCwd = true;
ftpFileStatus.m_fTryRetr = true;
}
int iState = 1;
int i = 0;
long lSize = 0;
long lYear = 0;
long lMonth = 0;
long lMDay = 0;
long lHour = 0;
long lMinute = 0;
for( int j=1; j<iLength; ++j )
{
if( pszLine[j]==_T(' ') && pszLine[j-1]!=_T(' ') )
{
switch(iState)
{
case 1: // skipping perm
ftpFileStatus.m_strAttributes.assign(pszLine+i, j-i);
iState = 2;
break;
case 2: // skipping nlink
iState = 3;
ftpFileStatus.m_strLink.assign(pszLine+i, j-i);
if( j-i==6 && pszLine[i]==_T('f') ) // for NetPresenz
iState = 4;
break;
case 3: // skipping uid
iState = 4;
ftpFileStatus.m_strUID.assign(pszLine+i, j-i);
break;
case 4: // getting tentative size
if( !GetLong(pszLine+i, j-i, lSize) )
{
lSize = -1;
ftpFileStatus.m_strGID.assign(pszLine+i, j-i);
}
iState = 5;
break;
case 5: // searching for month, otherwise getting tentative size
lMonth = GetMonth(pszLine + i,j - i);
if( lMonth >= 0 )
iState = 6;
else
{
if( !GetLong(pszLine+i, j-i, lSize) )
lSize = -1;
}
break;
case 6: // have size and month
GetLong(pszLine+i, j-i, lMDay);
iState = 7;
break;
case 7: // have size, month, mday
if( j-i==4 && pszLine[i+1]==_T(':') )
{
GetLong(pszLine+i, 1, lHour);
GetLong(pszLine+i+2, 2, lMinute);
ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
// ftpFileStatus.m_mtime = m_tmBase + GuessTAI(lMonth,lMDay) + lHour * 3600 + lMinute * 60;
INSERT_TIME();
}
else if( j-i==5 && pszLine[i+2]==_T(':') )
{
GetLong(pszLine+i, 2, lHour);
GetLong(pszLine+i+3, 2, lMinute);
ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
//ftpFileStatus.m_mtime = m_tmBase + GuessTAI(lMonth,lMDay) + lHour * 3600 + lMinute * 60;
INSERT_TIME();
}
else if( j-i >= 4 )
{
GetLong(pszLine+i, j-i, lYear);
ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteDay;
ftpFileStatus.m_mtime = m_tmBase + CFTPListParse::ToTAI(lYear,lMonth,lMDay);
INSERT_TIME();
}
else
return false;
ftpFileStatus.m_strName = pszLine + j + 1;
iState = 8;
break;
case 8: // twiddling thumbs
break;
}
i = j + 1;
while( i<iLength && pszLine[i]==_T(' ') )
++i;
}
}
if( iState != 8 )
return false;
ftpFileStatus.m_lSize = lSize;
ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;
// handle links
if( pszLine[0] == _T('l') )
{
tstring::size_type pos = ftpFileStatus.m_strName.find(_T(" -> "));
if( pos != tstring::npos )
ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(0, pos);
}
// eliminate extra NetWare spaces
if( pszLine[1]==_T(' ') || pszLine[1]==_T('[') )
{
if( ftpFileStatus.m_strName.length()>3 && ftpFileStatus.m_strName.substr(0, 3)==_T(" ") )
ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(3);
}
return true;
}
/// MultiNet (some spaces removed from examples)
/// "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)"
/// "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)"
/// and non-MutliNet VMS:
/// "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)"
bool CFTPListParse::IsMultiNetListing(LPCTSTR pszLine)
{
return pszLine && tcschr(pszLine, _T(';')) != NULL;
}
bool CFTPListParse::ParseMultiNetListing(CFTPFileStatus& ftpFileStatus, LPCTSTR pszLine, int iLength)
{
if( !IsMultiNetListing(pszLine) )
return false;
// name lookup of `i' changed for new ISO `for' scoping
int i=0;
for( ; i<iLength; ++i )
if( pszLine[i]==_T(';') )
break;
if( i < iLength)
{
ftpFileStatus.m_strName = pszLine;
ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(0, i);
if( i > 4 && tcsncmp(pszLine+i-4, _T(".DIR"), 4)==0 )
{
ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(0, ftpFileStatus.m_strName.length()-4);
ftpFileStatus.m_fTryCwd = true;
}
else
ftpFileStatus.m_fTryRetr = true;
while (pszLine[i] != _T(' ')) if (++i == iLength) return false;
while (pszLine[i] == _T(' ')) if (++i == iLength) return false;
while (pszLine[i] != _T(' ')) if (++i == iLength) return false;
while (pszLine[i] == _T(' ')) if (++i == iLength) return false;
int j = i;
while (pszLine[j] != _T('-')) if (++j == iLength) return false;
long lMDay = 0;
GetLong(pszLine+i, j-i, lMDay);
while (pszLine[j] == _T('-')) if (++j == iLength) return false;
i = j;
while (pszLine[j] != _T('-')) if (++j == iLength) return false;
long lMonth = GetMonth(pszLine+i, j-i);
if (lMonth < 0) return false;
while (pszLine[j] == _T('-')) if (++j == iLength) return false;
i = j;
while (pszLine[j] != _T(' ')) if (++j == iLength) return false;
long lYear = 0;
GetLong(pszLine+i, j-i, lYear);
while (pszLine[j] == _T(' ')) if (++j == iLength) return false;
i = j;
while (pszLine[j] != _T(':')) if (++j == iLength) return false;
long lHour = 0;
GetLong(pszLine+i, j-i, lHour);
while (pszLine[j] == _T(':')) if (++j == iLength) return false;
i = j;
while (pszLine[j] != _T(':') && pszLine[j] != _T(' ')) if (++j == iLength) return false;
long lMinute = 0;
GetLong(pszLine+i, j-i, lMinute);
ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
ftpFileStatus.m_mtime = m_tmBase + CFTPListParse::ToTAI(lYear, lMonth, lMDay) + lHour * 3600 + lMinute * 60;
INSERT_TIME();
}
return true;
}
/// MSDOS format
/// 04-27-00 09:09PM <DIR> licensed
/// 07-18-00 10:16AM <DIR> pub
/// 04-14-00 03:47PM 589 readme.htm
bool CFTPListParse::IsMSDOSListing(LPCTSTR pszLine)
{
return pszLine && tisdigit(pszLine[0]);
}
bool CFTPListParse::ParseMSDOSListing(CFTPFileStatus& ftpFileStatus, LPCTSTR pszLine, int iLength)
{
if( !IsMSDOSListing(pszLine) )
return false;
int i = 0;
int j = 0;
while (pszLine[j] != _T('-')) if (++j == iLength) return false;
long lMonth = 0;
GetLong(pszLine+i, j-i, lMonth); //+# -1
while (pszLine[j] == _T('-')) if (++j == iLength) return false;
i = j;
while (pszLine[j] != _T('-')) if (++j == iLength) return false;
long lMDay = 0;
GetLong(pszLine+i, j-i, lMDay);
while (pszLine[j] == _T('-')) if (++j == iLength) return false;
i = j;
while (pszLine[j] != _T(' ')) if (++j == iLength) return false;
long lYear = 0;
GetLong(pszLine+i, j-i, lYear);
if (lYear < 50)
lYear += 2000;
if (lYear < 1000)
lYear += 1900;
while (pszLine[j] == _T(' ')) if (++j == iLength) return false;
i = j;
while (pszLine[j] != _T(':')) if (++j == iLength) return false;
long lHour = 0;
GetLong(pszLine+i, j-i, lHour);
while (pszLine[j] == _T(':')) if (++j == iLength) return false;
i = j;
while ((pszLine[j] != _T('A')) && (pszLine[j] != _T('P'))) if (++j == iLength) return false;
long lMinute = 0;
GetLong(pszLine+i, j-i, lMinute);
if (lHour == 12)
lHour = 0;
if (pszLine[j] == _T('A')) if (++j == iLength) return false;
if (pszLine[j] == _T('P')) { lHour += 12; if (++j == iLength) return false; }
if (pszLine[j] == _T('M')) if (++j == iLength) return false;
while (pszLine[j] == _T(' ')) if (++j == iLength) return false;
if (pszLine[j] == _T('<'))
{
ftpFileStatus.m_fTryCwd = true;
while (pszLine[j] != _T(' ')) if (++j == iLength) return false;
}
else
{
i = j;
while (pszLine[j] != _T(' ')) if (++j == iLength) return false;
if( !GetLong(pszLine+i, j-i, ftpFileStatus.m_lSize ) )
ftpFileStatus.m_lSize = -1;
ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;
ftpFileStatus.m_fTryRetr = true;
}
while (pszLine[j] == _T(' ')) if (++j == iLength) return false;
ftpFileStatus.m_strName = pszLine + j;
ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
ftpFileStatus.m_mtime = m_tmBase + CFTPListParse::ToTAI(lYear,lMonth,lMDay) + lHour * 3600 + lMinute * 60;
INSERT_TIME();
return true;
}
bool CFTPListParse::Parse(CFTPFileStatus& ftpFileStatus, const tstring& strLineToParse)
{
ftpFileStatus.Reset();
LPCTSTR pszLine = strLineToParse.c_str();
const int iLength = static_cast<int>(strLineToParse.length());
if( iLength < 2 ) // an empty name in EPLF, with no info, could be 2 chars
return false;
if( IsEPLS(pszLine) )
{
if( !ParseEPLF(ftpFileStatus, pszLine, iLength) )
return false;
}
else if( IsUNIXStyleListing(pszLine) )
{
if( !ParseUNIXStyleListing(ftpFileStatus, pszLine, iLength) )
return false;
}
else if( IsMultiNetListing(pszLine) )
{
if( !ParseMultiNetListing(ftpFileStatus, pszLine, iLength) )
return false;
}
else if( IsMSDOSListing(pszLine) )
{
if( !ParseMSDOSListing(ftpFileStatus, pszLine, iLength) )
return false;
}
else
{
// Some useless lines, safely ignored:
// "Total of 11 Files, 10966 Blocks." (VMS)
// "total 14786" (UNIX)
// "DISK$ANONFTP:[ANONYMOUS]" (VMS)
// "Directory DISK$PCSA:[ANONYM]" (VMS)
return false;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -