changeset 988:63555c9744c2

remote charset should be specified by each bookmark entry.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Fri, 14 Aug 2009 07:54:55 +0900
parents 2f6924c67846
children c99b134c6185
files lib/charset-conv.c lib/config_file.c lib/gftp.h lib/misc.c lib/options.h lib/protocols.c lib/rfc959.c lib/sshv2.c src/gtk/bookmarks.c src/gtk/gftp-gtk.c src/gtk/options_dialog.c
diffstat 11 files changed, 203 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/lib/charset-conv.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/charset-conv.c	Fri Aug 14 07:54:55 2009 +0900
@@ -74,12 +74,12 @@
           str, fromset, toset, error->message);
 }
 
-
 /*@null@*/ static char *
 _do_convert_string (gftp_request * request, int is_filename, int force_local,
                     const char *str, size_t *dest_len, int from_utf8)
 {
-  char *remote_charsets, *ret, *fromset, *toset, *stpos, *cur_charset;
+  char *remote_charset = NULL, *default_charset = NULL, *ret, *fromset,
+      *toset, *stpos, *cur_charset;
   GError * error;
   gsize bread;
 
@@ -90,8 +90,14 @@
     return (NULL);
 
   error = NULL;
-  gftp_lookup_request_option (request, "remote_charsets", &remote_charsets);
-  if (*remote_charsets == '\0' || request->use_local_encoding ||
+//  gftp_lookup_request_option (request, "remote_charset", &remote_charset);
+  remote_charset = request->remote_charset;
+  gftp_lookup_global_option ("default_charset", &default_charset);
+  if(!remote_charset)
+      remote_charset = (default_charset && *default_charset != '\0')
+          ? default_charset : "UTF8";
+
+  if (*remote_charset == '\0' || request->use_local_encoding ||
       force_local == 1)
     {
       if (from_utf8)
@@ -140,7 +146,7 @@
         }
     }
 
-  stpos = remote_charsets;
+  stpos = remote_charset;
   while ((cur_charset = _gftp_get_next_charset (&stpos)) != NULL)
     {
       if (from_utf8)
@@ -197,6 +203,7 @@
   return (NULL);
 }
 
+
 char *
 gftp_string_to_utf8 (gftp_request * request, const char *str, size_t *dest_len)
 {
@@ -227,6 +234,57 @@
   return (_do_convert_string (request, 1, 0, str, dest_len, 1));
 }
 
+
+char *
+gftp_remote_filename_to_utf8 (gftp_request * request, const char *str,
+                       size_t *dest_len)
+{
+    char *remote_charset = NULL, *default_charset = NULL;
+    GError *error = NULL;
+    gchar *ret = NULL;
+
+    if(request == NULL)
+        return (NULL);
+
+    /* get remote_charset */
+//    gftp_lookup_request_option (request, "remote_charset", &remote_charset);
+    remote_charset = request->remote_charset;
+    gftp_lookup_global_option ("default_charset", &default_charset);
+    if(!remote_charset)
+       remote_charset = (default_charset && *default_charset != '\0')
+           ? default_charset : "UTF8";
+
+    ret = g_convert(str, -1, "UTF8", remote_charset, NULL, dest_len, error);
+    return ret;
+}
+
+
+char *
+gftp_remote_filename_from_utf8 (gftp_request *request, const char *str,
+                         size_t *dest_len)
+{
+    char *remote_charset = NULL, *default_charset = NULL;
+    GError *error = NULL;
+    gchar *ret = NULL;
+
+    if(request == NULL)
+        return (NULL);
+
+    if(!g_utf8_validate (str, -1, NULL))
+        return (NULL);
+
+    /* get remote_charset */
+//    gftp_lookup_request_option (request, "remote_charset", &remote_charset);
+    remote_charset = request->remote_charset;
+    gftp_lookup_global_option ("default_charset", &default_charset);
+    if(!remote_charset)
+        remote_charset = (default_charset && *default_charset != '\0')
+            ? default_charset : "UTF8";
+
+    ret = g_convert(str, -1, remote_charset, "UTF8", NULL, dest_len, error);
+    return ret;
+}
+
 #else
 
 char *
@@ -258,6 +316,20 @@
   return (NULL);
 }
 
+char *
+gftp_remote_filename_to_utf8 (gftp_request * request, const char *str, size_t dest_len)
+{
+  return (NULL);
+}
+
+
+char *
+gftp_remote_filename_from_utf8 (gftp_request * request, int force_local,
+                         const char *str, size_t dest_len)
+{
+  return (NULL);
+}
+
 #endif
 
 
