/*---------------------------------------------------------------------------------------
 * $Id: SysParse.cpp 30 2009-11-29 23:38:12Z krkim $ $Revision: 30 $
 * $HeadURL: http://krkim-laptop/svn/DuruEdit/Src/DEFTP/SysParse.cpp $
 *Duru FTP Engine Class for RFC959 (Pure FTP only)
 *krkimÀÌ µÎ·ç¿¡µðÆ® ¿Ïº®ÇÑ FTP ±â´ÉÀ» À§ÇØ 2010.05.10~2010.05.17 ±¸ÇöÇÑ °Í
 *ÇÁ·ÎÅäÄÝ Âü°í ½ÎÀÌÆ® http://ftpguide.com
 *°¢¸ñÀÇ UNIX FTP È¯°æ¿¡¼­ ¸ñ·Ï¿À·ù°¡ ³ªÅ¸³ª ´õÀÌ»ó MSÀÇ WinINetÇÔ¼ö¸¦
 *»ç¿ëÇÏÁö ¸øÇÏ°Ô µÇ¾ú´Ù.¹°·Ð Æí¹ýÀ¸·Î FtpCommandÇÔ¼ö¸¦ ÀÌ¿ëÇØ ³¢¿ö³Ö±â
 *ÇÏ¸é µÇÁö¸¸,¹æÈ­º® Áö¿ø,±×¸®°í ´Ù¾çÇÑ ¼­¹öÅ¸ÀÔ,¿Ïº®ÇÑ passive,FTP Åë½Å
 *·Î±×µîÀ» º¸¿©ÁÖ°í ÃßÈÄ GNUTLS¸¦ ÀÌ¿ëÇÑ FTPS³ª SSH¸¦ ÀÌ¿ëÇÑ SFTPµîÀÇ È®Àå¼º
 *µµ °í·ÁÇØ¼­ RFC959 ÇÁ·ÎÅäÄÝÀ» Á÷Á¢ ±¸ÇöÇÏ´Â ÆíÀÌ ³ª¾Ò´Ù.

 *http://www.durumul.com,http://krkim.net 
 *yeamaec@hanafos.com, ns.quasar@gmail.com
 *Copyrights (c) 2010.05.15 krkim Allrights reserved.
 *RFC959 FTP Spec with Passive Mode Support
 *FTPS(Fillezilla)¿Í SFTP(Putty)´Â Â÷ÈÄ ÇÊ¿ä¼º°ú ¾¸¾¸ÀÌ Á¤µµ¸¦ º¸¾Æ Áö¿ø ÇÏ±â·Î ¹Ì·é´Ù.
 *Á»´õ,¾Æ´Ï È®½ÇÈ÷ ´õ º¹ÀâÇÏ±â ¶§¹®ÀÌ±âµµ ÇÔ ^^
 ---------------------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <time.h>
#include "SysParse.h"

SysParse::SysParse()
{
	m_serverType = SYST_NONE;
}

SysParse::~SysParse()
{

}

#if defined(NEED_MEMCCPY)
/*
* VAX C does not supply a memccpy routine so I provide my own
*/
void *memccpy(void *dest, const void *src, int c, size_t n)
{
	int i=0;
	const unsigned char *ip=src;
	unsigned char *op=dest;

	while (i < n)
	{
		if ((*op++ = *ip++) == c)
			break;
		i++;
	}
	if (i == n)
		return NULL;
	return op;
}
#endif
#if defined(NEED_STRDUP)
/*
* strdup - return a malloc'ed copy of a string
*/
char *strdup(const char *src)
{
	int l = strlen(src) + 1;
	char *dst = malloc(l);
	if (dst)
		strcpy(dst,src);
	return dst;
}
#endif

int SysParse::findmonth(char *str)
{
	static char *months[] = { 
		"Jan", "Feb" , "Mar", "Apr", "May", "Jun", "Jul",
		"Aug", "Sep",  "Oct", "Nov", "Dec"};

	for(int i=0;i<12;i++){
		if(!strnicmp(months[i],str,3))
			return i+1;
	}
	return 0;
}

