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

📄 ftplistparse.cpp

📁 自己改写的在WINCE上开发用的EVC++的FTP操作示例工程,希望能给相关人士提供帮助.
💻 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 <tchar.h>
#include <time.h>
#include "DataStack2.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 = wce_ctime(&ftpFileStatus.m_mtime); }/*CCnv::ConvertToTString()*/
#else
#define INSERT_TIME()
#endif
#endif

using namespace nsFTP;
using namespace nsHelper;

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

CFTPListParse::CFTPListParse() :
	m_lCurrentYear(-1)
	{
		m_tmBase = 0;
		tm* ptm = wce_localtime(&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(LPCSTR pszBuffer, LPCSTR 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(LPCSTR 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(LPCSTR pszLong, int iLength, long& lResult) const
	{
		CStringA strLong(pszLong);
		
		LPSTR pszEndPtr = NULL;
		lResult = strtoul(strLong.GetString(), &pszEndPtr, 10);
		
		if( pszEndPtr!=NULL && pszEndPtr[0]!='\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 = wce_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(LPCSTR pszLine)
	{
		return pszLine && *pszLine == '+';
	}
	
	bool CFTPListParse::ParseEPLF(CFTPFileStatus& ftpFileStatus, LPCSTR 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')
			{
				ftpFileStatus.m_strName = pszLine+j+1;
				return true;
			}
			
			if (pszLine[j] == ',')
			{
				switch(pszLine[i])
				{
				case '/':
					ftpFileStatus.m_fTryCwd    = true;
					break;
				case 'r':
					ftpFileStatus.m_fTryRetr   = true;
					break;
				case 's':
					ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;
					if( !GetLong(pszLine+i+1, j-i-1, ftpFileStatus.m_lSize) )
						ftpFileStatus.m_lSize = -1;
					break;
				case 'm':
					ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttLocal;
					GetLong(pszLine+i+1, j-i-1, lTemp);
					ftpFileStatus.m_mtime = m_tmBase + lTemp;
					INSERT_TIME();
					break;
				case 'i':
					ftpFileStatus.m_enIDType = CFTPFileStatus::idFull;
					ftpFileStatus.m_strID    = pszLine+i+1;
					ftpFileStatus.m_strID    = ftpFileStatus.m_strID.Mid(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(LPCSTR pszLine)
	{
		if( pszLine==NULL )
			return false;
		
		switch(*pszLine)
		{
		case 'b':
		case 'c':
		case 'd':
		case 'l':
		case 'p':
		case 's':
		case '-':
			return true;
		}
		return false;
	}
	
	bool CFTPListParse::ParseUNIXStyleListing(CFTPFileStatus& ftpFileStatus, LPCSTR pszLine, int iLength)
	{
		if( !IsUNIXStyleListing(pszLine) )
			return false;
		

⌨️ 快捷键说明

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