Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

讓 FileZilla3 的 sftp 支援 UTF-8 編碼
post by tommy @ 18 十月, 2006 13:48
FileZilla3 目前正在 beta 階段, 而上頭的 sftp 與 2.x 的官方版本一樣, 並不支援 UTF-8 的使用. 所以參考之前為 2.x 版所做的修正, 幫 FileZilla3 的 sftp 也加上 UTF-8 的支援.

由於 FileZilla3 在 Windows 下頭, 改用 MinGW 來編譯 (在我的 X31 上頭跑起來, 還真是很慢... 看來真的要換機器用了), 且預設的環境都是 UNICODE, 不像 2.x 版, 在 putty 的部份仍使用 ANSI. 所以整個修正並不像 2.x 版那麼大. 只要改幾個小地方就可以支援 UTF-8 了.

diff -Nur src.orig/engine/sftpcontrolsocket.cpp src/engine/sftpcontrolsocket.cpp
--- src.orig/engine/sftpcontrolsocket.cpp Wed Oct 18 02:17:44 2006
+++ src/engine/sftpcontrolsocket.cpp Wed Oct 18 11:25:19 2006
@@ -264,6 +264,8 @@
LogMessage(Status, _("Connecting to %s:%d..."), server.GetHost().c_str(), server.GetPort());
SetWait(true);

+ if (server.GetEncodingType() == ENCODING_UTF8)
+ m_useUTF8 = true;
if (m_pCurrentServer)
delete m_pCurrentServer;
m_pCurrentServer = new CServer(server);
@@ -277,7 +279,7 @@
if (executable == _T(""))
executable = _T("fzsftp");

- m_pid = wxExecute(executable + _T(" -v"), wxEXEC_ASYNC, m_pProcess);
+ m_pid = wxExecute(executable + _T(" -v") + (m_useUTF8 ? _T(" -utf8") : _T("")), wxEXEC_ASYNC, m_pProcess);
if (!m_pid)
{
delete m_pProcess;
@@ -481,7 +483,7 @@

cmd += _T("\n");

- const wxCharBuffer str = cmd.mb_str();
+ const wxCharBuffer str = m_useUTF8 ? cmd.mb_str(wxConvUTF8) : cmd.mb_str();
if (!m_pProcess)
return false;

@@ -862,7 +864,7 @@
return FZ_REPLY_INTERNALERROR;
}

- wxCharBuffer str = entry.mb_str();
+ wxCharBuffer str = m_useUTF8 ? entry.mb_str(wxConvUTF8) : entry.mb_str();
int len = strlen(str);
char* buffer = new char[len + 1];
strcpy(buffer, str);
diff -Nur src.orig/putty/fzsftp.c src/putty/fzsftp.c
--- src.orig/putty/fzsftp.c Sun Mar 19 20:09:52 2006
+++ src/putty/fzsftp.c Wed Oct 18 11:25:19 2006
@@ -1,6 +1,8 @@
#include "putty.h"
#include "misc.h"

+int gnFzUseUTF8 = 0; // use UTF8 enooding or not
+
int fznotify(sftpEventTypes type)
{
fprintf(stdout, "%c", (int)type + '0');
diff -Nur src.orig/putty/fzsftp.h src/putty/fzsftp.h
--- src.orig/putty/fzsftp.h Sun Mar 19 20:09:52 2006
+++ src/putty/fzsftp.h Wed Oct 18 11:25:19 2006
@@ -25,6 +25,8 @@
sftpReqUnknown
};

+extern int gnFzUseUTF8; // use UTF8 encoding or not
+
int fznotify(sftpEventTypes type);
int fzprintf(sftpEventTypes type, const char* p, ...);
int fzprintf_raw(sftpEventTypes type, const char* p, ...);
diff -Nur src.orig/putty/psftp.c src/putty/psftp.c
--- src.orig/putty/psftp.c Tue Oct 17 23:36:42 2006
+++ src/putty/psftp.c Wed Oct 18 11:25:19 2006
@@ -2907,6 +2907,8 @@
} else if (strcmp(argv[i], "--") == 0) {
i++;
break;
+ } else if (strcmp(argv[i], "-utf8") == 0) {
+ gnFzUseUTF8 = 1;
} else {
cmdline_error("unknown option \"%s\"", argv[i]);
}
diff -Nur src.orig/putty/windows/winsftp.c src/putty/windows/winsftp.c
--- src.orig/putty/windows/winsftp.c Sat Oct 7 19:39:33 2006
+++ src/putty/windows/winsftp.c Wed Oct 18 11:25:19 2006
@@ -77,8 +77,30 @@
HANDLE h;
RFile *ret;