char *SysParse::findspace(char *str)
{
	while(str && *str != ' ' && *str != '\t' && *str != '\r' && *str != '\n' && *str != '\0' ) str++;
	return str;
}

char *SysParse::getcolumnstr(char *linebuff, int column,bool includeremain)
{
	static char tempstr[512];
	char *p1, *p2;
	int i;

	strcpy(tempstr,linebuff);
	p1 = tempstr;
	while(p1 && (*p1 == ' ' || *p1 == '\t')) p1++;
	for(i = 0; column > 1 && i < column-1;i++) /* Skip n-1 words */
	{
		if ((*p1=='"')||(*p1=='\'')) 
		{
			p1=(char *)strchr(p1+1,*p1);
			if (p1==NULL) return "";
			p1++;
			while(p1 && (*p1 == ' ' || *p1 == '\t')) p1++;
			continue;
		}
		p1=findspace(p1);
		if ( *p1=='\0' ) return "";
		p1++;
		while(p1 && (*p1 == ' ' || *p1 == '\t')) p1++;
	}

	if ((*p1=='"')|(*p1=='\''))
	{
		p2=(char *)strchr(p1+1,*p1);
		if (p2==NULL) return p1+1;
		*p2=0;
		return p1+1;
	}

	if((p2=findspace(p1)) != NULL)
	{
		if(includeremain == false)
			*p2 = 0;
		return p1;
	}
	return "";
}

BOOL SysParse::isnumber(char *str)
{
	while(*str){
		if(*str < '0' || *str > '9')
			return 0;
		str++;
	}
	return 1;
}
int SysParse::ParseDir(char *linebuff,char *syst,DFServerType servertype,DFDirEntry *item)
{
	int count = 0;
	char templine[1024];
	DFServerType serverType = servertype;//-1 = auto
	memset(item,0,sizeof(DFDirEntry));

	if(m_serverType != SYST_NONE && serverType == SYST_AUTO){
		serverType = m_serverType;
	}
	else if(serverType == SYST_AUTO){
		if(!strcmp(syst,"VMS"))
			serverType = SYST_VMS;
		if(!strcmp(syst,"MSDOS"))
			serverType = SYST_DOS;
		if(!strcmp(syst,"UNIX") || !strcmp(syst,"UNKNOWN"))
			serverType = SYST_UNIX;
	}
	else if(serverType == SYST_WINDOWS ||serverType == SYST_NETWARE || serverType == SYST_WSFTPD)
		serverType = SYST_UNIX;

	if(m_serverType != serverType)
		m_serverType = serverType;

	memset(templine,0,sizeof(templine));
	lstrcpyn(templine,linebuff,sizeof(templine)+1);
	int len = lstrlen(templine);
	if(len < 1)
		return 0;
	char *p = templine + len -1;
	while(p >= templine && *p && (*p == '\r' || *p == '\n' || *p == '\t' ||*p == ' ')) *p-- = 0;

	if(ParseLine((char*)templine,serverType,*item)){
		return 1;
	}
	return 0;
}

int SysParse::ParseLine(char *linebuff,int serverType,DFDirEntry &item)
{
	int rc = 0;
	
	memset(&item,0,sizeof(DFDirEntry));
	if(*linebuff == '\0') return 0;
	
	if(serverType == SYST_VMS){
		rc = ParseAsVms(linebuff,&item);
		if(rc) goto done;
	}
	else if(serverType == SYST_DOS){
		rc = ParseAsDos(linebuff,&item);
		if(rc) goto done;
	}
	rc = ParseAsUnix(linebuff,&item);
	if(rc) goto done;
	rc = ParseAsDos(linebuff,&item);
	if(rc) goto done;
	rc = ParseAsVms(linebuff,&item);
	if(rc) goto done;
	rc = ParseAsIbm(linebuff,&item);
	if(rc) goto done;
	rc = ParseAsWfFtp(linebuff,&item);
	if(rc) goto done;
	return 0;
done:
	if(item.name[0] == 0 || !strcmp(item.name,".") || !strcmp(item.name,".."))
		return 0;

	return 1;
}