--- a/lib/config_file.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/config_file.c	Fri Aug 14 07:54:55 2009 +0900
@@ -255,6 +255,13 @@
 	    g_free (newentry->local_dir);
 	  newentry->local_dir = g_strdup (curpos);
 	}
+      else if (strncmp (buf, "remote_charset", 14) == 0 && newentry)
+	{
+	  curpos = buf + 15;
+	  if (newentry->remote_charset)
+	    g_free (newentry->remote_charset);
+	  newentry->remote_charset = g_strdup (curpos);
+	}
       else if (strncmp (buf, "username", 8) == 0 && newentry)
 	{
 	  curpos = buf + 9;
@@ -776,13 +783,14 @@
             password = NULL;
 
           fprintf (bmfile,
-    	       "[%s]\nhostname=%s\nport=%u\nprotocol=%s\nremote directory=%s\nlocal directory=%s\nusername=%s\npassword=%s\naccount=%s\n",
+    	       "[%s]\nhostname=%s\nport=%u\nprotocol=%s\nremote directory=%s\nlocal directory=%s\nremote_charset=%s\nusername=%s\npassword=%s\naccount=%s\n",
     	       tempstr, tempentry->hostname == NULL ? "" : tempentry->hostname,
     	       tempentry->port, tempentry->protocol == NULL
     	       || *tempentry->protocol ==
     	       '\0' ? gftp_protocols[0].name : tempentry->protocol,
     	       tempentry->remote_dir == NULL ? "" : tempentry->remote_dir,
     	       tempentry->local_dir == NULL ? "" : tempentry->local_dir,
+    	       tempentry->remote_charset == NULL ? "" : tempentry->remote_charset,
     	       tempentry->user == NULL ? "" : tempentry->user,
     	       password == NULL ? "" : password,
     	       tempentry->acct == NULL ? "" : tempentry->acct);
@@ -1281,14 +1289,18 @@
       (tmpconfigvar = g_hash_table_lookup (gftp_global_options_htable,
                                            key)) != NULL)
     memcpy (value, &tmpconfigvar->value, sizeof (value));
