changeset 136:84b3e69807a2

2003-4-18 Brian Masney <masneyb@gftp.org> * lib/config_file.c lib/gftp.h - removed gftp_option_type_subtree, gftp_option_type_table and gftp_option_type_newtable * lib/config_file.c - implemented gftp_set_request_option() * lib/gftp.h lib/config_file.c - changed declaration of ui_print_function in struct gftp_option_type. Also added ui_save_function field to this structure * lib/gftp.h added local_options_vars num_local_options_vars variables to gftp_request * lib/local.c (local_set_directory) - small improvements to this function * lib/misc.c - added gftp_copy_local_options() * lib/options.h - fix declaration of General tab * lib/protocols.c - free local options * lib/rfc2068.c - check to see if we're connecting to a FTP site via proxy * lib/rfc959.c lib/protocols.c - changes for CRAY directory listings * src/gtk/gftp-gtk.h - added struct gftp_options_dialog_data and struct gftp_textcomboedt_widget_data * src/gtk/options_dialog.c - start to use new configuration interface * src/gtk/transfer.c - remove FIXME note. This is already in lib/gftp.h
author masneyb
date Fri, 18 Apr 2003 19:38:34 +0000
parents 0261e7b5346c
children 986b379fb5c3
files ChangeLog lib/config_file.c lib/gftp.h lib/local.c lib/misc.c lib/options.h lib/protocols.c lib/rfc2068.c lib/rfc959.c src/gtk/gftp-gtk.h src/gtk/options_dialog.c src/gtk/transfer.c
diffstat 12 files changed, 849 insertions(+), 586 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Apr 18 16:02:38 2003 +0000
+++ b/ChangeLog	Fri Apr 18 19:38:34 2003 +0000
@@ -1,3 +1,38 @@
+2003-4-18 Brian Masney <masneyb@gftp.org>
+	* lib/config_file.c lib/gftp.h - removed gftp_option_type_subtree,
+	gftp_option_type_table and gftp_option_type_newtable
+
+	* lib/config_file.c - implemented gftp_set_request_option()
+
+	* lib/gftp.h lib/config_file.c - changed declaration of
+	ui_print_function in struct gftp_option_type. Also added
+	ui_save_function field to this structure
+
+	* lib/gftp.h added local_options_vars num_local_options_vars variables
+	to gftp_request
+
+	* lib/local.c (local_set_directory) - small improvements to this
+	function
+
+	* lib/misc.c - added gftp_copy_local_options()
+
+	* lib/options.h - fix declaration of General tab
+
+	* lib/protocols.c - free local options
+
+	* lib/rfc2068.c - check to see if we're connecting to a FTP site via
+	proxy
+
+	* lib/rfc959.c lib/protocols.c - changes for CRAY directory listings
+
+	* src/gtk/gftp-gtk.h - added struct gftp_options_dialog_data and
+	struct gftp_textcomboedt_widget_data
+
+	* src/gtk/options_dialog.c - start to use new configuration interface
+
+	* src/gtk/transfer.c - remove FIXME note. This is already in
+	lib/gftp.h
+
 2003-4-13 Brian Masney <masneyb@gftp.org>
 	* lib/config_file.c - fixed float config type
 
@@ -693,7 +728,7 @@
 
 	* cvsclean - added this script
 
-	* *.[ch] - added $Id: ChangeLog,v 1.70 2003/04/14 01:07:34 masneyb Exp $ tags
+	* *.[ch] - added $Id: ChangeLog,v 1.71 2003/04/18 19:38:33 masneyb Exp $ tags
 
 	* debian/* - updated files from Debian maintainer
 
--- a/lib/config_file.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/config_file.c	Fri Apr 18 19:38:34 2003 +0000
@@ -437,9 +437,7 @@
 
   for (i=0; cvars[i].key != NULL; i++)
     {
-      if (cvars[i].otype == gftp_option_type_subtree)
-        gftp_setup_global_options (cvars[i].value);
-      else if (cvars[i].key != NULL && *cvars[i].key != '\0')
+      if (cvars[i].key != NULL && *cvars[i].key != '\0')
         g_hash_table_insert (gftp_global_options_htable, 
                              cvars[i].key, &cvars[i]);
     }
@@ -821,13 +819,21 @@
 static int
 gftp_config_file_read_text (char *str, gftp_config_vars * cv, int line)
 {
+  if (cv->flags & GFTP_CVARS_FLAGS_DYNMEM && cv->value != NULL)
+    g_free (cv->value);
+
   if (str != NULL)
     {
       cv->value = g_strdup (str);
+      cv->flags |= GFTP_CVARS_FLAGS_DYNMEM;
       return (0);
     }
   else
-    return (-1);
+    {
+      cv->value = NULL;
+      cv->flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
+      return (-1);
+    }
 }
 
 
@@ -922,6 +928,9 @@
   char *red, *green, *blue;
   gftp_color * color;
 
+  if (cv->flags & GFTP_CVARS_FLAGS_DYNMEM && cv->value != NULL)
+    g_free (cv->value);
+
   parse_args (str, 3, line, &red, &green, &blue);
 
   color = g_malloc (sizeof (*color));
@@ -933,6 +942,7 @@
   g_free (blue);
 
   cv->value = color;
+  cv->flags |= GFTP_CVARS_FLAGS_DYNMEM;
 
   return (0);
 }
@@ -1015,20 +1025,17 @@
 /* Note, the index numbers of this array must match up to the numbers in
    gftp_option_type_enum in gftp.h */
 gftp_option_type_var gftp_option_types[] = {
-  {gftp_config_file_read_text, gftp_config_file_write_text, NULL, NULL},
-  {gftp_config_file_read_textcombo, gftp_config_file_write_text, NULL, NULL},
-  {gftp_config_file_read_text, gftp_config_file_write_text, NULL, NULL},
-  {gftp_config_file_read_text, gftp_config_file_write_hidetext, NULL, NULL},
-  {gftp_config_file_read_int, gftp_config_file_write_int, NULL, NULL},
-  {gftp_config_file_read_checkbox, gftp_config_file_write_int, NULL, NULL},
-  {gftp_config_file_read_intcombo, gftp_config_file_write_intcombo, NULL, NULL},
-  {gftp_config_file_read_float, gftp_config_file_write_float, NULL, NULL},
-  {gftp_config_file_read_color, gftp_config_file_write_color, NULL, NULL},
-  {NULL, NULL, NULL, NULL},
-  {NULL, NULL, NULL, NULL},
-  {NULL, NULL, NULL, NULL},
-  {NULL, NULL, NULL, NULL},
-  {NULL, NULL, NULL, NULL}
+  {gftp_config_file_read_text, gftp_config_file_write_text, NULL, NULL, NULL},
+  {gftp_config_file_read_textcombo, gftp_config_file_write_text, NULL, NULL, NULL},
+  {gftp_config_file_read_text, gftp_config_file_write_text, NULL, NULL, NULL},
+  {gftp_config_file_read_text, gftp_config_file_write_hidetext, NULL, NULL, NULL},
+  {gftp_config_file_read_int, gftp_config_file_write_int, NULL, NULL, NULL},
+  {gftp_config_file_read_checkbox, gftp_config_file_write_int, NULL, NULL, NULL},
+  {gftp_config_file_read_intcombo, gftp_config_file_write_intcombo, NULL, NULL, NULL},
+  {gftp_config_file_read_float, gftp_config_file_write_float, NULL, NULL, NULL},
+  {gftp_config_file_read_color, gftp_config_file_write_color, NULL, NULL, NULL},
+  {NULL, NULL, NULL, NULL, NULL},
+  {NULL, NULL, NULL, NULL, NULL}
 };
 
 
@@ -1080,6 +1087,34 @@
 void
 gftp_set_request_option (gftp_request * request, char * key, void *value)
 {
+  gftp_config_vars * tmpconfigvar;
+
+  if (request->local_options_hash == NULL)
+    request->local_options_hash = g_hash_table_new (string_hash_function,
+                                                    string_hash_compare);
+
+  if ((tmpconfigvar = g_hash_table_lookup (request->local_options_hash,
+                                           key)) != NULL)
+    memcpy (&tmpconfigvar->value, value, sizeof (tmpconfigvar->value));
+  else
+    {
+      if (gftp_global_options_htable == NULL &&
+          (tmpconfigvar = g_hash_table_lookup (gftp_global_options_htable,
+                                               key)) == NULL)
+        {
+          fprintf (stderr, _("FATAL gFTP Error: Config option '%s' not found in global hash table\n"), key);
+          exit (1);
+        }
+      
+      request->num_local_options_vars++;
+      request->local_options_vars = g_realloc (request->local_options_vars, 
+                                               sizeof (gftp_config_vars) * (request->num_local_options_vars + 1));
+
+      memcpy (&request->local_options_vars[request->num_local_options_vars],
+              tmpconfigvar, sizeof (*tmpconfigvar));
+      memcpy (&request->local_options_vars[request->num_local_options_vars].value, value, sizeof (value));
+      
+    }
 }
 
 
