본문 바로가기

DuruEdit

[두루에디트 제작기] FTP Ascii 모드 Binary 모드,Auto 모드 처리하기

두루에디트?
두루에디트? 전세계를 통들어 너댓명만 제외하곤 도대체 듣보잡 두루에디트가 뭐냐하는 궁금증이 생길텐데 그건 당연할 수 밖에 없다.
왜냐하면 간혹 짬짬이 만드는 이 프로그램은, 너무나 허접한 나머지,
아래 화면과 같이 울트라 에디트,에디트 플러스 같은 텍스트 편집기 임은 분명한데 아직 인터넷과 같은 불특정 다수에게는 공개 하지 않았기 때문이다. 언젠가 완벽한 모양새를 갖춘다면 모를까...


어쨌든,FTP 프로토콜 RFC를 토대로 FTP 처리기를 구현하였지만, 아직 텍스트 모드 전송의 버그가 있다.
따라서,텍스트 모드 전송기능의 개선작업에 대해 알아 보도록 하고 어떻게 문제해결의 접근을 하는가 하는
방법을 제시하고자 한다.
우선,줄 끝을 알리는 End Of Line은 각 플랫폼 별로 상이하다.

유닉스.리눅스 계열: LF(0x0a) 최근 Mac OS X 이후 부터 여기에 가세.
Mac OS 9 이하 : CR(0x0d)
MS-Windows : CRLF(0x0d,0x0a)

원래의 CR의 의미는 파일이든,프린터든 Carrage Return 의 뜻으로 프린트로 치자면 프린트 헤더를 맨 좌측으로 이동하는 것이다.(Home키 같이 현재 줄의 선두로 이동하라는 의미)

원래의 LF는 Line Feed 로 프린트로 치자면 프린트 헤더를 다음 라인으로 수직으로 한칸(1줄) 내리는 것이다.
즉,CR만 하면 같은 줄의 맨 처음으로 이동하는 셈이되고 LF만 하면 다음 라인의 같은 칸으로 이동하는 셈이 된다.

따라서 정확한 의미는 CFLF가 합쳐져야 비로소 다음라인의 선두로 이동하는 것이지만 각 플랫폼마다 다르게 처리하고 있는 것이다.

뭐 어쨋든,FTP 클라이언트가 매번 서버가 무엇인지 FTP 명령 "SYST" 을 날려서(uname 같은 기능,,) 안먹히는 서버도 있기 때문에 이렇게 시스템 종류를 확인하고 구분할 수는 없는 노릇이다. 이 역할은 그 플랫폼에 설치되는 순전히 FTP 서버의 몫이 되어야 한다.

파일질라에 의하면 ASCII 모드는 클라이언트는 무조건 CRLF로 서버에 날리고 서버가 각 용도에 맞게,
짜르게 되어있다.
따라서,클라이언트는 Pair가 안맞는 CRLF를 검사하여 CRLF로 만들어 주어서 날린다.
2010.07 krkim

또한,파일질라는 다음의 파일 확장자를 디폴트 ASCII 처리로 하고 있다.
"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"

두루에디트 에서는 추가적으로 (DEFTP.DLL) 아래와 같이 더 많은 다양한 파일을 처리하도록 구현 하였다.

아래는 두루에디트 FTP 소스일부로 AUTO 모드 처리로직의 소스이다.
(참고로 본 블로그에서 오픈된 소스는 누구든지 복사,퍼가서 활용하는것을 허용합니다,단,본인의 저작물에 한함)

/* FtpDataCmd() mode codes */
enum DFFileMode
{
 PFMOD_AUTO = '0',
 PFMOD_ASCII = 'A',
 PFMOD_BINARY= 'I'
};

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;
}

아래는 파일질라 측에서 설명한 데이타 타입에 관한(RFC를 근거로) 처리를 하는 방침이다.

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.