-  else if ((tmplistvar = g_hash_table_lookup (gftp_config_list_htable, 
+  else if ((tmplistvar = g_hash_table_lookup (gftp_config_list_htable,
                                               key)) != NULL)
     *(gftp_config_list_vars **) value = tmplistvar;
   else
+#if 0
     {
       fprintf (stderr, _("FATAL gFTP Error: Config option '%s' not found in global hash table\n"), key);
       exit (EXIT_FAILURE);
     }
+#else
+  value = NULL;
+#endif
 }
 
 
--- a/lib/gftp.h	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/gftp.h	Fri Aug 14 07:54:55 2009 +0900
@@ -92,9 +92,9 @@
 #include <openssl/x509v3.h>
 #endif
 
+#include <locale.h>
 #ifdef ENABLE_NLS
 #include <libintl.h>
-#include <locale.h>
 #define _(String) gettext (String)
 #else 
 #define _(String) String
@@ -312,6 +312,7 @@
 #define GFTP_CVARS_FLAGS_DYNMEM			(1 << 1)
 #define GFTP_CVARS_FLAGS_DYNLISTMEM		(1 << 2)
 #define GFTP_CVARS_FLAGS_SHOW_BOOKMARK		(1 << 3)
+#define GFTP_CVARS_FLAGS_SHOW_BOOKMARK_ONLY		(1 << 4)
 
 typedef struct gftp_config_vars_tag
 {
@@ -500,6 +501,7 @@
                iconv_to_initialized : 1;
   char *iconv_charset;
 #endif
+  char *remote_charset;
 };
 
 
@@ -595,10 +597,11 @@
                isfolder : 1,   /* If this is set, then the children field can
                                   be non-NULL */
                save_password : 1; /* Save this password */
+  char *remote_charset;
   gftp_bookmarks_var *children, /* The children of this node. */
                      *prev, 	/* The parent of this node */
                      *next; 	/* The next sibling of this node */
-  gpointer cnode; 
+  gpointer cnode;
 
   gftp_config_vars * local_options_vars;
   int num_local_options_vars;
@@ -684,6 +687,14 @@
 					  const char *str,
 					  size_t *dest_len );
 
+/*@null@*/ char * gftp_remote_filename_to_utf8	( gftp_request * request, 
+					  const char *str,
+					  size_t *dest_len );
+
+/*@null@*/ char * gftp_remote_filename_from_utf8 ( gftp_request * request, 
+					  const char *str,
+					  size_t *dest_len );
+
 /* config_file.c */
 int gftp_config_parse_args 		( char *str, 
 					  int numargs, 
@@ -958,6 +969,9 @@
 void gftp_set_hostname 			( gftp_request * request, 
 					  const char *hostname );
 
+void gftp_set_remote_charset     (gftp_request * request,
+                                  const char *remote_charset);
+
 void gftp_set_username 			( gftp_request * request, 
 					  const char *username );
 
--- a/lib/misc.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/misc.c	Fri Aug 14 07:54:55 2009 +0900
@@ -596,6 +596,9 @@
     newreq->directory = g_strdup (req->directory);
   if (req->url_prefix)
     newreq->url_prefix = g_strdup (req->url_prefix);
+  if (req->remote_charset)
+    newreq->remote_charset = g_strdup (req->remote_charset);
+
   newreq->port = req->port;
   newreq->use_proxy = req->use_proxy;
   newreq->logging_function = req->logging_function;
@@ -1166,9 +1169,9 @@
 void
 gftp_locale_init (void)
 {
-#ifdef HAVE_GETTEXT
+  setlocale (LC_ALL, "");
 
-  setlocale (LC_ALL, "");
+#ifdef HAVE_GETTEXT
   textdomain ("gftp");
   bindtextdomain ("gftp", LOCALE_DIR);
 
--- a/lib/options.h	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/options.h	Fri Aug 14 07:54:55 2009 +0900
@@ -49,10 +49,20 @@
    gftp_option_type_int, 0, NULL, 0, 
    N_("The maximum size of the log window in bytes for the GTK+ port"), 
    GFTP_PORT_GTK, NULL},
-  {"remote_charsets", N_("Remote Character Sets:"), 
+
+  /* charsets */
+  {"default_charset", N_("Default Character Set:"),
+   gftp_option_type_text, "", NULL, 0,
+   N_("This is the default charset to try to convert the remote messages to the current locale"),
+   GFTP_PORT_ALL, NULL},
+
+#if 0
+  {"remote_charset", N_("Remote Character Set:"),
    gftp_option_type_text, "", NULL, GFTP_CVARS_FLAGS_SHOW_BOOKMARK,
-   N_("This is a comma separated list of charsets to try to convert the remote messages to the current locale"), 
+   N_("This is the site specific charset to try to convert the remote messages to the current locale"),
    GFTP_PORT_ALL, NULL},
+#endif
+
   {"remote_lc_time", N_("Remote LC_TIME:"), 
    gftp_option_type_text, "", NULL, GFTP_CVARS_FLAGS_SHOW_BOOKMARK,
    N_("This is the value of LC_TIME for the remote site. This is so that dates can be parsed properly in the directory listings."), 
--- a/lib/protocols.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/protocols.c	Fri Aug 14 07:54:55 2009 +0900
@@ -545,6 +545,9 @@
   gftp_set_directory (request, tempentry->remote_dir);
   gftp_set_port (request, tempentry->port);
 
+  /* charset */
+  gftp_set_remote_charset (request, tempentry->remote_charset);
+
   if (local_request != NULL && tempentry->local_dir != NULL &&
       *tempentry->local_dir != '\0')
     {
@@ -749,6 +752,16 @@
   request->hostname = g_strdup (hostname);
 }
 
+void
+gftp_set_remote_charset(gftp_request * request, const char *remote_charset)
+{
+  g_return_if_fail (request != NULL);
+  g_return_if_fail (remote_charset != NULL);
+
+  if (request->remote_charset)
+    g_free (request->remote_charset);
+  request->remote_charset = g_strdup (remote_charset);
+}
 
 void
 gftp_set_username (gftp_request * request, const char *username)
--- a/lib/rfc959.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/rfc959.c	Fri Aug 14 07:54:55 2009 +0900
@@ -44,6 +44,15 @@
    gftp_option_type_text, "", NULL, GFTP_CVARS_FLAGS_SHOW_BOOKMARK,
    N_("This is the password that will be used whenever you log into a remote FTP server as anonymous"), 
    GFTP_PORT_ALL, NULL},
+
+  /* charset */
+#if 0
+  {"remote_charset", N_("Remote Character Set:"),
+   gftp_option_type_text, "", NULL, GFTP_CVARS_FLAGS_SHOW_BOOKMARK_ONLY,
+   N_("This is the site specific charset"),
+   GFTP_PORT_ALL, NULL},
+#endif
+
   {"ftp_proxy_host", N_("Proxy hostname:"), 
    gftp_option_type_text, "", NULL, 0,
    N_("Firewall hostname"), GFTP_PORT_ALL, NULL},
@@ -212,7 +221,7 @@
 
   if (argument != NULL)
     {
-      utf8 = gftp_filename_from_utf8 (request, argument, &len);
+      utf8 = gftp_remote_filename_from_utf8 (request, argument, &len);
       if (utf8 != NULL)
         {
           tempstr = g_strconcat (command, " ", utf8, "\r\n", NULL);
@@ -1718,7 +1727,7 @@
   g_return_val_if_fail (file != NULL, GFTP_EFATAL);
   g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL);
 
-  utf8 = gftp_filename_from_utf8 (request, file, &destlen);
+  utf8 = gftp_remote_filename_from_utf8 (request, file, &destlen);
   if (utf8 != NULL)
     {
       tempstr = g_strdup_printf ("SITE CHMOD %o %s\r\n", mode, utf8);
--- a/lib/sshv2.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/lib/sshv2.c	Fri Aug 14 07:54:55 2009 +0900
@@ -35,6 +35,14 @@
    gftp_option_type_text, NULL, NULL, 0,  
    N_("Extra parameters to pass to the SSH program"), GFTP_PORT_ALL, NULL},
 
+  /* charset */
+#if 0
+  {"remote_charset", N_("Remote Character Set:"),
+   gftp_option_type_text, "", NULL, GFTP_CVARS_FLAGS_SHOW_BOOKMARK_ONLY,
+   N_("This is the site specific charset"),
+   GFTP_PORT_ALL, NULL},
+#endif
+
   {"ssh_need_userpass", N_("Need SSH User/Pass"), 
    gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 
    GFTP_CVARS_FLAGS_SHOW_BOOKMARK,
--- a/src/gtk/bookmarks.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/src/gtk/bookmarks.c	Fri Aug 14 07:54:55 2009 +0900
@@ -22,8 +22,9 @@
 
 static GtkWidget * bm_dialog = NULL, * edit_bookmarks_dialog = NULL;
 static GtkWidget * bm_hostedit, * bm_portedit, * bm_localdiredit,
-                 * bm_remotediredit, * bm_useredit, * bm_passedit, * tree,
-                 * bm_acctedit, * anon_chk, * bm_pathedit, * bm_protocol;
+    * bm_remotediredit, * bm_useredit, * bm_passedit, * tree,
+    * bm_acctedit, * anon_chk, * bm_pathedit, * bm_protocol,
+    * bm_charsetedit;
 static GHashTable * new_bookmarks_htable = NULL;
 static gftp_bookmarks_var * new_bookmarks = NULL;
 static GtkItemFactory * edit_factory;
@@ -217,6 +218,9 @@
       if (tempentry->remote_dir)
 	newentry->remote_dir = g_strdup (tempentry->remote_dir);
 
+      if (tempentry->remote_charset)
+	newentry->remote_charset = g_strdup (tempentry->remote_charset);
+
       if (tempentry->user)
 	newentry->user = g_strdup (tempentry->user);
 
@@ -715,6 +719,13 @@
     g_free (entry->local_dir);
   entry->local_dir = g_strdup (str);
 
+  /* charset */
+  str = gtk_entry_get_text (GTK_ENTRY (bm_charsetedit));
+  if (entry->remote_charset != NULL)
+    g_free (entry->remote_charset);
+  entry->remote_charset = g_strdup (str);
+
+  /* user */
   if (GTK_TOGGLE_BUTTON (anon_chk)->active)
     str = GFTP_ANONYMOUS_USER;
   else
@@ -825,7 +836,7 @@
 edit_entry (gpointer data)
 {
   GtkWidget * table, * tempwid, * menu, * notebook;
-  gftp_bookmarks_var * entry;
+  volatile gftp_bookmarks_var * entry;
   unsigned int num, i;
   char *pos;
 
@@ -980,17 +991,34 @@
     gtk_entry_set_text (GTK_ENTRY (bm_localdiredit), entry->local_dir);
   gtk_widget_show (bm_localdiredit);
 
-  tempwid = gtk_hseparator_new ();
-  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 2, 7, 8);
+  /* remote charset */
+  tempwid = gtk_label_new (_("Remote Charset:"));
+  gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
+  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 6, 7);
   gtk_widget_show (tempwid);
 
+  bm_charsetedit = gtk_entry_new ();
+  gtk_table_attach_defaults (GTK_TABLE (table), bm_charsetedit, 1, 2, 6, 7);
+  if (entry->isfolder)
+    gtk_widget_set_sensitive (bm_charsetedit, 0);
+  else if (entry->remote_charset) {
+    gtk_entry_set_text (GTK_ENTRY (bm_charsetedit), entry->remote_charset);
+  }
+  gtk_widget_show (bm_charsetedit);
+
+  /* separator line */
+  tempwid = gtk_hseparator_new ();
+  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 2, 8, 9);
+  gtk_widget_show (tempwid);
+
+  /* user name */
   tempwid = gtk_label_new (_("Username:"));
   gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
-  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 8, 9);
+  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 9, 10);
   gtk_widget_show (tempwid);
 
   bm_useredit = gtk_entry_new ();
-  gtk_table_attach_defaults (GTK_TABLE (table), bm_useredit, 1, 2, 8, 9);
+  gtk_table_attach_defaults (GTK_TABLE (table), bm_useredit, 1, 2, 9, 10);
   if (entry->isfolder)
     gtk_widget_set_sensitive (bm_useredit, 0);
   else if (entry->user)
@@ -999,11 +1027,11 @@
 
   tempwid = gtk_label_new (_("Password:"));
   gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
-  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 9, 10);
+  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 10, 11);
   gtk_widget_show (tempwid);
 
   bm_passedit = gtk_entry_new ();