--- a/lib/gftp.h	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/gftp.h	Fri Apr 18 19:38:34 2003 +0000
@@ -192,6 +192,80 @@
   char *domain;
 } gftp_proxy_hosts;
 
+
+/* Note, these numbers must match up to the index number in config_file.c
+   in the declaration of gftp_option_types */
+typedef enum 
+{
+  gftp_option_type_text		= 0,
+  gftp_option_type_textcombo	= 1,
+  gftp_option_type_textcomboedt = 2,
+  gftp_option_type_hidetext	= 3,
+  gftp_option_type_int		= 4,
+  gftp_option_type_checkbox	= 5,
+  gftp_option_type_intcombo	= 6,
+  gftp_option_type_float	= 7,
+  gftp_option_type_color	= 8,
+  gftp_option_type_notebook	= 9
+} gftp_option_type_enum;
+
+
+#define GFTP_PORT_GTK			(1 << 1)
+#define GFTP_PORT_TEXT			(1 << 2)
+#define GFTP_PORT_ALL			(GFTP_PORT_GTK | GFTP_PORT_TEXT)
+
+
+typedef struct gftp_config_list_vars_tag
+{
+  char *key;
+  void * (*read_func) (char *buf, int line);
+  void (*write_func) (FILE *fd, void *data);
+  GList * list;
+  unsigned int num_items;
+  char *header;
+} gftp_config_list_vars;
+
+
+#define GFTP_CVARS_FLAGS_DYNMEM		(1 << 1)
+
+
+typedef struct gftp_config_vars_tag
+{
+  char *key,			/* variable name */
+       *description;		/* How this field will show up in the dialog */
+  int otype;			/* Type of option this is */
+  void *value;
+  void *listdata;		/* For options that have several different 
+				   options, this is a list of all the options.
+				   Each option_type that uses this will use this
+				   field differently */
+  int flags;			/* See GFTP_CVARS_FLAGS_* above */
+  char *comment;                /* Comment to write out to the config file */
+  int ports_shown;		/* What ports of gFTP is this option shown in */
+  void *user_data;		/* Data that the GUI can store here (Widget in gtk+) */
+} gftp_config_vars;
+
+
+typedef struct gftp_option_type_tag
+{
+  int (*read_function) (char *str, gftp_config_vars * cv, int line);
+  int (*write_function) (gftp_config_vars * cv, FILE * fd, int to_config_file);
+  void * (*ui_print_function) (gftp_config_vars * cv, void *user_data);
+  void (*ui_save_function) (gftp_config_vars * cv, void *user_data);
+  void *user_data;
+} gftp_option_type_var;
+
+
+#define GFTP_TEXTCOMBOEDT_EDITABLE 	(1 << 0)
+
+typedef struct gftp_textcomboedt_data_tag
+{
+  char *description,
+       *text;
+  int flags;
+} gftp_textcomboedt_data;
+
+
 typedef struct gftp_request_tag gftp_request;
 
 struct gftp_request_tag 
@@ -303,13 +377,13 @@
   void (*swap_socks)			( gftp_request * dest,
 					  gftp_request * source );
 
-  GHashTable * local_options;
+  gftp_config_vars * local_options_vars;
+  int num_local_options_vars;
+  GHashTable * local_options_hash;
 };
 
 
-typedef struct gftp_transfer_tag gftp_transfer;
-
-struct gftp_transfer_tag
+typedef struct gftp_transfer_tag
 {
   gftp_request * fromreq,
                * toreq;
@@ -354,7 +428,7 @@
 
   void *user_data;
   void *clist;
-};
+} gftp_transfer;
 
 
 typedef struct gftp_log_tag
@@ -421,79 +495,6 @@
 } gftp_color;
 
 
-/* Note, these numbers must match up to the index number in config_file.c
-   in the declaration of gftp_option_types */
-typedef enum 
-{
-  gftp_option_type_text		= 0,
-  gftp_option_type_textcombo	= 1,
-  gftp_option_type_textcomboedt = 2,
-  gftp_option_type_hidetext	= 3,
-  gftp_option_type_int		= 4,
-  gftp_option_type_checkbox	= 5,
-  gftp_option_type_intcombo	= 6,
-  gftp_option_type_float	= 7,
-  gftp_option_type_color	= 8,
-  gftp_option_type_notebook	= 9,
-  gftp_option_type_newtable	= 10,
-  gftp_option_type_label	= 11,
-  gftp_option_type_subtree	= 12,
-  gftp_option_type_table	= 13
-} gftp_option_type_enum;
-
-
-#define GFTP_PORT_GTK			(1 << 1)
-#define GFTP_PORT_TEXT			(1 << 2)
-#define GFTP_PORT_ALL			(GFTP_PORT_GTK | GFTP_PORT_TEXT)
-
-
-typedef struct gftp_config_list_vars_tag
-{
-  char *key;
-  void * (*read_func) (char *buf, int line);
-  void (*write_func) (FILE *fd, void *data);
-  GList * list;
-  unsigned int num_items;
-  char *header;
-} gftp_config_list_vars;
-
-
-#define GFTP_CVARS_FLAGS_DYNMEM		(1 << 1)
-
-
-typedef struct gftp_config_vars_tag
-{
-  char *key,			/* variable name */
-       *description;		/* How this field will show up in the dialog */
-  int otype;			/* Type of option this is */
-  void *value;
-  void *listdata;		/* For options that have several different 
-				   options, this is a list of all the options.
-				   Each option_type that uses this will use this
-				   field differently */
-  int flags;			/* See GFTP_CVARS_FLAGS_* above */
-  char *comment;                /* Comment to write out to the config file */
-  int ports_shown;		/* What ports of gFTP is this option shown in */
-  void *user_data;		/* Data that the GUI can store here (Widget in gtk+) */
-} gftp_config_vars;
-
-
-typedef struct gftp_option_type_tag
-{
-  int (*read_function) (char *str, gftp_config_vars * cv, int line);
-  int (*write_function) (gftp_config_vars * cv, FILE * fd, int to_config_file);
-  int (*ui_print_function) (char *label, void *ptr, void *user_data);
-  void *user_data;
-} gftp_option_type_var;
-
-
-typedef struct gftp_textcomboedt_data_tag
-{
-  char *key,
-       *description;
-} gftp_textcomboedt_data;
-
-
 typedef struct gftp_getline_buffer_tag
 {
   char *buffer,
@@ -603,6 +604,9 @@
 
 void free_tdata 			( gftp_transfer * tdata );
 
+void gftp_copy_local_options 		( gftp_request * dest, 
+					  gftp_request * source );
+
 gftp_request * copy_request 		( gftp_request * req );
 
 int ptym_open 				( char *pts_name,
--- a/lib/local.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/local.c	Fri Apr 18 19:38:34 2003 +0000
@@ -451,20 +451,19 @@
       request->logging_function (gftp_logging_misc, request->user_data,
                           _("Successfully changed local directory to %s\n"),
                           directory);
-      if (request->directory != directory) /* FIXME - take this out ? */
+
+      if (getcwd (tempstr, sizeof (tempstr)) == NULL)
         {
-          if (getcwd (tempstr, sizeof (tempstr)) == NULL)
-	    {
-              request->logging_function (gftp_logging_error, request->user_data,
+          request->logging_function (gftp_logging_error, request->user_data,
                             _("Could not get current working directory: %s\n"),
                             g_strerror (errno));
-	      return (GFTP_ERETRYABLE);
-	    }
+	  return (GFTP_ERETRYABLE);
+        }
 
-          if (request->directory)
-	    g_free (request->directory);
-          request->directory = g_strdup (tempstr);
-        }
+      if (request->directory)
+        g_free (request->directory);
+      request->directory = g_strdup (tempstr);
+
       return (0);
     }
   else
--- a/lib/misc.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/misc.c	Fri Apr 18 19:38:34 2003 +0000
@@ -549,6 +549,37 @@
 }
 
 
