📄 ftplistparse.cpp
字号:
switch( *pszLine )
{
case 'd': ftpFileStatus.m_fTryCwd = true; break;
case '-': ftpFileStatus.m_fTryRetr = true; break;
case '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] == ' ' && pszLine[j-1] != ' ')
{
CDataStack2 data;
switch(iState)
{
case 1: // skipping perm
data.NewStack(j-i+1);
data.SetAt(0,(char*)pszLine+i, j-i);
ftpFileStatus.m_strAttributes = data.GetData();
iState = 2;
break;
case 2: // skipping nlink
iState = 3;
data.NewStack(j-i+1);
data.SetAt(0,(char*)pszLine+i, j-i);
ftpFileStatus.m_strLink = data.GetData();
if( j-i==6 && pszLine[i] == 'f') // for NetPresenz
iState = 4;
break;
case 3: // skipping uid
iState = 4;
data.NewStack(j-i+1);
data.SetAt(0,(char*)pszLine+i, j-i);
ftpFileStatus.m_strUID = data.GetData();
break;
case 4: // getting tentative size
if( !GetLong(pszLine+i, j-i, lSize) )
{
lSize = -1;
data.NewStack(j-i+1);
data.SetAt(0,(char*)pszLine+i, j-i);
ftpFileStatus.m_strGID = data.GetData();
}
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]==':' )
{
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]==':' )
{
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]==' ')
++i;
}
}
if( iState != 8 )
return false;
ftpFileStatus.m_lSize = lSize;
ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;
// handle links
if( pszLine[0] == 'l' )
{
int pos = ftpFileStatus.m_strName.Find(" -> ");
if( pos != -1 )
ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(0, pos);
}
// eliminate extra NetWare spaces
if( pszLine[1]==' ' || pszLine[1]=='[')
{
if( ftpFileStatus.m_strName.GetLength()>3 && ftpFileStatus.m_strName.Mid(0, 3)==" " )
ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(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(LPCSTR pszLine)
{
return pszLine && strchr(pszLine, ';') != NULL;
}
bool CFTPListParse::ParseMultiNetListing(CFTPFileStatus& ftpFileStatus, LPCSTR 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]==';' )
break;
if( i < iLength)
{
ftpFileStatus.m_strName = pszLine;
ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(0, i);
if( i > 4 && strncmp(pszLine+i-4, ".DIR", 4)==0 )
{
ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(0, ftpFileStatus.m_strName.GetLength()-4);
ftpFileStatus.m_fTryCwd = true;
}
else
ftpFileStatus.m_fTryRetr = true;
while (pszLine[i] != ' ') if (++i == iLength) return false;
while (pszLine[i] == ' ') if (++i == iLength) return false;
while (pszLine[i] != ' ') if (++i == iLength) return false;
while (pszLine[i] == ' ') if (++i == iLength) return false;
int j = i;
while (pszLine[j] != '-') if (++j == iLength) return false;
long lMDay = 0;
GetLong(pszLine+i, j-i, lMDay);
while (pszLine[j] == '-') if (++j == iLength) return false;
i = j;
while (pszLine[j] != '-') if (++j == iLength) return false;
long lMonth = GetMonth(pszLine+i, j-i);
if (lMonth < 0) return false;
while (pszLine[j] == '-') if (++j == iLength) return false;
i = j;
while (pszLine[j] != ' ') if (++j == iLength) return false;
long lYear = 0;
GetLong(pszLine+i, j-i, lYear);
while (pszLine[j] == ' ') if (++j == iLength) return false;
i = j;
while (pszLine[j] != ':') if (++j == iLength) return false;
long lHour = 0;
GetLong(pszLine+i, j-i, lHour);
while (pszLine[j] == ':') if (++j == iLength) return false;
i = j;
while (pszLine[j] != ':' && pszLine[j] != ' ') 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(LPCSTR pszLine)
{
return pszLine && _istdigit(pszLine[0]);
}
bool CFTPListParse::ParseMSDOSListing(CFTPFileStatus& ftpFileStatus, LPCSTR pszLine, int iLength)
{
if( !IsMSDOSListing(pszLine) )
return false;
int i = 0;
int j = 0;
while (pszLine[j] != '-') if (++j == iLength) return false;
long lMonth = 0;
GetLong(pszLine+i, j-i, lMonth); //+# -1
while (pszLine[j] == '-') if (++j == iLength) return false;
i = j;
while (pszLine[j] != '-') if (++j == iLength) return false;
long lMDay = 0;
GetLong(pszLine+i, j-i, lMDay);
while (pszLine[j] == '-') if (++j == iLength) return false;
i = j;
while (pszLine[j] != ' ') 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] == ' ') if (++j == iLength) return false;
i = j;
while (pszLine[j] != ':') if (++j == iLength) return false;
long lHour = 0;
GetLong(pszLine+i, j-i, lHour);
while (pszLine[j] == ':') if (++j == iLength) return false;
i = j;
while ((pszLine[j] != 'A') && (pszLine[j] != 'P')) if (++j == iLength) return false;
long lMinute = 0;
GetLong(pszLine+i, j-i, lMinute);
if (lHour == 12)
lHour = 0;
if (pszLine[j] == 'A') if (++j == iLength) return false;
if (pszLine[j] == 'P') { lHour += 12; if (++j == iLength) return false; }
if (pszLine[j] == 'M') if (++j == iLength) return false;
while (pszLine[j] == ' ') if (++j == iLength) return false;
if (pszLine[j] == '<')
{
ftpFileStatus.m_fTryCwd = true;
while (pszLine[j] != ' ') if (++j == iLength) return false;
}
else
{
i = j;
while (pszLine[j] != ' ') 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] == ' ') 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, CStringA& strLineToParse)
{
ftpFileStatus.Reset();
LPCSTR pszLine = (LPCSTR)strLineToParse;
const int iLength = static_cast<int>(strLineToParse.GetLength());
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 + -