-  gtk_table_attach_defaults (GTK_TABLE (table), bm_passedit, 1, 2, 9, 10);
+  gtk_table_attach_defaults (GTK_TABLE (table), bm_passedit, 1, 2, 10, 11);
   gtk_entry_set_visibility (GTK_ENTRY (bm_passedit), FALSE);
   if (entry->isfolder)
     gtk_widget_set_sensitive (bm_passedit, 0);
@@ -1013,11 +1041,11 @@
 
   tempwid = gtk_label_new (_("Account:"));
   gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
-  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 10, 11);
+  gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 11, 12);
   gtk_widget_show (tempwid);
 
   bm_acctedit = gtk_entry_new ();
-  gtk_table_attach_defaults (GTK_TABLE (table), bm_acctedit, 1, 2, 10, 11);
+  gtk_table_attach_defaults (GTK_TABLE (table), bm_acctedit, 1, 2, 11, 12);
   gtk_entry_set_visibility (GTK_ENTRY (bm_acctedit), FALSE);
   if (entry->isfolder)
     gtk_widget_set_sensitive (bm_acctedit, 0);
@@ -1026,7 +1054,7 @@
   gtk_widget_show (bm_acctedit);
 
   anon_chk = gtk_check_button_new_with_label (_("Log in as ANONYMOUS"));