- h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, 0, 0);
+ if (gnFzUseUTF8) {
+ int len;
+
+ // convert from UTF-8 to UNICODE
+ len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, NULL, 0);
+ if (len != 0)
+ {
+ wchar_t *p1;
+
+ p1 = malloc(sizeof(wchar_t) * (len*2+1));
+ MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1 , (LPWSTR)p1, len*2);
+ h = CreateFileW(p1, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, 0);
+ free(p1);
+ }
+ else {
+ h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, 0);
+ }
+ }
+ else {
+ h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, 0);
+ }
if (h == INVALID_HANDLE_VALUE)
return NULL;

@@ -125,8 +147,30 @@
HANDLE h;
WFile *ret;

- h = CreateFile(name, GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (gnFzUseUTF8) {
+ int len;
+
+ // convert from UTF-8 to UNICODE
+ len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, NULL, 0);
+ if (len != 0)
+ {
+ wchar_t *p1;
+
+ p1 = malloc(sizeof(wchar_t) * (len*2+1));
+ MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1 , (LPWSTR)p1, len*2);
+ h = CreateFileW(p1, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ free(p1);
+ }
+ else {
+ h = CreateFile(name, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ }
+ }
+ else {
+ h = CreateFile(name, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ }
if (h == INVALID_HANDLE_VALUE)
return NULL;

@@ -141,8 +185,30 @@
HANDLE h;
WFile *ret;

- h = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, 0, 0);
+ if (gnFzUseUTF8) {
+ int len;
+
+ // convert from UTF-8 to UNICODE
+ len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, NULL, 0);
+ if (len != 0)
+ {
+ wchar_t *p1;
+
+ p1 = malloc(sizeof(wchar_t) * (len*2+1));
+ MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1 , (LPWSTR)p1, len*2);
+ h = CreateFileW(p1, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, 0);
+ free(p1);
+ }
+ else {
+ h = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, 0);
+ }
+ }
+ else {
+ h = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, 0);
+ }
if (h == INVALID_HANDLE_VALUE)
return NULL;

@@ -223,7 +289,27 @@
int file_type(char *name)
{
DWORD attr;
- attr = GetFileAttributes(name);
+ if (gnFzUseUTF8) {
+ int len;
+
+ // convert from UTF-8 to UNICODE
+ len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, NULL, 0);
+ if (len != 0)
+ {
+ wchar_t *p1;
+
+ p1 = malloc(sizeof(wchar_t) * (len*2+1));
+ MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1 , (LPWSTR)p1, len*2);
+ attr = GetFileAttributesW(name);
+ free(p1);
+ }
+ else {
+ attr = GetFileAttributes(name);
+ }
+ }
+ else {
+ attr = GetFileAttributes(name);
+ }
/* We know of no `weird' files under Windows. */
if (attr == (DWORD)-1)
return FILE_TYPE_NONEXISTENT;
 

這個 patch 可以到這兒抓: http://www.teatime.com.tw/~tommy/mypatch/filezilla3_beta2_sftp_utf8.patch

由於 beta2 的版本, 在目錄建立上頭仍有些問題, 所以上下傳整個目錄與子目錄的功能並沒有作用, 所以我也沒測這部份, 不知道是否能正常運作. 不過一般上下傳檔案, 更改檔案名稱, 更改屬性, 刪除檔案, 建立目錄, 更改目錄名稱, 更改目錄屬性, 刪除目錄等功能都可以正常使用 UTF-8.

因為整個目錄上下傳會有無法建立目錄的情形 (與 UTF-8 無關), 所以就沒有放執行檔上來. 如果有需要, 可以自己製造一個出來吧.

由於整個 patch 不像 2.x 那麼大, 我想作者應該不會像 2.x 的版本一樣, 拒絕把這個加到官方的版本中. 希望作者能接受這個 patch, 到時就不用每出一版就要自己 patch 一次.

patch submit 在這兒.


剛剛自己修正了無法上下傳目錄的問題, 所以順便把程式打包一下, 如果有需要, 可以抓下頭的檔案回去測試.

http://www.teatime.com.tw/~tommy/filezilla3_beta2_sftp_utf8.7z

不過.... 記住, 這是 beta 版, 看來問題還不少的樣子.

Del.icio.us Furl HEMiDEMi Technorati MyShare
迴響
暱稱:
標題:
個人網頁:
電子郵件:
迴響

  

Bad Behavior 已經阻擋了 123 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS