⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftplistparse.cpp

📁 实现了wince 客户端上传下载查看文件及目录的功能接口d
💻 CPP
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////////
//
// Code taken from D. J. Bernstein (C ==> C++)
//
// ftpparse.c, ftpparse.h: library for parsing FTP LIST responses
// 20001223
// D. J. Bernstein, djb@cr.yp.to
// http://cr.yp.to/ftpparse.html
//
// Commercial use is fine, if you let me know what programs you're using this in.
//
// Currently covered formats:
// EPLF.
// UNIX ls, with or without gid.
// Microsoft FTP Service.
// Windows NT FTP Server.
// VMS.
// WFTPD.
// NetPresenz (Mac).
// NetWare.
// MSDOS.
//
// Definitely not covered: 
// Long VMS filenames, with information split across two lines.
// NCSA Telnet FTP server. Has LIST = NLST (and bad NLST for directories).
//
////////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "FTPListParse.h"
#include "FTPFileState.h"
#include <time.h>

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

#ifndef INSERT_TIME
#ifdef _DEBUG
#define INSERT_TIME() //if( ftpFileStatus.m_mtime>0 ) ftpFileStatus.m_strMTime = CCnv::ConvertToTString(asctime(gmtime(&ftpFileStatus.m_mtime)));
#else
#define INSERT_TIME()
#endif
#endif

using namespace nsFTP;
using namespace nsHelper;

TCHAR* CFTPListParse::m_Months[12] = {
   _T("jan"),_T("feb"),_T("mar"),_T("apr"),_T("may"),_T("jun"),
   _T("jul"),_T("aug"),_T("sep"),_T("oct"),_T("nov"),_T("dec")
};

CFTPListParse::CFTPListParse() :
   m_lCurrentYear(-1)
{
  /* m_tmBase = 0;
   tm* ptm = gmtime(&m_tmBase);
   m_tmBase = -(ToTAI(ptm->tm_year + 1900, ptm->tm_mon, ptm->tm_mday) + 
                ptm->tm_hour * 3600 + ptm->tm_min * 60 + ptm->tm_sec);*/
   // assumes the right time_t, counting seconds.
   // base may be slightly off if time_t counts non-leap seconds.
}

CFTPListParse::~CFTPListParse()
{
}

bool CFTPListParse::CheckMonth(LPCTSTR pszBuffer, LPCTSTR pszMonthName) const
{
  if ( tolower(pszBuffer[0]) != pszMonthName[0] ||
       tolower(pszBuffer[1]) != pszMonthName[1] ||
       tolower(pszBuffer[2]) != pszMonthName[2] )
     return false;

  return true;
}

int CFTPListParse::GetMonth(LPCTSTR pszBuffer,int iLength) const
{
  if (iLength == 3)
  {
    for (int i = 0; i < 12; ++i)
    {
      if (CheckMonth(pszBuffer, m_Months[i]))
         return i;
    }
  }
  return -1;
}

bool CFTPListParse::GetLong(LPCTSTR pszLong, int iLength, long& lResult) const
{
   tstring strLong(pszLong, iLength);
   
   LPTSTR pszEndPtr = NULL;
      lResult = tcstoul(strLong.c_str(), &pszEndPtr, 10);

   if( pszEndPtr!=NULL && pszEndPtr[0]!=_T('\0') )
      return false;

   return true;
}

long CFTPListParse::ToTAI(long lYear, long lMonth, long lMDay) const
{
   if (lMonth >= 2)
   {
      lMonth -= 2;
   }
   else
   {
      lMonth += 10;
      --lYear;
   }

   long lResult = (lMDay - 1) * 10 + 5 + 306 * lMonth;
   lResult /= 10;

   if (lResult == 365)
   {
      lYear -= 3;
      lResult = 1460;
   }
   else 
      lResult += 365 * (lYear % 4);

   lYear /= 4;

   lResult += 1461 * (lYear % 25);

   lYear /= 25;

   if (lResult == 36524)
   {
      lYear -= 3;
      lResult = 146096;
   }
   else
   {
      lResult += 36524 * (lYear % 4);
   }

   lYear /= 4;
   lResult += 146097 * (lYear - 5);
   lResult += 11017;

   return lResult * 86400;
}

long CFTPListParse::GetYear(time_t time) const
{
   long lDay = static_cast<long>(time / 86400L);

   if ((time % 86400L) < 0)
      --lDay;
   
   lDay -= 11017;
   
   long lYear = 5 + lDay / 146097;
   
   lDay = lDay % 146097;
   if (lDay < 0)
   {
      lDay += 146097;
      --lYear;
   }
   lYear *= 4;
   
   if (lDay == 146096) 
   {
      lYear += 3;
      lDay = 36524;
   }
   else
   {
      lYear += lDay / 36524;
      lDay %= 36524;
   }

   lYear *= 25;
   lYear += lDay / 1461;
   lDay %= 1461;
   lYear *= 4;

   if (lDay == 1460) 
   {
      lYear += 3;
      lDay = 365;
   }
   else
   {
      lYear += lDay / 365;
      lDay %= 365;
   }

   lDay *= 10;
   if ((lDay + 5) / 306 >= 10)
      ++lYear;

   return lYear;
}