-  gtk_table_attach_defaults (GTK_TABLE (table), anon_chk, 0, 2, 11, 12);
+  gtk_table_attach_defaults (GTK_TABLE (table), anon_chk, 0, 2, 12, 13);
   if (entry->isfolder)
     gtk_widget_set_sensitive (anon_chk, 0);
   else
--- a/src/gtk/gftp-gtk.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/src/gtk/gftp-gtk.c	Fri Aug 14 07:54:55 2009 +0900
@@ -1361,6 +1361,8 @@
 {
   GtkWidget *window, *ui;
 
+  g_thread_init (NULL);
+
   /* We override the read color functions because we are using a GdkColor 
      structures to store the color. If I put this in lib/config_file.c, then 
      the core library would be dependant on Gtk+ being present */
@@ -1370,8 +1372,6 @@
   gftpui_common_init (&argc, &argv, ftp_log);
   gftpui_common_child_process_done = 0;
 
-  g_thread_init (NULL);
-
 #if GTK_MAJOR_VERSION > 1
   gdk_threads_init();
 #endif
--- a/src/gtk/options_dialog.c	Wed Apr 08 11:07:35 2009 +0000
+++ b/src/gtk/options_dialog.c	Fri Aug 14 07:54:55 2009 +0900
@@ -1417,6 +1417,9 @@
           if (!(cv[i].ports_shown & GFTP_PORT_GTK))
             continue;
 
+          if ((cv[i].flags & GFTP_CVARS_FLAGS_SHOW_BOOKMARK_ONLY))
+            continue;
+
           if (gftp_option_types[cv[i].otype].ui_print_function == NULL)
             continue;
 
@@ -1495,7 +1498,8 @@
 
       for (i=0; cv[i].key != NULL; i++)
         {
-          if (!(cv[i].flags & GFTP_CVARS_FLAGS_SHOW_BOOKMARK))
+          if (!(cv[i].flags & GFTP_CVARS_FLAGS_SHOW_BOOKMARK) &&
+              !(cv[i].flags & GFTP_CVARS_FLAGS_SHOW_BOOKMARK_ONLY))
             continue;
 
           if (gftp_option_types[cv[i].otype].ui_print_function == NULL)