+void
+gftp_copy_local_options (gftp_request * dest, gftp_request * source)
+{
+  int i;
+
+  if (source->local_options_vars == NULL)
+    {
+      dest->local_options_vars = NULL;
+      dest->num_local_options_vars = 0;
+      dest->local_options_hash = NULL;
+      return;
+    }
+
+  dest->local_options_hash = g_hash_table_new (string_hash_function,
+                                               string_hash_compare);
+
+  for (i=0; source->local_options_vars[i].key != NULL; i++);
+
+  dest->local_options_vars = g_malloc (sizeof (gftp_config_vars) * (i + 1));
+  memcpy (dest, source, sizeof (gftp_config_vars) * (i + 1));
+  dest->num_local_options_vars = i;
+
+  for (i=0; dest->local_options_vars[i].key != NULL; i++)
+    {
+      g_hash_table_insert (dest->local_options_hash, 
+                           dest->local_options_vars[i].key,
+                           &dest->local_options_vars[i]);
+    }
+}
+
+
 gftp_request * 
 copy_request (gftp_request * req)
 {
@@ -569,7 +600,7 @@
   newreq->port = req->port;
   newreq->use_proxy = req->use_proxy;
   newreq->logging_function = req->logging_function;
-  newreq->local_options = NULL; /* FIXME */
+  gftp_copy_local_options (newreq, req);
 
   req->init (newreq);
 
--- a/lib/options.h	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/options.h	Fri Apr 18 19:38:34 2003 +0000
@@ -31,8 +31,7 @@
 
 gftp_config_vars gftp_global_config_vars[] =
 {
-  {"", N_("General"), gftp_option_type_notebook, NULL, 
-   NULL, GFTP_PORT_GTK, NULL},
+  {"", N_("General"), gftp_option_type_notebook, NULL, NULL, 0, NULL, GFTP_PORT_GTK, NULL},
 
   {"view_program", N_("View program:"), gftp_option_type_text, "", NULL, 0,
    N_("The default program used to view files. If this is blank, the internal file viewer will be used"), 
@@ -86,7 +85,7 @@
    N_("The maximum KB/s a file transfer can get. (Set to 0 to disable)"),  
    GFTP_PORT_ALL, NULL},
 
-  {"default_protocol", N_("Default Protocol"),
+  {"default_protocol", N_("Default Protocol:"),
    gftp_option_type_textcombo, "FTP", NULL, 0,
    N_("This specifies the default protocol to use"), GFTP_PORT_ALL, NULL},
 
--- a/lib/protocols.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/protocols.c	Fri Apr 18 19:38:34 2003 +0000
@@ -20,7 +20,6 @@
 #include "gftp.h"
 static const char cvsid[] = "$Id$";
 
-/* {{{ gftp_request_new */
 gftp_request *
 gftp_request_new (void)
 {
@@ -33,7 +32,7 @@
   request->server_type = GFTP_DIRTYPE_OTHER;
   return (request);
 }
-/* }}} */
+
 
 void
 gftp_request_destroy (gftp_request * request, int free_request)
@@ -76,7 +75,9 @@
       request->datafd = -1;
       request->cachefd = -1;
     }
-  /* FIXME - free local_options */
+
+  g_free (request->local_options_vars);
+  g_hash_table_destroy (request->local_options_hash);
 }
 
 
@@ -1115,8 +1116,7 @@
       startpos = goto_next_token (startpos);
     }
 
-  /* FIXME - make this GFTP_DIRTYPE_CRAY */
-  if (request->server_type != GFTP_DIRTYPE_UNIX)
+  if (request->server_type != GFTP_DIRTYPE_CRAY)
     {
       /* See if this is a Cray directory listing. It has the following format:
       drwx------     2 feiliu    g913     DK  common      4096 Sep 24  2001 wv */
--- a/lib/rfc2068.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/rfc2068.c	Fri Apr 18 19:38:34 2003 +0000
@@ -223,8 +223,8 @@
 static int
 rfc2068_connect (gftp_request * request)
 {
+  char *proxy_hostname, *proxy_config;
   rfc2068_params * params;
-  char *proxy_hostname;
   int proxy_port;
 
   g_return_val_if_fail (request != NULL, GFTP_EFATAL);
@@ -236,12 +236,17 @@
   if (request->sockfd > 0)
     return (0);
 
+  gftp_lookup_request_option (request, "proxy_config", &proxy_config);
   gftp_lookup_request_option (request, "http_proxy_host", &proxy_hostname);
   gftp_lookup_request_option (request, "http_proxy_port", &proxy_port);
 
   if (request->url_prefix != NULL)
     g_free (request->url_prefix);
-  request->url_prefix = g_strdup ("http"); /* FIXME _ can be FTP */
+
+  if (proxy_config != NULL && strcmp (proxy_config, "ftp") == 0)
+    request->url_prefix = g_strdup ("ftp");
+  else
+    request->url_prefix = g_strdup ("http");
 
   if ((request->sockfd = gftp_connect_server (request, request->url_prefix, 
                                               proxy_hostname, proxy_port)) < 0)
--- a/lib/rfc959.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/lib/rfc959.c	Fri Apr 18 19:38:34 2003 +0000
@@ -20,16 +20,18 @@
 #include "gftp.h"
 static const char cvsid[] = "$Id$";
 
+/* FIXME - add coversion functios for %n to \n */
+
 static gftp_textcomboedt_data gftp_proxy_type[] = {
-  {N_("none"), ""},
-  {N_("SITE command"), "USER %pu\nPASS %pp\nSITE %hh\nUSER %hu\nPASS %hp\n"},
-  {N_("user@host"), "USER %pu\nPASS %pp\nUSER %hu@%hh\nPASS %hp\n"},
-  {N_("user@host:port"), "USER %hu@%hh:%ho\nPASS %hp\n"},
-  {N_("AUTHENTICATE"), "USER %hu@%hh\nPASS %hp\nSITE AUTHENTICATE %pu\nSITE RESPONSE %pp\n"},
-  {N_("user@host port"), "USER %hu@%hh %ho\nPASS %hp\n"},
-  {N_("user@host NOAUTH"), "USER %hu@%hh\nPASS %hp\n"},
-  {N_("HTTP Proxy"), "http"},
-  {N_("Custom"), ""},
+  {N_("none"), "", 0},
+  {N_("SITE command"), "USER %pu\nPASS %pp\nSITE %hh\nUSER %hu\nPASS %hp\n", 0},
+  {N_("user@host"), "USER %pu\nPASS %pp\nUSER %hu@%hh\nPASS %hp\n", 0},
+  {N_("user@host:port"), "USER %hu@%hh:%ho\nPASS %hp\n", 0},
+  {N_("AUTHENTICATE"), "USER %hu@%hh\nPASS %hp\nSITE AUTHENTICATE %pu\nSITE RESPONSE %pp\n", 0},
+  {N_("user@host port"), "USER %hu@%hh %ho\nPASS %hp\n", 0},
+  {N_("user@host NOAUTH"), "USER %hu@%hh\nPASS %hp\n", 0},
+  {N_("HTTP Proxy"), "http", 0},
+  {N_("Custom"), "", GFTP_TEXTCOMBOEDT_EDITABLE},
   {NULL, NULL}
 };
 
@@ -42,18 +44,6 @@
    gftp_option_type_text, "", NULL, 0,
    N_("This is the password that will be used whenever you log into a remote FTP server as anonymous"), 
    GFTP_PORT_ALL, NULL},
-  {"passive_transfer", N_("Passive file transfers"), 
-   gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 0,
-   N_("If this is enabled, then the remote FTP server will open up a port for the data connection. If you are behind a firewall, you will need to enable this. Generally, it is a good idea to keep this enabled unless you are connecting to an older FTP server that doesn't support this. If this is disabled, then gFTP will open up a port on the client side and the remote server will attempt to connect to it."),
-   GFTP_PORT_ALL, NULL},
-  {"resolve_symlinks", N_("Resolve Remote Symlinks (LIST -L)"), 
-   gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 0,
-   N_("The remote FTP server will attempt to resolve symlinks in the directory listings. Generally, this is a good idea to leave enabled. The only time you will want to disable this is if the remote FTP server doesn't support the -L option to LIST"), 
-   GFTP_PORT_ALL, NULL},
-  {"ascii_transfers", N_("Transfer files in ASCII mode"), 
-   gftp_option_type_checkbox, GINT_TO_POINTER(0), NULL, 0,
-   N_("If you are transfering a text file from Windows to UNIX box or vice versa, then you should enable this. Each system represents newlines differently for text files. If you are transfering from UNIX to UNIX, then it is safe to leave this off. If you are downloading binary data, you will want to disable this."), 
-   GFTP_PORT_ALL, NULL},
   {"ftp_proxy_host", N_("Proxy hostname:"), 
    gftp_option_type_text, "", NULL, 0,
    N_("Firewall hostname"), GFTP_PORT_ALL, NULL},
@@ -70,13 +60,24 @@
    gftp_option_type_text, "", NULL, 0,
    N_("Your firewall account (optional)"), GFTP_PORT_ALL, NULL},
   
