The detial see the diff~~ And using this patch, the problem will be slove, and the charset can auto change.. http://www.teatime.com.tw/~tommy/linux/gftp_remote_charsets.patch Thanks~ |
diff -Nur gftp-2.0.18/lib/local.c gftp-2.0.18.patched/lib/local.c --- gftp-2.0.18/lib/local.c 2005-02-02 09:24:51.000000000 +0800 +++ gftp-2.0.18.patched/lib/local.c 2005-02-28 14:41:00.000000000 +0800 @@ -26,6 +26,18 @@ GHashTable *userhash, *grouphash; } local_protocol_data; +static char * +_local_force_to_utf8(gftp_request * request, const char *name) +{ + char *utf8_name; + + if (name == NULL) return NULL; + + if (g_utf8_validate (name, -1, NULL)) return g_strdup(name); + utf8_name = gftp_string_to_utf8 (request, name); + if (utf8_name == NULL) return g_strdup(name); + return utf8_name; +} static void local_remove_key (gpointer key, gpointer value, gpointer user_data) @@ -112,6 +124,7 @@ { off_t size; int flags; + char *utf8_name; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); @@ -124,8 +137,15 @@ flags |= O_LARGEFILE; #endif - if ((request->datafd = gftp_fd_open (request, filename, flags, 0)) == -1) - return (GFTP_ERETRYABLE); + utf8_name = _local_force_to_utf8(request, filename); + if (utf8_name != NULL) { + request->datafd = gftp_fd_open (request, utf8_name, flags, 0); + g_free(utf8_name); + } + else + request->datafd = gftp_fd_open (request, filename, flags, 0); + if (request->datafd == -1) + return (GFTP_ERETRYABLE); } else request->datafd = fd; @@ -157,6 +177,7 @@ off_t startsize, off_t totalsize) { int flags; + char *utf8_name; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); @@ -171,8 +192,17 @@ flags |= O_LARGEFILE; #endif - if ((request->datafd = gftp_fd_open (request, filename, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) - return (GFTP_ERETRYABLE); + utf8_name = _local_force_to_utf8(request, filename); + if (utf8_name != NULL) { + request->datafd = gftp_fd_open (request, utf8_name, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + g_free(utf8_name); + } + else + request->datafd = gftp_fd_open (request, filename, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + if (request->datafd == -1) { + return (GFTP_ERETRYABLE); + } } else request->datafd = fd; @@ -185,7 +215,7 @@ gftp_disconnect (request); return (GFTP_ERETRYABLE); } - + if (lseek (request->datafd, startsize, SEEK_SET) == -1) { request->logging_function (gftp_logging_error, request, @@ -229,8 +259,17 @@ mode_t * mode) { struct stat st; + char *utf8_name; + int rc; - if (stat (filename, &st) != 0) + utf8_name = _local_force_to_utf8(request, filename); + if (utf8_name != NULL) { + rc = stat (utf8_name, &st); + g_free(utf8_name); + } + else + rc = stat (filename, &st); + if (rc != 0) return (GFTP_ERETRYABLE); *mode = st.st_mode; @@ -275,13 +314,13 @@ if (stat (fle->file, &fst) != 0) return (GFTP_ERETRYABLE); - if ((user = g_hash_table_lookup (lpd->userhash, + if ((user = g_hash_table_lookup (lpd->userhash, GUINT_TO_POINTER(st.st_uid))) != NULL) fle->user = g_strdup (user); else { if ((pw = getpwuid (st.st_uid)) == NULL) - fle->user = g_strdup_printf ("%u", st.st_uid); + fle->user = g_strdup_printf ("%u", st.st_uid); else fle->user = g_strdup (pw->pw_name); @@ -289,13 +328,13 @@ g_hash_table_insert (lpd->userhash, GUINT_TO_POINTER (st.st_uid), user); } - if ((group = g_hash_table_lookup (lpd->grouphash, + if ((group = g_hash_table_lookup (lpd->grouphash, GUINT_TO_POINTER(st.st_gid))) != NULL) fle->group = g_strdup (group); else { if ((gr = getgrgid (st.st_gid)) == NULL) - fle->group = g_strdup_printf ("%u", st.st_gid); + fle->group = g_strdup_printf ("%u", st.st_gid); else fle->group = g_strdup (gr->gr_name); @@ -358,12 +397,21 @@ } -static off_t +static off_t local_get_file_size (gftp_request * request, const char *filename) { struct stat st; + char *utf8_name; + int rc; - if (stat (filename, &st) == -1) + utf8_name = _local_force_to_utf8(request, filename); + if (utf8_name != NULL) { + rc = stat (utf8_name, &st); + g_free(utf8_name); + } + else + rc = stat (filename, &st); + if (rc != 0) return (GFTP_ERETRYABLE); return (st.st_size); } @@ -373,24 +421,34 @@ local_chdir (gftp_request * request, const char *directory) { char tempstr[255]; + char *utf8_name; + int need_free; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (directory != NULL, GFTP_EFATAL); - if (chdir (directory) == 0) + need_free = 0; + utf8_name = _local_force_to_utf8(request, directory); + if (utf8_name != NULL) + need_free = 1; + else + utf8_name = directory; + + if (chdir (utf8_name) == 0) { request->logging_function (gftp_logging_misc, request, _("Successfully changed local directory to %s\n"), - directory); + utf8_name); - if (request->directory != directory) + if (request->directory != utf8_name) { if (getcwd (tempstr, sizeof (tempstr)) == NULL) { request->logging_function (gftp_logging_error, request, _("Could not get current working directory: %s\n"), g_strerror (errno)); + if (need_free) g_free(utf8_name); return (GFTP_ERETRYABLE); } @@ -399,13 +457,15 @@ request->directory = g_strdup (tempstr); } + if (need_free) g_free(utf8_name); return (0); } else { request->logging_function (gftp_logging_error, request, _("Could not change local directory to %s: %s\n"), - directory, g_strerror (errno)); + utf8_name, g_strerror (errno)); + if (need_free) g_free(utf8_name); return (GFTP_ERETRYABLE); } } @@ -414,11 +474,22 @@ static int local_rmdir (gftp_request * request, const char *directory) { + char *utf8_name; + int rc; + g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (directory != NULL, GFTP_EFATAL); - if (rmdir (directory) == 0) + utf8_name = _local_force_to_utf8(request, directory); + if (utf8_name != NULL) { + rc = rmdir (utf8_name); + g_free(utf8_name); + } + else + rc = rmdir (directory); + + if (rc == 0) { request->logging_function (gftp_logging_misc, request, _("Successfully removed %s\n"), directory); @@ -437,11 +508,21 @@ static int local_rmfile (gftp_request * request, const char *file) { + char *utf8_name; + int rc; + g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (file != NULL, GFTP_EFATAL); - if (unlink (file) == 0) + utf8_name = _local_force_to_utf8(request, file); + if (utf8_name != NULL) { + rc = unlink (utf8_name); + g_free(utf8_name); + } + else + rc = unlink (file); + if (rc == 0) { request->logging_function (gftp_logging_misc, request, _("Successfully removed %s\n"), file); @@ -460,11 +541,22 @@ static int local_mkdir (gftp_request * request, const char *directory) { + char *utf8_name; + int rc; + g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (directory != NULL, GFTP_EFATAL); - if (mkdir (directory, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) + utf8_name = _local_force_to_utf8(request, directory); + if (utf8_name != NULL) { + rc = mkdir (utf8_name, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + g_free(utf8_name); + } + else + rc = mkdir (directory, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + if (rc == 0) { request->logging_function (gftp_logging_misc, request, _("Successfully made directory %s\n"), @@ -485,12 +577,39 @@ local_rename (gftp_request * request, const char *oldname, const char *newname) { + char *utf8_oldname, *utf8_newname; + int rc; + g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); g_return_val_if_fail (newname != NULL, GFTP_EFATAL); - if (rename (oldname, newname) == 0) + utf8_oldname = _local_force_to_utf8(request, oldname); + utf8_newname = _local_force_to_utf8(request, newname); + + if (utf8_oldname != NULL) { + if (utf8_newname != NULL) { + rc = rename (utf8_oldname, utf8_newname); + g_free(utf8_oldname); + g_free(utf8_newname); + } + else { + rc = rename (utf8_oldname, newname); + g_free(utf8_oldname); + } + } + else { + if (utf8_newname != NULL) { + rc = rename (oldname, utf8_newname); + g_free(utf8_newname); + } + else { + rc = rename (oldname, newname); + } + } + + if (rc == 0) { request->logging_function (gftp_logging_misc, request, _("Successfully renamed %s to %s\n"), @@ -510,20 +629,30 @@ static int local_chmod (gftp_request * request, const char *file, mode_t mode) { + char *utf8_name; + int rc; + g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (file != NULL, GFTP_EFATAL); - if (chmod (file, mode) == 0) + utf8_name = _local_force_to_utf8(request, file); + if (utf8_name != NULL) { + rc = chmod (utf8_name, mode); + g_free(utf8_name); + } + else + rc = chmod (file, mode); + if (rc == 0) { - request->logging_function (gftp_logging_misc, request, + request->logging_function (gftp_logging_misc, request, _("Successfully changed mode of %s to %o\n"), file, mode); return (0); } - else + else { - request->logging_function (gftp_logging_error, request, + request->logging_function (gftp_logging_error, request, _("Error: Could not change mode of %s to %o: %s\n"), file, mode, g_strerror (errno)); return (GFTP_ERETRYABLE); @@ -536,6 +665,8 @@ time_t datetime) { struct utimbuf time_buf; + char *utf8_name; + int rc; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); @@ -543,7 +674,16 @@ time_buf.modtime = datetime; time_buf.actime = datetime; - return (utime (file, &time_buf) == 0 ? 0 : GFTP_ERETRYABLE); + + utf8_name = _local_force_to_utf8(request, file); + if (utf8_name != NULL) { + rc = utime (utf8_name, &time_buf); + g_free(utf8_name); + } + else + rc = utime (file, &time_buf); + + return (rc == 0 ? 0 : GFTP_ERETRYABLE); } @@ -561,7 +701,7 @@ } -void +void local_register_module (void) { } diff -Nur gftp-2.0.18/lib/protocols.c gftp-2.0.18.patched/lib/protocols.c --- gftp-2.0.18/lib/protocols.c 2005-01-25 10:34:18.000000000 +0800 +++ gftp-2.0.18.patched/lib/protocols.c 2005-02-28 13:51:54.000000000 +0800 @@ -450,11 +450,16 @@ { ret = g_convert_with_iconv (str, -1, request->iconv, &bread, &bwrite, &error); - if (ret == NULL) - printf (_("Error converting string '%s' from character set %s to character set %s: %s\n"), - str, _("<unknown>"), "UTF-8", error->message); - - return (ret); + if (ret == NULL) { +// printf (_("Error converting string '%s' from character set %s to character set %s: %s\n"), +// str, _("<unknown>"), "UTF-8", error->message); + g_iconv_close (request->iconv); + request->iconv = NULL; + request->iconv_initialized = 0; + } + else { + return (ret); + } } gftp_lookup_request_option (request, "remote_charsets", &tempstr); @@ -521,11 +526,16 @@ { ret = g_convert_with_iconv (str, -1, request->iconv, &bread, &bwrite, &error); - if (ret == NULL) - printf (_("Error converting string '%s' from character set %s to character set %s: %s\n"), - str, "UTF-8", _("<unknown>"), error->message); - - return (ret); + if (ret == NULL) { +// printf (_("Error converting string '%s' from character set %s to character set %s: %s\n"), +// str, "UTF-8", _("<unknown>"), error->message); + g_iconv_close (request->iconv); + request->iconv = NULL; + request->iconv_initialized = 0; + } + else { + return (ret); + } } gftp_lookup_request_option (request, "remote_charsets", &tempstr); @@ -597,6 +607,7 @@ { char *slashpos, *newfile; int fd, ret; + int rc; g_return_val_if_fail (request != NULL, GFTP_EFATAL); @@ -650,7 +661,10 @@ request->cachefd = -1; } } - } while (ret > 0 && !gftp_match_filespec (fle->file, filespec)); + rc = gftp_match_filespec(fle->file, filespec); + if (rc == 0 && fle->utf8_file != NULL) + rc = gftp_match_filespec(fle->utf8_file, filespec); + } while (ret > 0 && !rc); return (ret); } diff -Nur gftp-2.0.18/src/uicommon/gftpuicallbacks.c gftp-2.0.18.patched/src/uicommon/gftpuicallbacks.c --- gftp-2.0.18/src/uicommon/gftpuicallbacks.c 2005-01-04 21:32:16.000000000 +0800 +++ gftp-2.0.18.patched/src/uicommon/gftpuicallbacks.c 2005-02-28 13:52:31.000000000 +0800 @@ -79,9 +79,20 @@ { if (cdata->source_string == NULL) matched_filespec = 1; - else + else { matched_filespec = gftp_match_filespec (fle->file, cdata->source_string); + if (matched_filespec == 0) { + char *remote_file; + + remote_file = gftp_string_to_utf8 (cdata->request, fle->file); + if (remote_file != NULL) { + matched_filespec = gftp_match_filespec (remote_file, + cdata->source_string); + g_free(remote_file); + } + } + } if (got < 0 || strcmp (fle->file, ".") == 0 || !matched_filespec) {