// ¾î¶² ¿Ü±¹ ½ÎÀÌÆ®¿¡¼­ Ã£¾Æ³½ Æ÷¸Ë,¿©±â¼± DOS,WINDOWS Æ÷¸ËÀÌ ¾à°£
// ½ÇÁ¦¿Í ´Ù¸£´Ù.

	/* 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" */
	
	/* 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)" */
	
	/* MSDOS format */
	/* 04-27-00  09:09PM       <DIR>          licensed */
	/* 07-18-00  10:16AM       <DIR>          pub */
	/* 04-14-00  03:47PM                  589 readme.htm */
	//±×·ìÀÌ »ý·«µÈ °æ¿ì (ftp.sunfreeware.com)
	//lrwxrwxrwx   1 staff          7 Aug 13  2003 bin -> usr/bin
	//d--x--x--x   2 staff        512 Sep 24  2000 dev
	//ftp.kr.freebsd.org
	//drwxr-xr-x  22 0         0  512 Aug  5  2009 pub

//this function support unix,netware,windows
int SysParse::ParseAsUnix(char *linebuff, DFDirEntry *entry)
{
	char tempbuf[512];
	int column=1;
	int tokenlen;
	int mon;

	strcpy(tempbuf,getcolumnstr(linebuff,column++));
	tokenlen = strlen(tempbuf);
	//filezilla
	if (tempbuf[0] != 'b' &&
		tempbuf[0] != 'c' &&
		tempbuf[0] != 'd' &&
		tempbuf[0] != 'l' &&
		tempbuf[0] != 'p' &&
		tempbuf[0] != 's' &&
		tempbuf[0] != '-')
		return 0;

	entry->dir = (tempbuf[0] == 'd' || tempbuf[0] == 'l') ? 1 : 0;
	entry->link = (tempbuf[0] == 'l') ? 1 : 0;
	strncpy(entry->permissions,tempbuf,10);
	
	int netware = 0;
	// Check for netware servers, which split the permissions into two parts 
	// ÆÄÀÏÁú¶ó directorylistingparser.cpp 908 line ÂüÁ¶
	if(tokenlen == 1){
		strcat(entry->permissions," ");
		strcat(entry->permissions,getcolumnstr(linebuff,column++));
		netware = 1;
	}
	if(!netware)
	{
		// Filter out link count, we don't need it
		// -rw-r--r--   1 COMNEKR  COMNEKR       893 Apr 14 05:10 crontab8.txt
		strcpy(tempbuf,getcolumnstr(linebuff, column++));
		if(tempbuf[0] == '\0')
			return 0;
		entry->inodes = atoi(tempbuf);
		if(tempbuf[0] < '0' || tempbuf[0] > '9')
			column--;
	}
	int numOwnerGroup = 3;
	//owner and group
	entry->ownergroup[0] = 0;
	for(int i = 0 ; i < numOwnerGroup; i++){
		strcpy(tempbuf,getcolumnstr(linebuff, column++));
		if(i <= 1 || ( i >= 2 && !isnumber(tempbuf))){
			char tempbuf2[256];
			strcpy(tempbuf2,getcolumnstr(linebuff, column));
			mon = findmonth(tempbuf2);
			if(mon > 0)//next is Jan,Feb, so maybe file size not groupname
				break;
			if(i)
				strcat(entry->ownergroup," ");
			strcat(entry->ownergroup,tempbuf);
			tempbuf[0] = 0;
		}
		else
			break;
	}
	if(!tempbuf[0])//not size
		strcpy(tempbuf,getcolumnstr(linebuff, column++));
	if(isnumber(tempbuf))
		entry->size = atoi(tempbuf);

	int step = 0;
	strcpy(tempbuf,getcolumnstr(linebuff, column++));
	// Some servers use the following date formats:
	// 2002-10-14
	// 2004.07.15
	// 26-05 2002
	// 30-DEC-1996
	// 01-jun-99
	// Apr 14 05:10
	// Dec  5  2008
	// 1¿ù 15ÀÏ 10:35
	// slashes instead of dashes are also possible

	char deli = 0;
	char *p = strchr(tempbuf,'-');
	if(!p)
		p = strchr(tempbuf,'.');
	if(p){
		deli = *p;
		int len = p - tempbuf;
		if(len >= 4){//YYYY-MM-DD or YYYY.MM.DD 2002-10-14 2004.07.15
			*p = 0;
			entry->year = atoi(tempbuf);
			entry->month = atoi(p+1);
			p++;
			char *q = strchr(p,deli);
			if(*q){
				entry->day = atoi(q+1);
			}
		}
		else{//DD-MM-YYYY or DD-MM YYYY 26-05 2002
			*p = 0;
			entry->day = atoi(tempbuf);
			entry->month = atoi(p+1);
			mon = findmonth(p+1);//30-DEC-1996
			if(mon > 0)
				entry->month = mon;
			p++;
			char *q = strchr(p,deli);
			if(*q){
				entry->year = atoi(q+1);
			}
			else{
				strcpy(tempbuf,getcolumnstr(linebuff, column++));
				entry->year = atoi(tempbuf);
			}
			if(entry->year != 0 && entry->year < 1900)//01-jun-99
				entry->year += 1900;
		}
	}
	else {//Apr 14 05:10 Dec  5  2008 1¿ù 15ÀÏ 10:35
		mon = findmonth(tempbuf);
		if(mon > 0)
			entry->month = mon;
		else
			entry->month = atoi(tempbuf);
		strcpy(tempbuf,getcolumnstr(linebuff, column++));
		entry->day = atoi(tempbuf);
		strcpy(tempbuf,getcolumnstr(linebuff, column++));
		if(strchr(tempbuf,':')){
			time_t ltm;
			//time_t timespan;
			struct tm *psttm;
			ltm = time(NULL);//ÃÊ´ÜÀ§,½Ã°£ÀÌ ÀÖ´Â °ÍÀº ¿ÃÇØÀÌ´Ù.
			psttm = localtime(&ltm);
			entry->year = psttm->tm_year + 1900;
			char tempxx[10];
			lstrcpy(tempxx,tempbuf);
			char *p = strchr(tempxx,':');
			if(p){
				*p= 0;
				entry->min = atoi(p+1);
				entry->hour = atoi(tempxx);
			}
		}
		else
			entry->year = atoi(tempbuf);
		step = 1;
	}

	strcpy(tempbuf,getcolumnstr(linebuff, column++,(entry->link) ? false : true));
	tokenlen = strlen(tempbuf);
	if(tokenlen > 0 && //filezilla directorylistingparser.cpp 980 line
		(tempbuf[tokenlen-1] == '/' || tempbuf[tokenlen-1] == '|' || tempbuf[tokenlen-1] == '*'))
	{
		tempbuf[tokenlen-1] = 0;
	}
	strcpy(entry->name,tempbuf);

	strcpy(tempbuf,getcolumnstr(linebuff, column++));
	if(entry->link && !strcmp(tempbuf,"->"))
	{
		strcpy(entry->target,getcolumnstr(linebuff, column++));
	}
	return 1;
}

/* and non-MutliNet VMS: */
/* "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,,)" */
int SysParse::ParseAsVms(char *linebuff, DFDirEntry *entry)
{
	char tempbuf[512];
	int column=1;
	int i;
	int tokenlen;
	char *p;

	strcpy(tempbuf,getcolumnstr(linebuff,1));
	tokenlen = strlen(tempbuf);
	p = strchr(tempbuf,';');
	if(!p)
		return 0;

	//if(*getcolumnstr(linebuff,2) == 0 && ((char*)strchr(tempbuf,'.') != NULL && 
 //    	((char*)strchr(tempbuf,';'))!=NULL)
 //     && fgets(tempbuf,sizeof(tempbuf),in)!=NULL)
 //   *(char *)strchr(str,10)=0,
 //   strcat(str,tmp);
	if(p - tempbuf > 4 && strncmp(p - 4,".DIR",4) == 0)  
	{
		entry->dir = 1;
		if(strcmp(p,";1") == 0)
			lstrcpyn(entry->name,tempbuf,p - tempbuf+1);
		else{
			lstrcpyn(entry->name,tempbuf,p - tempbuf);
			lstrcat(entry->name,p);
		}
		p = strrchr(entry->name,';');//trim version num;
		if(p) *p = 0;
	}
	else{
		entry->dir = 0;
		lstrcpy(entry->name,tempbuf);
	}
	// filezilla Some VMS servers escape special characters like additional dots with ^
	if(strchr(entry->name,'^')){
		int j = 0;
		for(i = 0; i <lstrlen(entry->name);i++)
		{
			if(entry->name[i] != '^')
				tempbuf[j++] = entry->name[i];
		}
		tempbuf[j] = 0;
		lstrcpy(entry->name,tempbuf);
	}
	
	int groupindex = 4;
	strcpy(tempbuf,getcolumnstr(linebuff,groupindex));
	if(tempbuf[0] != '[')//½Ã°£ÀÌ »ý·«µÈ °æ¿ì
		groupindex = 5;

	if(*getcolumnstr(linebuff,groupindex)!='[' && *getcolumnstr(linebuff,groupindex+1)!='(')
		return 0;
	
	// Definitely size = / otherwise Perhaps size

	strcpy(tempbuf,getcolumnstr(linebuff,2));
	entry->size = atoi(tempbuf);
	strcpy(tempbuf,getcolumnstr(linebuff,groupindex));

	if(strchr(tempbuf+1,',')==NULL)
	{
		strcpy(entry->ownergroup,tempbuf+1);
		*(char *)strchr(entry->ownergroup,']')='\0';
	}
	else
	{
		strcpy(entry->ownergroup,tempbuf+1);
		*(char *)strchr(entry->ownergroup,',')=' ';
		*(char *)strchr(entry->ownergroup,']')='\0';
	}

	for(p=entry->ownergroup;*p;p++) *p=tolower(*p);

	entry->day = atoi(getcolumnstr(linebuff,3));

	strcpy(tempbuf,(char *)strchr(getcolumnstr(linebuff,3),'-')+1);
	tempbuf[3]=0;
	entry->month = findmonth(tempbuf);

	if(groupindex == 5){
		strcpy(tempbuf,getcolumnstr(linebuff,4));
		entry->hour = atoi(tempbuf);
		p = strchr(tempbuf,':');
		if(p)
			entry->min = atoi(p+1);
	}

	strcpy(tempbuf,getcolumnstr(linebuff,groupindex+1));
	
	for(p=tempbuf;*p;p++){
		if(*p == ',')
			*p = ' ';
		if(*p == ')')
			*p = 0;
	}
	strcpy(entry->permissions,tempbuf);
	return 1;
}

/* MSDOS format */
/* 04-27-00  09:09PM       <DIR>          licensed */
/* 07-18-00  10:16AM       <DIR>          pub */
/* 04-14-00  03:47PM                  589 readme.htm */
int SysParse::ParseAsDos(char *linebuff, DFDirEntry *entry)
{
	char tempbuf[512];
	int column=1;
	int tokenlen;
	char *p;

	if(*getcolumnstr(linebuff,6) != 0) return 0;

	strcpy(tempbuf,getcolumnstr(linebuff,1));
	tokenlen = strlen(tempbuf);
	
	entry->month = atoi(tempbuf);
	p = strchr(tempbuf,'-');//mm-dd-yyyy
	if(!p)
		p = strchr(tempbuf,'.');
	if(!p)
		p = strchr(tempbuf,'/');
	if(p){
		char deli = *p;
		int year = -1;
		if(p - tempbuf == 4){//yyyy-mm-dd
			year = entry->year = atoi(tempbuf);
			entry->month = atoi(p+1);
		}
		else
			entry->day = atoi(p+1);
		p = strchr(p+1,deli);
		if(p){
			if(year == -1)
				entry->year = atoi(p+1);
			else
				entry->day = atoi(p+1);
		}
		if(entry->year <= 70)
			entry->year += 2000;
		else if(entry->year <= 1000)
			entry->year += 1900;
	}
	int tmpi = entry->month;

	if(tmpi > 12){
		entry->month = entry->day;
		entry->day = tmpi;
	}
	//time
	strcpy(tempbuf,getcolumnstr(linebuff,2));
	entry->hour = atoi(tempbuf);
	p = strchr(tempbuf,':');
	if(p)
		entry->min = atoi(p+1);
	//dir or size
	strcpy(tempbuf,getcolumnstr(linebuff,3));
	if(!stricmp(tempbuf,"<dir>")){
		entry->dir = 1;
	}
	else{
		entry->dir = 0;
		entry->size = atoi(tempbuf);
	}
	//name
	strcpy(tempbuf,getcolumnstr(linebuff,4));
	if(!strcmp(tempbuf,".")||!strcmp(tempbuf,".."))
		return 0;
	
	entry->permissions[0] = 0;
	entry->target[0] = 0;
	entry->link = 0;
	entry->ownergroup[0] = 0;
	strcpy(entry->name,tempbuf);
	return 1;
}