-  {"", "", gftp_option_type_newtable, "", NULL, 0, "", GFTP_PORT_GTK, NULL},
-
   {"proxy_config", N_("Proxy server type:"),
    gftp_option_type_textcomboedt, "", gftp_proxy_type, 0,
    N_("This specifies how your proxy server expects us to log in. You can specify a 2 character replacement string prefixed by a % that will be replaced with the proper data. The first character can be either p for proxy or h for the host of the FTP server. The second character can be u (user), p (pass), h (host), o (port) or a (account). For example, to specify the proxy user, you can you type in %pu"), 
    GFTP_PORT_ALL, NULL},
 
+  {"passive_transfer", N_("Passive file transfers"), 
+   gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 0,
+   N_("If this is enabled, then the remote FTP server will open up a port for the data connection. If you are behind a firewall, you will need to enable this. Generally, it is a good idea to keep this enabled unless you are connecting to an older FTP server that doesn't support this. If this is disabled, then gFTP will open up a port on the client side and the remote server will attempt to connect to it."),
+   GFTP_PORT_ALL, NULL},
+  {"resolve_symlinks", N_("Resolve Remote Symlinks (LIST -L)"), 
+   gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 0,
+   N_("The remote FTP server will attempt to resolve symlinks in the directory listings. Generally, this is a good idea to leave enabled. The only time you will want to disable this is if the remote FTP server doesn't support the -L option to LIST"), 
+   GFTP_PORT_ALL, NULL},
+  {"ascii_transfers", N_("Transfer files in ASCII mode"), 
+   gftp_option_type_checkbox, GINT_TO_POINTER(0), NULL, 0,
+   N_("If you are transfering a text file from Windows to UNIX box or vice versa, then you should enable this. Each system represents newlines differently for text files. If you are transfering from UNIX to UNIX, then it is safe to leave this off. If you are downloading binary data, you will want to disable this."), 
+   GFTP_PORT_ALL, NULL},
+
   {NULL, NULL, 0, NULL, NULL, 0, NULL, 0, NULL}
 };
 
@@ -398,6 +399,8 @@
     request->server_type = GFTP_DIRTYPE_UNIX;
   else if (strcmp (stpos, "VMS") == 0)
     request->server_type = GFTP_DIRTYPE_VMS;
+  else if (strcmp (stpos, "CRAY") == 0)
+    request->server_type = GFTP_DIRTYPE_CRAY;
   else
     request->server_type = GFTP_DIRTYPE_OTHER;
 
--- a/src/gtk/gftp-gtk.h	Fri Apr 18 16:02:38 2003 +0000
+++ b/src/gtk/gftp-gtk.h	Fri Apr 18 19:38:34 2003 +0000
@@ -134,6 +134,26 @@
 } gftp_save_dir_struct;
 
 
+typedef struct gftp_textcomboedt_widget_data_tag
+{
+  GtkWidget * combo,
+            * text;
+  gftp_config_vars * cv;
+} gftp_textcomboedt_widget_data;
+
+
+typedef struct gftp_options_dialog_data_tag
+{
+  GtkWidget * dialog,
+            * notebook,
+            * box,
+            * table;
+  int tbl_col_num,
+      tbl_row_num;
+  gftp_option_type_enum last_option;
+} gftp_options_dialog_data;
+
+
 extern gftp_window_data window1, window2, * other_wdata, * current_wdata;
 extern GtkWidget * stop_btn, * hostedit, * useredit, * passedit,
                  * portedit, * logwdw, * dlwdw, * protocol_menu, * optionmenu;
--- a/src/gtk/options_dialog.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/src/gtk/options_dialog.c	Fri Apr 18 19:38:34 2003 +0000
@@ -20,12 +20,500 @@
 #include <gftp-gtk.h>
 static const char cvsid[] = "$Id$";
 
-static GtkWidget * proxy_text, * proxy_list, * new_proxy_domain, * network1,
+static GtkWidget * proxy_list, * new_proxy_domain, * network1,
                  * network2, * network3, * network4, * netmask1, * netmask2, 
-                 * netmask3, * netmask4, * domain_active, * proxy_combo,
-                 * def_proto_combo;
+                 * netmask3, * netmask4, * domain_active;
 static GList * new_proxy_hosts;