/// UNIX ls does not show the year for dates in the last six months.
/// So we have to guess the year.
/// Apparently NetWare uses ``twelve months'' instead of ``six months''; ugh.
/// Some versions of ls also fail to show the year for future dates.
//long CFTPListParse::GuessTAI(long lMonth, long lMDay)
//{
//  ///////////////////////////*/*/*/*/
//  time_t now = time((time_t *) 0) - m_tmBase;
//
//  if (m_lCurrentYear==-1)
//  {
//    m_lCurrentYear = GetYear(now);
//  }
//
//  long lTAI = 0;
//  for (long lYear = m_lCurrentYear - 1; lYear < m_lCurrentYear + 100; ++lYear)
//  {
//    lTAI = ToTAI(lYear, lMonth, lMDay);
//    if (now - lTAI < 350 * 86400)
//      return lTAI;
//  }
//  return lTAI;
//}

/// Easily Parsed LIST Format (EPLF)
/// see http://pobox.com/~djb/proto/eplf.txt
/// "+i8388621.29609,m824255902,/,\tdev"
/// "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF"
bool CFTPListParse::IsEPLS(LPCTSTR pszLine)
{
   return pszLine && *pszLine == _T('+');
}

bool CFTPListParse::ParseEPLF(CFTPFileStatus& ftpFileStatus, LPCTSTR pszLine, int iLength)
{
   if( !IsEPLS(pszLine) )
      return false;

   long lTemp=0;
   int i = 1;
   for (int j=1; j<iLength; ++j)
   {
      if (pszLine[j] == _T('\t'))
      {
         ftpFileStatus.m_strName = pszLine+j+1;
         return true;
      }

      if (pszLine[j] == _T(','))
      {
         switch(pszLine[i])
         {
         case _T('/'):
            ftpFileStatus.m_fTryCwd    = true;
            break;
         case _T('r'):
            ftpFileStatus.m_fTryRetr   = true;
            break;
         case _T('s'):
            ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;
            if( !GetLong(pszLine+i+1, j-i-1, ftpFileStatus.m_lSize) )
               ftpFileStatus.m_lSize = -1;
            break;
         case _T('m'):
            ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttLocal;
            GetLong(pszLine+i+1, j-i-1, lTemp);
            ftpFileStatus.m_mtime = m_tmBase + lTemp;
            INSERT_TIME();
            break;
         case _T('i'):
            ftpFileStatus.m_enIDType = CFTPFileStatus::idFull;
            ftpFileStatus.m_strID    = pszLine+i+1;
            ftpFileStatus.m_strID    = ftpFileStatus.m_strID.substr(0, j-i-1);
         }
         i = j + 1;
      }
   }
   return false;
}

/// UNIX-style listing, without inum and without blocks
/// "-rw-r--r--   1 root     other        531 Jan 29 03:26 README"
/// "dr-xr-xr-x   2 root     other        512 Apr  8  1994 etc"
/// "dr-xr-xr-x   2 root     512 Apr  8  1994 etc"
/// "lrwxrwxrwx   1 root     other          7 Jan 25 00:17 bin -> usr/bin"
/// 
/// Also produced by Microsoft's FTP servers for Windows:
/// "----------   1 owner    group         1803128 Jul 10 10:18 ls-lR.Z"
/// "d---------   1 owner    group               0 May  9 19:45 Softlib"
/// 
/// Also WFTPD for MSDOS:
/// "-rwxrwxrwx   1 noone    nogroup      322 Aug 19  1996 message.ftp"
/// 
/// Also NetWare:
/// "d [R----F--] supervisor            512       Jan 16 18:53    login"
/// "- [R----F--] rhesus             214059       Oct 20 15:27    cx.exe"
//
/// Also NetPresenz for the Mac:
/// "-------r--         326  1391972  1392298 Nov 22  1995 MegaPhone.sit"
/// "drwxrwxr-x               folder        2 May 10  1996 network"
bool CFTPListParse::IsUNIXStyleListing(LPCTSTR pszLine)
{
   if( pszLine==NULL )
      return false;

   switch(*pszLine)
   {
   case _T('b'):
   case _T('c'):
   case _T('d'):
   case _T('l'):
   case _T('p'):
   case _T('s'):
   case _T('-'):
      return true;
   }
   return false;
}
//
bool CFTPListParse::ParseUNIXStyleListing(CFTPFileStatus& ftpFileStatus, LPCTSTR pszLine, int iLength)
{

⌨️ 快捷键说明

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