int SysParse::ParseAsIbm(char *linebuff, DFDirEntry *entry)
{
	char tempbuf[512];
	int column=1;
	int tokenlen;
	char *p;
	//get owner
	strcpy(tempbuf,getcolumnstr(linebuff,1));
	tokenlen = strlen(tempbuf);
	if(tokenlen < 1) return 0;
	lstrcpy(entry->ownergroup,tempbuf);
	//size
	strcpy(tempbuf,getcolumnstr(linebuff,2));
	if(!isnumber(tempbuf))
		return 0;
	entry->size = atoi(tempbuf);
	//date
	strcpy(tempbuf,getcolumnstr(linebuff,3));

	entry->month = atoi(tempbuf);
	p = strchr(tempbuf,'-');//mm-dd-yyyy
	if(!p)
		p = strchr(tempbuf,'.');
	if(!p)
		p = strchr(tempbuf,'/');
	if(p){
		char deli = *p;
		int year = -1;
		if(p - tempbuf == 4){//yyyy-mm-dd
			year = entry->year = atoi(tempbuf);
			entry->month = atoi(p+1);
		}
		else
			entry->day = atoi(p+1);
		p = strchr(p+1,deli);
		if(p){
			if(year == -1)
				entry->year = atoi(p+1);
			else
				entry->day = atoi(p+1);
		}
		if(entry->year <= 70)
			entry->year += 2000;
		else if(entry->year <= 1000)
			entry->year += 1900;
	}
	int tmpi = entry->month;

	if(tmpi > 12){
		entry->month = entry->day;
		entry->day = tmpi;
	}
	//time
	strcpy(tempbuf,getcolumnstr(linebuff,4));
	entry->hour = atoi(tempbuf);
	p = strchr(tempbuf,':');
	if(p)
		entry->min = atoi(p+1);
	//filename
	strcpy(tempbuf,getcolumnstr(linebuff,5));
	tokenlen = strlen(tempbuf);
	if(tokenlen == 0) return 0;

	if(tempbuf[tokenlen-1] == '/'){
		entry->dir = 1;
		tempbuf[tokenlen-1] = 0;
	}
	else{
		entry->dir = 0;
	}
	entry->target[0] = 0;
	entry->link = 0;
	strcpy(entry->name,tempbuf);
	return 1;
}