-static char *custom_proxy;
+
+static void
+_setup_option (gftp_option_type_enum otype,
+               gftp_options_dialog_data * option_data, 
+               void * (*ui_print_function) (gftp_config_vars * cv,
+                                                 void *user_data),
+               void (*ui_save_function) (gftp_config_vars * cv,
+                                         void *user_data))
+{
+  gftp_option_types[otype].user_data = option_data;
+  gftp_option_types[otype].ui_print_function = ui_print_function;
+  gftp_option_types[otype].ui_save_function = ui_save_function;
+}
+
+
+static void *
+_gen_input_widget (gftp_options_dialog_data * option_data, char *label)
+{
+  GtkWidget * tempwid;
+
+  option_data->tbl_row_num++;
+  gtk_table_resize (GTK_TABLE (option_data->table), 
+                    option_data->tbl_row_num, 2);
+
+  tempwid = gtk_label_new (_(label));
+  gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
+  gtk_table_attach_defaults (GTK_TABLE (option_data->table), tempwid, 0, 1,
+                             option_data->tbl_row_num - 1, 
+                             option_data->tbl_row_num);
+  gtk_widget_show (tempwid);
+
+  tempwid = gtk_entry_new ();
+  gtk_table_attach_defaults (GTK_TABLE (option_data->table), tempwid, 1, 2,
+                             option_data->tbl_row_num - 1, 
+                             option_data->tbl_row_num);
+  gtk_widget_show (tempwid);
+  return (tempwid);
+}
+
+
+static void *
+_print_option_type_newtable (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+
+  option_data = user_data;
+
+  option_data->table = gtk_table_new (1, 2, FALSE);
+  gtk_table_set_row_spacings (GTK_TABLE (option_data->table), 5);
+  gtk_table_set_col_spacings (GTK_TABLE (option_data->table), 5);
+  gtk_box_pack_start (GTK_BOX (option_data->box), option_data->table, FALSE, 
+                      FALSE, 0);
+  gtk_widget_show (option_data->table);
+  option_data->tbl_row_num = 0;
+  option_data->tbl_col_num = 0;
+
+  return (NULL);
+}
+
+
+static void *
+_print_option_type_text (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  GtkWidget * tempwid;
+
+  option_data = user_data;
+
+  tempwid = _gen_input_widget (option_data, cv->description);
+  gtk_entry_set_text (GTK_ENTRY (tempwid), (char *) cv->value);
+  return (tempwid);
+}
+
+
+static void
+_save_option_type_text (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  const char *tempstr;
+
+  option_data = user_data;
+  tempstr = gtk_entry_get_text (GTK_ENTRY (cv->user_data));
+
+  if (cv->flags & GFTP_CVARS_FLAGS_DYNMEM)
+    g_free (cv->value);
+
+  cv->value = g_strdup (tempstr);
+  cv->flags |= GFTP_CVARS_FLAGS_DYNMEM;
+}
+
+
+static GtkWidget *
+_gen_combo_widget (gftp_options_dialog_data * option_data, char *label)
+{
+  GtkWidget * tempwid, * combo;
+
+  option_data->tbl_row_num++;
+  gtk_table_resize (GTK_TABLE (option_data->table), 
+                               option_data->tbl_row_num, 2);
+
+  tempwid = gtk_label_new (_(label));
+  gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
+  gtk_table_attach_defaults (GTK_TABLE (option_data->table), tempwid, 0, 1,
+                             option_data->tbl_row_num - 1, 
+                             option_data->tbl_row_num);
+  gtk_widget_show (tempwid);
+
+  combo = gtk_combo_new ();
+  gtk_table_attach_defaults (GTK_TABLE (option_data->table), combo, 1, 2,
+                             option_data->tbl_row_num - 1, 
+                             option_data->tbl_row_num);
+  return (combo);
+}
+
+
+static void *
+_print_option_type_textcombo (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  GList * widget_list;
+  GtkWidget * tempwid, * combo;
+  int selitem, i;
+  char **clist;
+
+  option_data = user_data;
+  combo = _gen_combo_widget (option_data, cv->description);
+
+  if (cv->listdata != NULL)
+    {
+      selitem = 0;
+      widget_list = NULL;
+
+      clist = cv->listdata;
+      for (i=0; clist[i] != NULL; i++)
+        {
+          if (cv->value != NULL &&
+              strcasecmp ((char *) cv->value, clist[i]) == 0)
+            selitem = i;
+
+          tempwid = gtk_list_item_new_with_label (clist[i]);
+          gtk_widget_show (tempwid);
+          widget_list = g_list_append (widget_list, tempwid);
+        }
+
+      gtk_list_prepend_items (GTK_LIST (GTK_COMBO (combo)->list), widget_list); 
+      gtk_list_select_item (GTK_LIST (GTK_COMBO (combo)->list), selitem);
+    }
+
+  gtk_widget_show (combo);
+  return (combo);
+}
+
+
+static void
+_save_option_type_textcombo (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  const char *tempstr;
+  char **clist;
+  int i;
+
+  option_data = user_data;
+
+  tempstr = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cv->user_data)->entry));
+
+  if (cv->listdata != NULL && tempstr != NULL)
+    {
+      clist = cv->listdata;
+      for (i=0; clist[i] != NULL; i++)
+        {
+          if (strcasecmp (tempstr, clist[i]) == 0)
+            {
+              cv->value = clist[i];
+              break;
+            }
+        }
+    }
+}
+
+
+static void
+_textcomboedt_toggle (GtkList * list, GtkWidget * child, gpointer data)
+{
+  gftp_textcomboedt_widget_data * widdata;
+  gftp_textcomboedt_data * tedata;
+  int num, isedit;
+#if GTK_MAJOR_VERSION > 1
+  GtkTextIter iter, iter2;
+  GtkTextBuffer * textbuf;
+  guint len;
+#endif
+
+  widdata = data;
+  tedata = widdata->cv->listdata;
+
+  num = gtk_list_child_position (list, child);
+  isedit = tedata[num].flags & GFTP_TEXTCOMBOEDT_EDITABLE;
+#if GTK_MAJOR_VERSION == 1
+  gtk_text_set_editable (GTK_TEXT (widdata->text), isedit);
+#else
+  gtk_text_view_set_editable (GTK_TEXT_VIEW (widdata->text), isedit);
+#endif
+
+  if (isedit)
+    return;
+
+#if GTK_MAJOR_VERSION == 1
+  gtk_text_set_point (GTK_TEXT (widdata->text), 0);
+  gtk_text_forward_delete (GTK_TEXT (widdata->text),
+			   gtk_text_get_length (GTK_TEXT (widdata->text)));
+
+  gtk_text_insert (GTK_TEXT (widdata->text), NULL, NULL, NULL, 
+                   tedata[num].text, -1);
+#else
+  textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widdata->text));
+  len = gtk_text_buffer_get_char_count (textbuf);
+  gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0);
+  gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1);
+  gtk_text_buffer_delete (textbuf, &iter, &iter2);
+
+  len = gtk_text_buffer_get_char_count (textbuf);
+  gtk_text_buffer_get_iter_at_offset (textbuf, &iter, len - 1);
+  gtk_text_buffer_insert (textbuf, &iter, tedata[num].text, -1);
+#endif
+}
+
+
+static void *
+_print_option_type_textcomboedt (gftp_config_vars * cv, void *user_data)
+{
+  gftp_textcomboedt_widget_data * widdata;
+  GtkWidget * combo, * textwid, * tempwid;
+  gftp_options_dialog_data * option_data;
+  gftp_textcomboedt_data * tedata;
+  int i, selitem, edititem;
+  GList * widget_list;
+  char *tempstr;
+
+  option_data = user_data;
+  combo = _gen_combo_widget (option_data, cv->description);
+
+  edititem = selitem = -1;
+  if (cv->listdata != NULL)
+    {
+      widget_list = NULL;
+
+      if (cv->value == NULL)
+        tempstr = "";
+      else
+        tempstr = cv->value;
+
+      tedata = cv->listdata;
+      for (i=0; tedata[i].description != NULL; i++)
+        {
+          if (tedata[i].flags & GFTP_TEXTCOMBOEDT_EDITABLE)
+            edititem = i;
+
+          if (strcasecmp (tempstr, tedata[i].text) == 0)
+            selitem = i;
+
+          tempwid = gtk_list_item_new_with_label (tedata[i].description);
+          gtk_widget_show (tempwid);
+          widget_list = g_list_append (widget_list, tempwid);
+        }
+
+      gtk_list_prepend_items (GTK_LIST (GTK_COMBO (combo)->list), widget_list); 
+
+      gtk_list_select_item (GTK_LIST (GTK_COMBO (combo)->list), selitem);
+    }
+
+  if (selitem == -1 && edititem != -1)
+    selitem = edititem;
+  else if (selitem == -1)
+    selitem = 0;
+
+  option_data->tbl_row_num++;
+  gtk_table_resize (GTK_TABLE (option_data->table), 
+                               option_data->tbl_row_num, 2);
+
+#if GTK_MAJOR_VERSION == 1
+  textwid = gtk_text_new (NULL, NULL);
+  gtk_text_set_editable (GTK_TEXT (textwid), TRUE);
+#else
+  textwid = gtk_text_view_new ();
+  gtk_text_view_set_editable (GTK_TEXT_VIEW (textwid), TRUE);
+#endif
+  gtk_widget_set_size_request (textwid, -1, 75);
+  gtk_table_attach_defaults (GTK_TABLE (option_data->table), textwid, 0, 2,
+                             option_data->tbl_row_num - 1, 
+                             option_data->tbl_row_num);
+  gtk_widget_show (textwid);
+
+  widdata = g_malloc0 (sizeof (*widdata));
+  widdata->combo = combo;
+  widdata->text = textwid;
+  widdata->cv = cv;
+
+  gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->list),
+                      "select_child", 
+                      GTK_SIGNAL_FUNC (_textcomboedt_toggle), widdata);
+  gtk_list_select_item (GTK_LIST (GTK_COMBO (combo)->list), selitem);
+  gtk_widget_show (combo);
+
+  return (textwid);
+}
+
+
+static void
+_save_option_type_textcomboedt (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  const char *textstr;
+  char *newstr;
+#if GTK_MAJOR_VERSION == 1
+  char tmp[128];
+#else
+  GtkTextBuffer * textbuf;
+  GtkTextIter iter, iter2;
+  size_t len;
+#endif
+
+  option_data = user_data;
+
+#if GTK_MAJOR_VERSION == 1
+  /*
+     GTK_TEXT uses wchar_t instead of char in environment of multibyte encoding
+     locale (ex Japanese),  so we must convert from wide character 
+     to multibyte charator....   Yasuyuki Furukawa (yasu@on.cs.keio.ac.jp)
+   */
+  if (GTK_TEXT (cv->user_data)->use_wchar)
+    {
+      wcstombs (tmp, (wchar_t *) GTK_TEXT (cv->user_data)->text.wc, sizeof (tmp));
+      newstr = g_strdup (tmp);
+    }
+  else
+    {
+      textstr = (char *) GTK_TEXT (cv->user_data)->text.ch; 
+      newstr = g_strdup (textstr);
+    }
+#else
+  textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (cv->user_data));
+  len = gtk_text_buffer_get_char_count (textbuf);
+  gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0);
+  gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1);
+  newstr = gtk_text_buffer_get_text (textbuf, &iter, &iter2, 0);
+#endif
+
+  cv->value = newstr;
+}
+
+
+static void *
+_print_option_type_hidetext (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  GtkWidget * tempwid;
+
+  option_data = user_data;
+
+  tempwid = _gen_input_widget (option_data, cv->description);
+  gtk_entry_set_visibility (GTK_ENTRY (tempwid), 0);
+  gtk_entry_set_text (GTK_ENTRY (tempwid), (char *) cv->value);
+  return (tempwid);
+}
+
+
+static void *
+_print_option_type_int (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  GtkWidget * tempwid;
+  char tempstr[20];
+
+  option_data = user_data;
+
+  tempwid = _gen_input_widget (option_data, cv->description);
+  g_snprintf (tempstr, sizeof (tempstr), "%d", GPOINTER_TO_INT(cv->value));
+  gtk_entry_set_text (GTK_ENTRY (tempwid), tempstr);
+  return (tempwid);
+}
+
+
+static void
+_save_option_type_int (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  const char *tempstr;
+
+  option_data = user_data;
+  tempstr = gtk_entry_get_text (GTK_ENTRY (cv->user_data));
+  cv->value = GINT_TO_POINTER(strtol (tempstr, NULL, 10));
+}
+
+
+static void *
+_print_option_type_checkbox (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  GtkWidget * tempwid;
+
+  option_data = user_data;
+
+  if (option_data->last_option != gftp_option_type_checkbox)
+    _print_option_type_newtable (NULL, user_data);
+
+  if (option_data->tbl_col_num == 0)
+    {
+      option_data->tbl_row_num++;
+      gtk_table_resize (GTK_TABLE (option_data->table), 
+                        option_data->tbl_row_num + 1, 2);
+    }
+
+  tempwid = gtk_check_button_new_with_label (_(cv->description));
+  gtk_table_attach_defaults (GTK_TABLE (option_data->table), tempwid, 
+                             option_data->tbl_col_num, 
+                             option_data->tbl_col_num + 1, 
+                             option_data->tbl_row_num, 
+                             option_data->tbl_row_num + 1);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tempwid),
+                                GPOINTER_TO_INT(cv->value));
+  gtk_widget_show (tempwid);
+
+  option_data->tbl_col_num = (option_data->tbl_col_num + 1) % 2;
+  return (tempwid);
+}
+
+
+static void
+_save_option_type_checkbox (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+
+  option_data = user_data;
+  cv->value = GINT_TO_POINTER (GTK_TOGGLE_BUTTON (cv->user_data)->active);
+}
+
+
+static void *
+_print_option_type_float (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  GtkWidget * tempwid;
+  char tempstr[20];
+  float f;
+
+  option_data = user_data;
+
+  tempwid = _gen_input_widget (option_data, cv->description);
+  memcpy (&f, &cv->value, sizeof (f));
+  g_snprintf (tempstr, sizeof (tempstr), "%.2f", f);
+  gtk_entry_set_text (GTK_ENTRY (tempwid), tempstr);
+  return (tempwid);
+}
+
+
+static void
+_save_option_type_float (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  const char *tempstr;
+  float f;
+
+  option_data = user_data;
+  tempstr = gtk_entry_get_text (GTK_ENTRY (cv->user_data));
+  f = strtod (tempstr, NULL);
+  memcpy (&cv->value, &f, sizeof (cv->value));
+}
+
+
+static void *
+_print_option_type_notebook (gftp_config_vars * cv, void *user_data)
+{
+  gftp_options_dialog_data * option_data;
+  GtkWidget * tempwid;
+
+  option_data = user_data;
+
+  option_data->box = gtk_vbox_new (FALSE, 0);
+  gtk_container_border_width (GTK_CONTAINER (option_data->box), 10);
+  gtk_widget_show (option_data->box);
+
+  tempwid = gtk_label_new (_(cv->description));
+  gtk_widget_show (tempwid);
+  gtk_notebook_append_page (GTK_NOTEBOOK (option_data->notebook), 
+                            option_data->box, tempwid);
+
+  _print_option_type_newtable (NULL, user_data);
+  
+  return (NULL);
+}
 
 
 static void
@@ -45,160 +533,33 @@
     }
   g_list_free (new_proxy_hosts);
   new_proxy_hosts = NULL;
-
-  if (custom_proxy != NULL)
-    {
-      g_free (custom_proxy);
-      custom_proxy = NULL;
-    }
-}
-
-
-static char *
-get_proxy_config (void)
-{
-  char *newstr, *oldstr, *pos, *endpos, *textstr;
-  guint len;
-#if GTK_MAJOR_VERSION == 1
-  char tmp[128];
-#else
-  GtkTextBuffer * textbuf;
-  GtkTextIter iter, iter2;
-#endif
-
-  textstr = NULL;
-  newstr = g_malloc (1);
-  *newstr = '\0';
-
-#if GTK_MAJOR_VERSION == 1
-  /*
-     GTK_TEXT uses wchar_t instead of char in environment of multibyte encoding
-     locale (ex Japanese),  so we must convert from wide character 
-     to multibyte charator....   Yasuyuki Furukawa (yasu@on.cs.keio.ac.jp)
-   */
-  if (GTK_TEXT (proxy_text)->use_wchar)
-    {
-      wcstombs (tmp, (wchar_t *) GTK_TEXT (proxy_text)->text.wc,
-                sizeof (tmp));
-      pos = tmp;
-    }
-  else
-    {
-      oldstr = (char *) GTK_TEXT (proxy_text)->text.ch; 
-      len = gtk_text_get_length (GTK_TEXT (proxy_text));
-      textstr = g_malloc (len + 1);
-      strncpy (textstr, oldstr, len);
-      textstr[len] = '\0';
-      pos = textstr;
-    }
-#else
-  textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (proxy_text));
-  len = gtk_text_buffer_get_char_count (textbuf);
-  gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0);
-  gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1);
-  pos = textstr = gtk_text_buffer_get_text (textbuf, &iter, &iter2, 0);
-#endif
-
-  do
-    {
-      if ((endpos = strchr (pos, '\n')) != NULL)
-        *endpos = '\0';
-      oldstr = newstr;
-      if (endpos != NULL)
-        newstr = g_strconcat (newstr, pos, "%n", NULL);
-      else
-        newstr = g_strconcat (newstr, pos, NULL);
-      g_free (oldstr);
-      if (endpos != NULL)
-        {
-          *endpos = '\n';
-          pos = endpos + 1;
-        }
-    }
-  while (endpos != NULL);
-
-#if GTK_MAJOR_VERSION == 1
-  if (!GTK_TEXT (proxy_text)->use_wchar)
-    g_free (textstr);
-#else
-  g_free (textstr);
-#endif
-
-  return (newstr);
 }
 
 
 static void
 apply_changes (GtkWidget * widget, gpointer data)
 {
-#if 0
-FIXME
-  const char *tempstr;
-  int num, found, i;
-  GList *templist;
+  gftp_config_vars * cv;
+  GList * templist;
+  int i;
 
-  for (num = 0; config_file_vars[num].var != NULL; num++)
+  for (templist = gftp_options_list; 
+       templist != NULL; 
+       templist = templist->next)
     {
-      if (config_file_vars[num].widget != NULL)
+      cv = templist->data;
+
+      for (i=0; cv[i].key != NULL; i++)
         {
-          switch (config_file_vars[num].type)
-            {
-              case CONFIG_CHECKBOX:
-                *(int *) config_file_vars[num].var =
-                      GTK_TOGGLE_BUTTON (config_file_vars[num].widget)->active;
-                break;
-              case CONFIG_INTTEXT:
-              case CONFIG_UINTTEXT:
-                tempstr = gtk_entry_get_text ( 
-                               GTK_ENTRY (config_file_vars[num].widget));
-                *(int *) config_file_vars[num].var = strtol (tempstr, NULL, 10);
-                break;
-              case CONFIG_FLOATTEXT:
-                tempstr = gtk_entry_get_text ( 
-                               GTK_ENTRY (config_file_vars[num].widget));
-                *(double *) config_file_vars[num].var = strtod (tempstr, NULL);
-                break;
-              case CONFIG_CHARTEXT:
-              case CONFIG_CHARPASS:
-                tempstr = gtk_entry_get_text ( 
-                               GTK_ENTRY (config_file_vars[num].widget));
-                g_free (*(char **) config_file_vars[num].var);
-                *(char **) config_file_vars[num].var = 
-                                                g_malloc (strlen (tempstr) + 1);
-                strcpy (*(char **) config_file_vars[num].var, tempstr);
-                break;
-            }
+          if (!(cv[i].ports_shown & GFTP_PORT_GTK))
+            continue;
+
+          if (gftp_option_types[cv[i].otype].ui_save_function == NULL)
+            continue;
+
+          gftp_option_types[cv[i].otype].ui_save_function (&cv[i], gftp_option_types[cv[i].otype].user_data);
         }
     }
-
-  tempstr = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (def_proto_combo)->entry));
-  found = 0;
-  for (i = 0; gftp_protocols[i].name; i++)
-    {
-      if (strcmp (gftp_protocols[i].name, tempstr) == 0)
-        {
-          found = 1;
-          break;
-        }
-    }
-
-  if (found)
-    {
-      g_free (default_protocol);
-      default_protocol = g_strconcat (tempstr, NULL);
-    }
-
-  templist = proxy_hosts;
-  proxy_hosts = new_proxy_hosts;
-  new_proxy_hosts = templist;
-  clean_old_changes (NULL, NULL);
-
-  if (proxy_config != NULL)
-    g_free (proxy_config);
-  proxy_config = get_proxy_config ();
-
-  gftp_write_config_file ();
-#endif
 }
 
 
@@ -222,47 +583,6 @@
 
 
 static void