int SysParse::ParseAsWfFtp(char *linebuff, DFDirEntry *entry)
{
	char tempbuf[512];
	int column=1;
	int tokenlen;
	char *p;
	//get filename
	strcpy(tempbuf,getcolumnstr(linebuff,1));
	tokenlen = strlen(tempbuf);
	if(tokenlen < 1) return 0;
	lstrcpy(entry->name,tempbuf);

	//size
	strcpy(tempbuf,getcolumnstr(linebuff,2));
	if(!isnumber(tempbuf))
		return 0;
	entry->size = atoi(tempbuf);
	//date
	strcpy(tempbuf,getcolumnstr(linebuff,3));

	entry->month = atoi(tempbuf);
	p = strchr(tempbuf,'-');//mm-dd-yyyy
	if(!p)
		p = strchr(tempbuf,'.');
	if(!p)
		p = strchr(tempbuf,'/');
	if(p){
		char deli = *p;
		int year = -1;
		if(p - tempbuf == 4){//yyyy-mm-dd
			year = entry->year = atoi(tempbuf);
			entry->month = atoi(p+1);
		}
		else
			entry->day = atoi(p+1);
		p = strchr(p+1,deli);
		if(p){
			if(year == -1)
				entry->year = atoi(p+1);
			else
				entry->day = atoi(p+1);
		}
		if(entry->year <= 70)
			entry->year += 2000;
		else if(entry->year <= 1000)
			entry->year += 1900;
	}
	int tmpi = entry->month;

	if(tmpi > 12){
		entry->month = entry->day;
		entry->day = tmpi;
	}
	//unknown
	if(*getcolumnstr(linebuff,4) == 0) return 0;

	//time
	strcpy(tempbuf,getcolumnstr(linebuff,4));
	tokenlen = strlen(tempbuf);
	if(tokenlen > 0 && tempbuf[tokenlen-1] != '.')
		return 0;

	entry->hour = atoi(tempbuf);
	p = strchr(tempbuf,':');
	if(p)
		entry->min = atoi(p+1);
	entry->permissions[0] = 0;
	entry->target[0] = 0;
	entry->link = 0;
	entry->ownergroup[0] = 0;
	return 1;
}
/*
ÆÄÀÏÁú¶ó¿¡ ÀÇÇÏ¸é ASCII ¸ðµå´Â Å¬¶óÀÌ¾ðÆ®´Â ¹«Á¶°Ç CRLF·Î ¼­¹ö¿¡ ³¯¸®°í ¼­¹ö°¡ °¢ ¿ëµµ¿¡ ¸Â°Ô,Â¥¸£°Ô µÇ¾îÀÖ´Ù.
µû¶ó¼­,Å¬¶óÀÌ¾ðÆ®´Â Pair°¡ ¾È¸Â´Â CRLF¸¦ °Ë»çÇÏ¿© CRLF·Î ¸¸µé¾î ÁÖ¾î¼­ ³¯¸°´Ù. 2010.07
http://wiki.filezilla-project.org/Data_Type

Files can be transferred between an FTP client and server in different ways. The FTP specification (RFC 959) calls them "data type", but they are commonly referred to as "transfer mode", even though this is not correct. 

The different data types are: 

ASCII 
binary (called "image" in the specification) 
EBCDIC 
local 
But most of the time, however, only ASCII and binary types are used or even implemented. 

ASCII type is used to transfer text files. The problem with text files is that different platforms have different kinds of line endings. Microsoft Windows for example uses a CR+LF pair (carriage return and line feed), while Unix(-like) systems, including Linux and MacOS X, only use LF and traditional MacOS systems (MacOS 9 or older) only use CR. The purpose of ASCII type is to ensure that line endings are properly changed to what is right on the platform. According to the FTP specification, ASCII files are always transferred using a CR+LF pair as line ending. 

So in case the file is transferred from the client to the server, the client has to make sure CR+LF is used. Therefore it has to add nothing (on Microsoft Windows), add CR (on Unix) or add LF (on legacy MacOS) to each line ending. The server then adjusts the line ending again to what is used on the platform the server runs at. If it is Microsoft Windows, nothing has to be removed, while on Unix the superfluous CR is removed and on legacy MacOS the unneeded LF. 

The same happens when a file is downloaded from the server to the client: the server makes sure the line endings are CR+LF when sending the file and the client then strips away whatever is not needed as line ending on its platform. 

Because the file is changed if client and server are not running on the same kind of platform, this data type cannot be used for files with arbitrary characters, so called binary files, like images and videos. If it is used anyway, the binary files most likely are corrupted and won't work as expected anymore. 

Compared to ASCII type, binary type is the easier one: the file is just transferred as-is, and no line ending translation is done. 

So when you are not sure what to use, always go for binary type. Nowadays, nearly all (good) text editors can handle the three possible line endings, and other textual files like the ones of scripting languages such as Perl or PHP, as well as XML files (nearly) always work with any line ending as well. 

[edit] Example 
Client system: Windows (CRLF line endings) 

Server system: Some Linux distribution (LF line endings) 

If you upload a text file with 200 lines and a total size of 5768 bytes, it will have a size of 5568 bytes on the server. 
*/
DFFileMode SysParse::CheckFileType(LPSTR filename)
{
	struct FILETYPELIST{
		DFFileMode filemode;
		char *extlist;
	};
	//"am|asp|bat|c|cfm|cgi|conf|cpp|css|dhtml|diz|h|hpp|htm|html|in|inc|js|jsp|m4|mak|md5|nfo|nsi|pas|patch|php|phtml|pl|po|py|qmail|sh|shtml|sql|svg|tcl|tpl|txt|vbs|xhtml|xml|xrc"
	static FILETYPELIST filetypes[] = 
	{ 
		PFMOD_ASCII,	"htm|html|txt|log|xml|php|php5|c|cc|cpp|h|hpp|pc|cxx|inc|cob|sql|java|js|jsp|asp|ec|pc|hp||",
		PFMOD_ASCII,	"php|php3|php4|asa|asp|aspx|asax|html|htm|shtml|ihtml|phtml|ssi|pl|htc|vfo|conf|prn|cs||",
		PFMOD_ASCII,	"tab|asc|csv|sh||",
		PFMOD_BINARY,	"jpg|jpeg|gif|bmp|pcx|png|ttf|hwp|h30|exe|dll|ocx|swf|rtf|avi|mpg|mpeg|mqv|asf|wmv|mov||",
		PFMOD_BINARY,	"zip|alz|gz|tar|tgz|z|rar|jar|ace|bz|bz2|wav|mp3|mid|wma|sit|doc||",
	};
	
	static FILETYPELIST none_ext =
	{
		PFMOD_ASCII,	"makefile|readme|",
	};
	TCHAR ext[300];
	int idx = 0;
	
	CHAR *p = filename;
	if(!p || !*p)
		return PFMOD_BINARY;
	p = strrchr(filename,'.');
	if(!p || !*p){
		lstrcpyn(ext,filename,sizeof(ext));
		lstrcat(ext,"|");
		CharLower(ext);
		if(strstr(none_ext.extlist,ext))
			return none_ext.filemode;
		return PFMOD_BINARY;
	}
	p++;
	if(!p || !*p)
		return PFMOD_BINARY;
	lstrcpyn(ext,p,sizeof(ext));
	lstrcat(ext,"|");
	CharLower(ext);
	for(idx = 0; idx < sizeof(filetypes)/sizeof(filetypes[0]); idx++){
		p = filetypes[idx].extlist;
		if(strstr(p,ext))
			return filetypes[idx].filemode;
	}
	return PFMOD_BINARY;
}