-proxy_toggle (GtkList * list, GtkWidget * child, gpointer data)
-{
-#if 0
-FIXME
-  int proxy_num;
-  char *str;
-
-#if GTK_MAJOR_VERSION > 1
-  GtkTextIter iter, iter2;
-  GtkTextBuffer * textbuf;
-  guint len;
-#endif
-
-  proxy_num = gtk_list_child_position (list, child);
-  if (proxy_num == GFTP_CUSTOM_PROXY_NUM)
-    str = custom_proxy;
-  else
-    str = proxy_type[proxy_num].description;
-
-#if GTK_MAJOR_VERSION == 1
-  gtk_text_set_point (GTK_TEXT (proxy_text), 0);
-  gtk_text_forward_delete (GTK_TEXT (proxy_text),
-			   gtk_text_get_length (GTK_TEXT (proxy_text)));
-
-  gtk_text_insert (GTK_TEXT (proxy_text), NULL, NULL, NULL, str, -1);
-#else
-  textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (proxy_text));
-  len = gtk_text_buffer_get_char_count (textbuf);
-  gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0);
-  gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1);
-  gtk_text_buffer_delete (textbuf, &iter, &iter2);
-
-  len = gtk_text_buffer_get_char_count (textbuf);
-  gtk_text_buffer_get_iter_at_offset (textbuf, &iter, len - 1);
-  gtk_text_buffer_insert (textbuf, &iter, str, -1);
-#endif
-#endif
-}
-
-
-static void
 add_host_to_listbox (GList * templist)
 {
   gftp_proxy_hosts *hosts;
@@ -650,9 +970,7 @@
 make_proxy_hosts_tab (GtkWidget * notebook)
 {
   GtkWidget *tempwid, *box, *hbox, *scroll;
-  gftp_proxy_hosts *hosts, *newhosts;
   char *add_data[2];
-  GList *templist;
 
   add_data[0] = _("Network");
   add_data[1] = _("Netmask");
@@ -701,46 +1019,45 @@
   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
 		      GTK_SIGNAL_FUNC (delete_proxy_host), NULL);
   gtk_widget_show (tempwid);
-
-#if 0
-FIXME
-  new_proxy_hosts = NULL;
-  for (templist = proxy_hosts; templist != NULL;
-       templist = templist->next)
-    {
-      hosts = templist->data;
-      newhosts = g_malloc (sizeof (*newhosts));
-      memcpy (newhosts, hosts, sizeof (*newhosts));
-      if (newhosts->domain)
-	{
-	  newhosts->domain = g_malloc (strlen (hosts->domain) + 1);
-	  strcpy (newhosts->domain, hosts->domain);
-	}
-      new_proxy_hosts = g_list_prepend (new_proxy_hosts, newhosts);
-      add_host_to_listbox (new_proxy_hosts);
-    }
-#endif
 }
 
 
 void
 options_dialog (gpointer data)
 {
-  GtkWidget * dialog, * tempwid, * notebook, * table, * box;
-  char tempstr[20], *pos, *endpos, *oldstr;
-  int i, tbl_col, tbl_num, combo_num;
-  GList * combo_list;
+  gftp_options_dialog_data option_data;
+  gftp_config_vars * cv;
+  GList * templist;
+  int i;
+
+  memset (&option_data, 0, sizeof (option_data));
+  _setup_option (gftp_option_type_text, &option_data, 
+                 _print_option_type_text, _save_option_type_text);
+  _setup_option (gftp_option_type_textcombo, &option_data, 
+                 _print_option_type_textcombo, _save_option_type_textcombo);
+  _setup_option (gftp_option_type_textcomboedt, &option_data, 
+                 _print_option_type_textcomboedt, 
+                 _save_option_type_textcomboedt);
+  _setup_option (gftp_option_type_hidetext, &option_data, 
+                 _print_option_type_hidetext, _save_option_type_text);
+  _setup_option (gftp_option_type_int, &option_data, 
+                 _print_option_type_int, _save_option_type_int);
+  _setup_option (gftp_option_type_checkbox, &option_data, 
+                 _print_option_type_checkbox, _save_option_type_checkbox);
+  _setup_option (gftp_option_type_float, &option_data, 
+                 _print_option_type_float, _save_option_type_float);
+  _setup_option (gftp_option_type_notebook, &option_data, 
+                 _print_option_type_notebook, NULL);
 
 #if GTK_MAJOR_VERSION == 1
-  dialog = gtk_dialog_new ();
-  gtk_window_set_title (GTK_WINDOW (dialog), _("Options"));
-  gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area),
-                              5);
-  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15);
-  gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE);
+  option_data.dialog = gtk_dialog_new ();
+  gtk_window_set_title (GTK_WINDOW (option_data.dialog), _("Options"));
+  gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (option_data.dialog)->action_area), 5);
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (option_data.dialog)->action_area), 15);
+  gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (option_data.dialog)->action_area), TRUE);
 #else
-  dialog = gtk_dialog_new_with_buttons (_("Options"), NULL, 0,
-                                        GTK_STOCK_SAVE,
+  option_data.dialog = gtk_dialog_new_with_buttons (_("Options"), NULL, 0,
+                                        GTK_STOCK_OK,
                                         GTK_RESPONSE_OK,
                                         GTK_STOCK_CANCEL,
                                         GTK_RESPONSE_CANCEL,
@@ -748,265 +1065,82 @@
                                         GTK_RESPONSE_APPLY,
                                         NULL);
 #endif
-  gtk_window_set_wmclass (GTK_WINDOW(dialog), "options", "gFTP");
-  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
-  gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 10);
-  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
-  gtk_widget_realize (dialog);
+  gtk_window_set_wmclass (GTK_WINDOW(option_data.dialog), "options", "gFTP");
+  gtk_window_set_position (GTK_WINDOW (option_data.dialog), GTK_WIN_POS_MOUSE);
+  gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (option_data.dialog)->vbox), 10);
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (option_data.dialog)->vbox), 2);
+  gtk_widget_realize (option_data.dialog);
 
   if (gftp_icon != NULL)
     {
-      gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap,
+      gdk_window_set_icon (option_data.dialog->window, NULL, gftp_icon->pixmap,
                            gftp_icon->bitmap);
-      gdk_window_set_icon_name (dialog->window, _("gFTP Icon"));
+      gdk_window_set_icon_name (option_data.dialog->window, _("gFTP Icon"));
     }
 
-  notebook = gtk_notebook_new ();
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), notebook, TRUE,
-                      TRUE, 0);
-  gtk_widget_show (notebook);
-
-  tbl_num = tbl_col = 0;
-  table = box = NULL;
-
-#if 0
-FIXME
-  for (i=0; config_file_vars[i].key != NULL; i++)
-    {
-      if (!(config_file_vars[i].ports_shown & GFTP_PORT_GTK))
-        continue;
-
-      switch (config_file_vars[i].type)
-        {
-          case CONFIG_NOTEBOOK:
-            box = gtk_vbox_new (FALSE, 0);
-            gtk_container_border_width (GTK_CONTAINER (box), 10);
-            gtk_widget_show (box);
-
-            tempwid = gtk_label_new (_(config_file_vars[i].description));
-            gtk_widget_show (tempwid);
-            gtk_notebook_append_page (GTK_NOTEBOOK (notebook), box, tempwid);
-            break;
-          case CONFIG_TABLE:
-            table = gtk_table_new (1, 2, FALSE);
-            gtk_table_set_row_spacings (GTK_TABLE (table), 5);
-            gtk_table_set_col_spacings (GTK_TABLE (table), 5);
-            gtk_box_pack_start (GTK_BOX (box), table, FALSE, FALSE, 0);
-            gtk_widget_show (table);
-            tbl_num = 1;
-            tbl_col = 0;
-            break;
-          case CONFIG_COMBO:
-            gtk_table_resize (GTK_TABLE (table), tbl_num, 2);
-
-            tempwid = gtk_label_new (_(config_file_vars[i].description));
-            gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
-            gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1,
-                                       tbl_num - 1, tbl_num);
-            gtk_widget_show (tempwid);
-
-            tempwid = gtk_combo_new ();
-            gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 1, 2,
-                                       tbl_num - 1, tbl_num);
-            gtk_widget_show (tempwid);
-            config_file_vars[i].widget = tempwid;
-
-            /* We only have Default Protocol and the Proxy type as the two
-               combo types. If I add more later on, I'll work on a better
-               interface for all this stuff */
-            if (strcmp (config_file_vars[i].comment, "DP") == 0)
-              def_proto_combo = tempwid;
-            else
-              proxy_combo = tempwid;
-
-            tbl_num++;
-            break;
-          case CONFIG_TEXT:
-#if GTK_MAJOR_VERSION == 1
-            proxy_text = gtk_text_new (NULL, NULL);
-            gtk_text_set_editable (GTK_TEXT (proxy_text), TRUE);
-#else
-            proxy_text = gtk_text_view_new ();
-            gtk_text_view_set_editable (GTK_TEXT_VIEW (proxy_text), TRUE);
-#endif
-            gtk_widget_set_size_request (proxy_text, -1, 75);
-            gtk_table_attach_defaults (GTK_TABLE (table), proxy_text, 0, 2, 
-                                       tbl_num - 1, tbl_num);
-            gtk_widget_show (proxy_text);
-            config_file_vars[i].widget = proxy_text;
+  option_data.notebook = gtk_notebook_new ();
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (option_data.dialog)->vbox), 
+                      option_data.notebook, TRUE, TRUE, 0);
+  gtk_widget_show (option_data.notebook);
 
-            tbl_num++;
-            break;
-          case CONFIG_CHARTEXT:
-          case CONFIG_CHARPASS:
-          case CONFIG_INTTEXT:
-          case CONFIG_UINTTEXT:
-          case CONFIG_FLOATTEXT:
-            gtk_table_resize (GTK_TABLE (table), tbl_num, 2);
-
-            tempwid = gtk_label_new (_(config_file_vars[i].description));
-            gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5);
-            gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1,
-                                       tbl_num - 1, tbl_num);
-            gtk_widget_show (tempwid);
-
-            tempwid = gtk_entry_new ();
-            gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 1, 2,
-                                       tbl_num - 1, tbl_num);
+  cv = gftp_options_list->data;
+  option_data.last_option = cv[0].otype;
+  for (templist = gftp_options_list; 
+       templist != NULL; 
+       templist = templist->next)
+    {
+      cv = templist->data;
 
-            switch (config_file_vars[i].type)
-              {
-                case CONFIG_INTTEXT:
-                case CONFIG_UINTTEXT:
-                  g_snprintf (tempstr, sizeof (tempstr), "%d",
-                              *(int *) config_file_vars[i].var);
-                  gtk_entry_set_text (GTK_ENTRY (tempwid), tempstr);
-                  break;
-                case CONFIG_FLOATTEXT:
-                  g_snprintf (tempstr, sizeof (tempstr), "%.2f",
-                              *(double *) config_file_vars[i].var);
-                  gtk_entry_set_text (GTK_ENTRY (tempwid), tempstr);
-                  break;
-                case CONFIG_CHARTEXT:
-                  gtk_entry_set_text (GTK_ENTRY (tempwid),
-                                      *(char **) config_file_vars[i].var);
-                  break;
-                case CONFIG_CHARPASS:
-                  gtk_entry_set_text (GTK_ENTRY (tempwid),
-                                      *(char **) config_file_vars[i].var);
-                  gtk_entry_set_visibility (GTK_ENTRY (tempwid), 0);
-                  break;
-              }
-            gtk_widget_show (tempwid);
-            config_file_vars[i].widget = tempwid;
-            tbl_num++;
-            break;
-          case CONFIG_CHECKBOX:
-            tempwid = gtk_check_button_new_with_label (
-                                    _(config_file_vars[i].description));
-            gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 
-                                    tbl_col, tbl_col + 1, tbl_num, tbl_num + 1);
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tempwid),
-                                    *(int *) config_file_vars[i].var);
-            gtk_widget_show (tempwid);
-            config_file_vars[i].widget = tempwid;
-            tbl_col++;
-            if (tbl_col == 2)
-              {
-                tbl_col = 0;
-                tbl_num++;
-                gtk_table_resize (GTK_TABLE (table), tbl_num + 1, 2);
-              }
-            break; 
-          case CONFIG_LABEL:
-            tempwid = gtk_label_new (_(config_file_vars[i].description));
-            gtk_misc_set_alignment (GTK_MISC (tempwid), tbl_col, 0.5);
-            gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 
-                                    tbl_col, tbl_col + 1, tbl_num, tbl_num + 1);
-            gtk_widget_show (tempwid);
-            config_file_vars[i].widget = tempwid;
-            tbl_col++;
-            if (tbl_col == 2)
-              {
-                tbl_col = 0;
-                tbl_num++;
-                gtk_table_resize (GTK_TABLE (table), tbl_num + 1, 2);
-              }
-            break;
+      for (i=0; cv[i].key != NULL; i++)
+        {
+          if (!(cv[i].ports_shown & GFTP_PORT_GTK))
+            continue;
+
+          if (gftp_option_types[cv[i].otype].ui_print_function == NULL)
+            continue;
+
+          cv[i].user_data = gftp_option_types[cv[i].otype].ui_print_function (&cv[i], gftp_option_types[cv[i].otype].user_data);
+
+          option_data.last_option = cv[i].otype;
         }
     }
 
-  combo_num = 0;
-  combo_list = NULL;
-  for (i = 0; gftp_protocols[i].name != NULL; i++)
-    {
-      if (strcmp (default_protocol, gftp_protocols[i].name) == 0)
-        combo_num = i;
-      tempwid = gtk_list_item_new_with_label (gftp_protocols[i].name);
-      gtk_widget_show (tempwid);
-      combo_list = g_list_append (combo_list, tempwid);
-    }
-  gtk_list_prepend_items (GTK_LIST (GTK_COMBO (def_proto_combo)->list), 
-                          combo_list); 
-  gtk_list_select_item (GTK_LIST (GTK_COMBO (def_proto_combo)->list), 
-                        combo_num);
-
-  combo_list = NULL;
-  for (i = 0; proxy_type[i].key != NULL; i++)
-    {
-      tempwid = gtk_list_item_new_with_label (_(proxy_type[i].key));
-      gtk_widget_show (tempwid);
-      combo_list = g_list_append (combo_list, tempwid);
-    }
-  gtk_list_prepend_items (GTK_LIST (GTK_COMBO (proxy_combo)->list), combo_list);
-  combo_list = NULL;
-
-  custom_proxy = g_malloc0 (1);
-  if (proxy_config == NULL || *proxy_config == '\0')
-    combo_num = 0;
-  else
-    {
-      pos = proxy_config;
-      while ((endpos = strstr (pos, "%n")))
-        {
-          *endpos = '\0';
-          oldstr = custom_proxy;
-          custom_proxy = g_strconcat (custom_proxy, pos, "\n", NULL);
-          g_free (oldstr);
-          *endpos = '%';
-          pos = endpos + 2;
-        }
-
-      for (combo_num = 1; combo_num < GFTP_CUSTOM_PROXY_NUM; combo_num++)
-        {
-          if (strcmp (proxy_type[combo_num].description, custom_proxy) == 0)
-            break;
-        }
-    }
-
-  gtk_signal_connect (GTK_OBJECT (GTK_COMBO (proxy_combo)->list),
-                      "select_child", GTK_SIGNAL_FUNC (proxy_toggle), NULL);
-  gtk_list_select_item (GTK_LIST (GTK_COMBO (proxy_combo)->list), combo_num);
-
-  make_proxy_hosts_tab (notebook);
-#endif
-
 #if GTK_MAJOR_VERSION == 1
   tempwid = gtk_button_new_with_label (_("OK"));
   GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
-                      TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (option_data.dialog)->action_area), 
+                      tempwid, TRUE, TRUE, 0);
   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
                       GTK_SIGNAL_FUNC (apply_changes), NULL);
   gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked",
                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
-                             GTK_OBJECT (dialog));
+                             GTK_OBJECT (option_data.dialog));
   gtk_widget_show (tempwid);
 
   tempwid = gtk_button_new_with_label (_("  Cancel  "));
   GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
-                      TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (option_data.dialog)->action_area), 
+                      tempwid, TRUE, TRUE, 0);
   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
                       GTK_SIGNAL_FUNC (clean_old_changes), NULL);
   gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked",
                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
-                             GTK_OBJECT (dialog));
+                             GTK_OBJECT (option_data.dialog));
   gtk_widget_show (tempwid);
 
   tempwid = gtk_button_new_with_label (_("Apply"));
   GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
-                      TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (option_data.dialog)->action_area), 
+                      tempwid, TRUE, TRUE, 0);
   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
                       GTK_SIGNAL_FUNC (apply_changes), NULL);
   gtk_widget_grab_default (tempwid);
   gtk_widget_show (tempwid);
 #else
-  g_signal_connect (GTK_OBJECT (dialog), "response",
+  g_signal_connect (GTK_OBJECT (option_data.dialog), "response",
                     G_CALLBACK (options_action), NULL);
 #endif
 
-  gtk_widget_show (dialog);
+  gtk_widget_show (option_data.dialog);
 }
 
--- a/src/gtk/transfer.c	Fri Apr 18 16:02:38 2003 +0000
+++ b/src/gtk/transfer.c	Fri Apr 18 19:38:34 2003 +0000
@@ -706,8 +706,6 @@
         }
       else
         {
-          /* FIXME - this needs cleaned up. NOTE: view/edit file will be 
-             broken if the file has to be resumed */
           if (curfle->is_fd)
             {
               if (transfer->transfer_direction == GFTP_DIRECTION_DOWNLOAD)