changeset 341:eedc2c5727fa

2003-12-28 Brian Masney <masneyb@gftp.org> **** NOTE: this commit breaks a lot of functionality in gftp. I **** **** still have more work to do on this. Please don't email me **** **** saying that the CVS code is broken. **** * lib/bookmark.c lib/gftp.h lib/local.c lib/options.h lib/rfc2068.c lib/rfc959.c lib/sshv2.c - moved the use_threads option from the request structure over to the protocol declaration in options.h. * lib/options.h src/gtk/gftp-gtk.c - added cmd_in_gui option. When this option is enabled, a new toolbar will be shown in the GTK+ port that will allow you to control the GUI by entering manual commands. * src/Makefile.am - added uicommon directory * src/gtk/Makefile.am src/text/Makefile.am - link in the uicommon library. * src/uicommon/* src/text/gftp-text.c - moved most of the functionality of the text port over to the uicommon directory. Made this code a little more generic so that the GTK+ port can have a text interface associated with it. * src/gtk/gtkui.c src/gtk/gftp-gtk.c src/gtk/mkdir_dialog.c src/gtk/rename_dialog.c src/gtk/menu-items.c src/gtk/misc-gtk.c - started to clean up the callback functions and make them more tightly integrated with the uicommon code. * src/gtk/bookmarks.c src/gtk/chmod_dialog.c src/gtk/delete_dialog.c src/gtk/gftp-gtk.c src/gtk/menu-items.c src/gtk/misc-gtk.c src/gtk/transfer.c - s/refresh/gftpui_refresh/g s/jmp_environment/gftpui_common_jmp_environment/g s/request->use_threads/gftpui_common_use_threads (request)/g * src/gtk/options_dialog.c (apply_changes) - whenever the options are saved, check to see if the command entry needs to be shown or hidden.
author masneyb
date Sun, 28 Dec 2003 16:02:07 +0000
parents c45fdcb87667
children 07d635081926
files ChangeLog lib/bookmark.c lib/gftp.h lib/local.c lib/options.h lib/rfc2068.c lib/rfc959.c lib/sshv2.c src/Makefile.am src/gtk/Makefile.am src/gtk/bookmarks.c src/gtk/chmod_dialog.c src/gtk/delete_dialog.c src/gtk/gftp-gtk.c src/gtk/gftp-gtk.h src/gtk/menu-items.c src/gtk/misc-gtk.c src/gtk/mkdir_dialog.c src/gtk/options_dialog.c src/gtk/rename_dialog.c src/gtk/transfer.c src/text/Makefile.am src/text/gftp-text.c src/text/gftp-text.h src/uicommon/Makefile.am src/uicommon/gftpui.c src/uicommon/gftpui.h src/uicommon/gftpuicallbacks.c
diffstat 28 files changed, 1430 insertions(+), 1521 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Dec 20 22:00:04 2003 +0000
+++ b/ChangeLog	Sun Dec 28 16:02:07 2003 +0000
@@ -1,3 +1,42 @@
+2003-12-28 Brian Masney <masneyb@gftp.org>
+
+	**** NOTE: this commit breaks a lot of functionality in gftp. I ****
+	**** still have more work to do on this. Please don't email me  ****
+	**** saying that the CVS code is broken.                        ****
+
+	* lib/bookmark.c lib/gftp.h lib/local.c lib/options.h lib/rfc2068.c
+	lib/rfc959.c lib/sshv2.c - moved the use_threads option from the
+	request structure over to the protocol declaration in options.h.
+
+	* lib/options.h src/gtk/gftp-gtk.c - added cmd_in_gui option. When this
+	option is enabled, a new toolbar will be shown in the GTK+ port that
+	will allow you to control the GUI by entering manual commands.
+
+	* src/Makefile.am - added uicommon directory
+
+	* src/gtk/Makefile.am src/text/Makefile.am - link in the uicommon
+	library.
+
+	* src/uicommon/* src/text/gftp-text.c - moved most of the functionality
+	of the text port over to the uicommon directory. Made this code a little
+	more generic so that the GTK+ port can have a text interface
+	associated with it.
+
+	* src/gtk/gtkui.c src/gtk/gftp-gtk.c src/gtk/mkdir_dialog.c
+	src/gtk/rename_dialog.c src/gtk/menu-items.c src/gtk/misc-gtk.c -
+	started to clean up the callback functions and make them more tightly
+	integrated with the uicommon code.
+
+	* src/gtk/bookmarks.c src/gtk/chmod_dialog.c src/gtk/delete_dialog.c
+	src/gtk/gftp-gtk.c src/gtk/menu-items.c src/gtk/misc-gtk.c
+	src/gtk/transfer.c -
+	s/refresh/gftpui_refresh/g
+	s/jmp_environment/gftpui_common_jmp_environment/g
+	s/request->use_threads/gftpui_common_use_threads (request)/g
+
+	* src/gtk/options_dialog.c (apply_changes) - whenever the options are
+	saved, check to see if the command entry needs to be shown or hidden.
+
 2003-12-10 Brian Masney <masneyb@gftp.org>
 	* lib/rfc959.c - fix IPv6 compile problem when IPv6 support is not
 	available on the system.
@@ -1843,7 +1882,7 @@
 
 	* cvsclean - added this script
 
-	* *.[ch] - added $Id: ChangeLog,v 1.186 2003/12/13 21:01:49 masneyb Exp $ tags
+	* *.[ch] - added $Id: ChangeLog,v 1.187 2003/12/28 16:01:57 masneyb Exp $ tags
 
 	* debian/* - updated files from Debian maintainer
 
--- a/lib/bookmark.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/lib/bookmark.c	Sun Dec 28 16:02:07 2003 +0000
@@ -87,7 +87,6 @@
   request->url_prefix = "bookmark";
   request->need_hostport = 0;
   request->need_userpass = 0;
-  request->use_threads = 0;
   request->use_cache = 0;
   request->always_connected = 0;
 
--- a/lib/gftp.h	Sat Dec 20 22:00:04 2003 +0000
+++ b/lib/gftp.h	Sun Dec 28 16:02:07 2003 +0000
@@ -149,8 +149,12 @@
 #define GFTP_DIRTYPE_OTHER 	7
 
 /* Error types */
-#define GFTP_ERETRYABLE		-1
-#define GFTP_EFATAL		-2
+#define GFTP_ERETRYABLE		-1		/* Temporary failure. The GUI
+						   should wait briefly */
+#define GFTP_EFATAL		-2		/* Fatal error */
+#define GFTP_ERETRYABLE_NO_WAIT	-3		/* Temporary failure. The GUI
+						   should not wait and should
+						   reconnect */
 
 /* Some general settings */
 #define BASE_CONF_DIR		"~/.gftp"
@@ -345,8 +349,6 @@
                need_hostport : 1,
                need_userpass : 1,
                use_cache : 1,           /* Enable or disable the cache */
-               use_threads : 1,         /* Whether we need to spawn a thread
-                                           for this protocol */
                cached : 1,              /* Is this directory listing cached? */
                cancel : 1,		/* If a signal is received, should
 					   we cancel this operation */
@@ -503,9 +505,12 @@
   int (*init) (gftp_request * request);		/* Init function */
   void (*register_options) (void);		/* Protocol options */
   char *url_prefix;				/* URL Prefix */
-  int shown;					/* Whether this protocol is 
+  unsigned int shown : 1,			/* Whether this protocol is 
                                                    shown or not to the user in 
                                                    the protocol dropdown box */
+               use_threads : 1;			/* Whether or not operations in
+						   this protocol should use
+						   threads */
 } supported_gftp_protocols;
 
 
--- a/lib/local.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/lib/local.c	Sun Dec 28 16:02:07 2003 +0000
@@ -300,7 +300,7 @@
 
   /* the struct passwd and struct group are not thread safe. But,
      we're ok here because I have threading turned off for the local
-     protocol (see use_threads in local_init above) */
+     protocol (see use_threads in gftp_protocols in options.h) */
   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 (fle != NULL, GFTP_EFATAL);
@@ -670,7 +670,6 @@
   request->need_hostport = 0;
   request->need_userpass = 0;
   request->use_cache = 0;
-  request->use_threads = 0;
   request->always_connected = 1;
 
   lpd = g_malloc0 (sizeof (*lpd));
--- a/lib/options.h	Sat Dec 20 22:00:04 2003 +0000
+++ b/lib/options.h	Sun Dec 28 16:02:07 2003 +0000
@@ -88,6 +88,9 @@
   {"show_trans_in_title", N_("Show transfer status in title"), 
    gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 0,
    N_("Show the file transfer status in the titlebar"), GFTP_PORT_GTK, NULL},
+  {"cmd_in_gui", N_("Allow manual commands in GUI"), 
+   gftp_option_type_checkbox, GINT_TO_POINTER(0), NULL, 0,
+   N_("Allow entering manual commands in the GUI (functions like the text port)"), GFTP_PORT_GTK, NULL},
 
   {"", N_("Network"), gftp_option_type_notebook, NULL, NULL, 
    GFTP_CVARS_FLAGS_SHOW_BOOKMARK, NULL, GFTP_PORT_GTK, NULL},
@@ -209,16 +212,16 @@
 
 supported_gftp_protocols gftp_protocols[] =
 {
-  {N_("FTP"), rfc959_init, rfc959_register_module, "ftp", 1},
-  {N_("HTTP"), rfc2068_init, rfc2068_register_module, "http", 1},
+  {N_("FTP"), rfc959_init, rfc959_register_module, "ftp", 1, 1},
+  {N_("HTTP"), rfc2068_init, rfc2068_register_module, "http", 1, 1},
 #ifdef USE_SSL
-  {N_("HTTPS"), https_init, https_register_module, "https", 1},
+  {N_("HTTPS"), https_init, https_register_module, "https", 1, 1},
 #else
-  {N_("HTTPS"), https_init, https_register_module, "https", 0},
+  {N_("HTTPS"), https_init, https_register_module, "https", 0, 1},
 #endif
-  {N_("Local"), local_init, local_register_module, "file", 1},
-  {N_("SSH2"), sshv2_init, sshv2_register_module, "ssh2", 1},
-  {N_("Bookmark"), bookmark_init, bookmark_register_module, "bookmark", 0},
+  {N_("Local"), local_init, local_register_module, "file", 1, 0},
+  {N_("SSH2"), sshv2_init, sshv2_register_module, "ssh2", 1, 1},
+  {N_("Bookmark"), bookmark_init, bookmark_register_module, "bookmark", 0, 0},
   {NULL, NULL, NULL, NULL, 0}
 };
 
--- a/lib/rfc2068.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/lib/rfc2068.c	Sun Dec 28 16:02:07 2003 +0000
@@ -947,7 +947,6 @@
   request->need_hostport = 1;
   request->need_userpass = 0;
   request->use_cache = 1;
-  request->use_threads = 1;
   request->always_connected = 1;
 
   request->protocol_data = g_malloc0 (sizeof (rfc2068_params));
--- a/lib/rfc959.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/lib/rfc959.c	Sun Dec 28 16:02:07 2003 +0000
@@ -1774,7 +1774,6 @@
   request->need_hostport = 1;
   request->need_userpass = 1;
   request->use_cache = 1;
-  request->use_threads = 1;
   request->always_connected = 0;
 
   request->protocol_data = g_malloc0 (sizeof (rfc959_parms));
--- a/lib/sshv2.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/lib/sshv2.c	Sun Dec 28 16:02:07 2003 +0000
@@ -2299,7 +2299,6 @@
   request->need_hostport = 1;
   request->need_userpass = 1;
   request->use_cache = 1;
-  request->use_threads = 1;
   request->always_connected = 0;
   request->protocol_data = g_malloc0 (sizeof (sshv2_params));
   request->server_type = GFTP_DIRTYPE_UNIX;
--- a/src/Makefile.am	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/Makefile.am	Sun Dec 28 16:02:07 2003 +0000
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS=text gtk
+SUBDIRS=uicommon text gtk
 bin_SCRIPTS=gftp
 EXTRA_DIST=gftp.in
--- a/src/gtk/Makefile.am	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/Makefile.am	Sun Dec 28 16:02:07 2003 +0000
@@ -3,9 +3,9 @@
 bin_PROGRAMS = @GFTP_GTK@
 EXTRA_PROGRAMS = gftp-gtk
 gftp_gtk_SOURCES = bookmarks.c chmod_dialog.c delete_dialog.c dnd.c \
-                     gftp-gtk.c menu-items.c misc-gtk.c mkdir_dialog.c \
-                     options_dialog.c rename_dialog.c transfer.c view_dialog.c
+                     gftp-gtk.c gtkui.c menu-items.c misc-gtk.c \
+                     options_dialog.c transfer.c view_dialog.c
 INCLUDES = @GTK_CFLAGS@ @PTHREAD_CFLAGS@ -DSHARE_DIR=\"$(datadir)/gftp\" -I../../intl
-LDADD = ../../lib/libgftp.a @GTK_LIBS@ @PTHREAD_LIBS@ @EXTRA_LIBS@ @GTHREAD_LIBS@ @SSL_LIBS@
+LDADD = ../../lib/libgftp.a ../uicommon/libgftpui.a @GTK_LIBS@ @PTHREAD_LIBS@ @EXTRA_LIBS@ @GTHREAD_LIBS@ @SSL_LIBS@
 noinst_HEADERS = gftp-gtk.h
 localedir = $(datadir)/locale
--- a/src/gtk/bookmarks.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/bookmarks.c	Sun Dec 28 16:02:07 2003 +0000
@@ -49,7 +49,7 @@
     return;
 
   if (refresh_local)
-    refresh (other_wdata);
+    gftpui_refresh (other_wdata);
 
   ftp_connect (current_wdata, current_wdata->request, 1);
 }
--- a/src/gtk/chmod_dialog.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/chmod_dialog.c	Sun Dec 28 16:02:07 2003 +0000
@@ -39,10 +39,10 @@
   gftp_lookup_request_option (wdata->request, "network_timeout", 
                               &network_timeout);
 
-  if (wdata->request->use_threads)
+  if (gftpui_common_use_threads (wdata->request))
     {
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
+      sj = sigsetjmp (gftpui_common_jmp_environment, 1);
+      gftpui_common_use_jmp_environment = 1;
     }
   else
     sj = 0;
@@ -74,8 +74,8 @@
                                         _("Operation canceled\n"));
     }
 
-  if (wdata->request->use_threads)
-    use_jmp_environment = 0;
+  if (gftpui_common_use_threads (wdata->request))
+    gftpui_common_use_jmp_environment = 0;
 
   wdata->request->stopable = 0;
   return (GINT_TO_POINTER (success));
@@ -125,9 +125,9 @@
   if (check_reconnect (wdata) < 0)
     return;
 
-  ret = GPOINTER_TO_INT (generic_thread (do_chmod_thread, wdata));
+  ret = GPOINTER_TO_INT (gftpui_generic_thread (do_chmod_thread, wdata));
   if (ret)
-    refresh (wdata);
+    gftpui_refresh (wdata);
 }
 
 
@@ -157,8 +157,7 @@
   int num;
 
   wdata = data;
-  if (!check_status (_("Chmod"), wdata, wdata->request->use_threads, 0, 1, 
-                     wdata->request->chmod != NULL))
+  if (!check_status (_("Chmod"), wdata, gftpui_common_use_threads (wdata->request), 0, 1, wdata->request->chmod != NULL))
     return;
 
 #if GTK_MAJOR_VERSION == 1
--- a/src/gtk/delete_dialog.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/delete_dialog.c	Sun Dec 28 16:02:07 2003 +0000
@@ -40,10 +40,10 @@
 
   transfer = data;
 
-  if (transfer->fromreq->use_threads)
+  if (gftpui_common_use_threads (transfer->fromreq))
     {
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
+      sj = sigsetjmp (gftpui_common_jmp_environment, 1);
+      gftpui_common_use_jmp_environment = 1;
     }
   else
     sj = 0;
@@ -91,8 +91,8 @@
 
   transfer->fromreq->stopable = 0;
 
-  if (transfer->fromreq->use_threads)
-    use_jmp_environment = 0;
+  if (gftpui_common_use_threads (transfer->fromreq))
+    gftpui_common_use_jmp_environment = 0;
 
   return (NULL);
 }
@@ -113,7 +113,7 @@
 
   gtk_clist_freeze (GTK_CLIST (wdata->listbox));
   gftp_swap_socks (transfer->fromreq, wdata->request);
-  if (wdata->request->use_threads)
+  if (gftpui_common_use_threads (wdata->request))
     {
       wdata->request->stopable = 1;
       transfer->fromreq->stopable = 1;
@@ -142,7 +142,7 @@
   if (!GFTP_IS_CONNECTED (wdata->request))
     disconnect (wdata);
   else
-    refresh (wdata);
+    gftpui_refresh (wdata);
 
   gtk_clist_thaw (GTK_CLIST (wdata->listbox));
 }
@@ -173,7 +173,7 @@
   void *ret;
 
   wdata = data;
-  if (!check_status (_("Delete"), wdata, wdata->request->use_threads, 0, 1, 1))
+  if (!check_status (_("Delete"), wdata, gftpui_common_use_threads (wdata->request), 0, 1, 1))
     return;
 
   transfer = g_malloc0 (sizeof (*transfer));
@@ -202,7 +202,7 @@
 
   gftp_swap_socks (transfer->fromreq, wdata->request);
 
-  if (transfer->fromreq->use_threads)
+  if (gftpui_common_use_threads (transfer->fromreq))
     {
       wdata->request->stopable = 1;
       transfer->fromreq->stopable = 1;
--- a/src/gtk/gftp-gtk.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/gftp-gtk.c	Sun Dec 28 16:02:07 2003 +0000
@@ -22,11 +22,11 @@
 
 static GtkItemFactory *log_factory, *dl_factory;
 static GtkWidget * local_frame, * remote_frame, * log_table, * transfer_scroll,
-                 * openurl_btn;
+                 * openurl_btn, * gftpui_command_toolbar;
 
 gftp_window_data window1, window2, *other_wdata, *current_wdata;
 GtkWidget * stop_btn, * hostedit, * useredit, * passedit, * portedit, * logwdw,
-          * dlwdw, * protocol_menu, * optionmenu;
+          * dlwdw, * protocol_menu, * optionmenu, * gftpui_command_widget;
 GtkAdjustment * logwdw_vadj;
 #if GTK_MAJOR_VERSION > 1
 GtkTextMark * logwdw_textmark;
@@ -38,8 +38,6 @@
 pthread_mutex_t transfer_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
 gftp_graphic * gftp_icon;
-sigjmp_buf jmp_environment;
-volatile int use_jmp_environment = 0;
 pthread_t main_thread_id;
 GList * viewedit_processes = NULL;
 volatile sig_atomic_t viewedit_process_done;
@@ -141,15 +139,6 @@
     doexit (widget, data);
 }
 
-/* This function is only here because the callback function cannot have a
-   return value and chdir_dialog() does */
-
-static void
-chfunc (gpointer data)
-{
-  chdir_dialog (data);
-}
-
 
 static GtkWidget *
 CreateMenus (GtkWidget * parent)
@@ -183,15 +172,15 @@
     {N_("/Local/Deselect All"), NULL, deselectall, 0, MN_(NULL)},
     {N_("/Local/sep"), NULL, 0, 0, MN_("<Separator>")},
     {N_("/Local/Save Directory Listing..."), NULL, save_directory_listing, 0, MN_(NULL)},
-    {N_("/Local/Send SITE Command..."), NULL, site_dialog, 0, MN_(NULL)},
-    {N_("/Local/Change Directory"), NULL, chfunc, 0, MN_(NULL)},
+    {N_("/Local/Send SITE Command..."), NULL, gftpui_site_dialog, 0, MN_(NULL)},
+    {N_("/Local/Change Directory"), NULL, gftpui_chdir_dialog, 0, MN_(NULL)},
     {N_("/Local/Chmod..."), NULL, chmod_dialog, 0, MN_(NULL)},
-    {N_("/Local/Make Directory..."), NULL, mkdir_dialog, 0, MN_(NULL)},
-    {N_("/Local/Rename..."), NULL, rename_dialog, 0, MN_(NULL)},
+    {N_("/Local/Make Directory..."), NULL, gftpui_mkdir_dialog, 0, MN_(NULL)},
+    {N_("/Local/Rename..."), NULL, gftpui_rename_dialog, 0, MN_(NULL)},
     {N_("/Local/Delete..."), NULL, delete_dialog, 0, MN_(NULL)},
     {N_("/Local/Edit..."), NULL, edit_dialog, 0, MN_(NULL)},
     {N_("/Local/View..."), NULL, view_dialog, 0, MN_(NULL)},
-    {N_("/Local/Refresh"), NULL, refresh, 0, MS_(GTK_STOCK_REFRESH)},
+    {N_("/Local/Refresh"), NULL, gftpui_refresh, 0, MS_(GTK_STOCK_REFRESH)},
     {N_("/_Remote"), NULL, 0, 0, MN_("<Branch>")},
     {N_("/Remote/tearoff"), NULL, 0, 0, MN_("<Tearoff>")},
     {N_("/Remote/Open _URL..."), "<control>U", openurl_dialog, 0,
@@ -206,15 +195,15 @@
     {N_("/Remote/Deselect All"), NULL, deselectall, 0, MN_(NULL)},
     {N_("/Remote/sep"), NULL, 0, 0, MN_("<Separator>")},
     {N_("/Remote/Save Directory Listing..."), NULL, save_directory_listing, 0, MN_(NULL)},
-    {N_("/Remote/Send SITE Command..."), NULL, site_dialog, 0, MN_(NULL)},
-    {N_("/Remote/Change Directory"), NULL, chfunc, 0, MN_(NULL)},
+    {N_("/Remote/Send SITE Command..."), NULL, gftpui_site_dialog, 0, MN_(NULL)},
+    {N_("/Remote/Change Directory"), NULL, gftpui_chdir_dialog, 0, MN_(NULL)},
     {N_("/Remote/Chmod..."), NULL, chmod_dialog, 0, MN_(NULL)},
-    {N_("/Remote/Make Directory..."), NULL, mkdir_dialog, 0, MN_(NULL)},
-    {N_("/Remote/Rename..."), NULL, rename_dialog, 0, MN_(NULL)},
+    {N_("/Remote/Make Directory..."), NULL, gftpui_mkdir_dialog, 0, MN_(NULL)},
+    {N_("/Remote/Rename..."), NULL, gftpui_rename_dialog, 0, MN_(NULL)},
     {N_("/Remote/Delete..."), NULL, delete_dialog, 0, MN_(NULL)},
     {N_("/Remote/Edit..."), NULL, edit_dialog, 0, MN_(NULL)},
     {N_("/Remote/View..."), NULL, view_dialog, 0, MN_(NULL)},
-    {N_("/Remote/Refresh"), NULL, refresh, 0, MS_(GTK_STOCK_REFRESH)},
+    {N_("/Remote/Refresh"), NULL, gftpui_refresh, 0, MS_(GTK_STOCK_REFRESH)},
     {N_("/_Bookmarks"), NULL, 0, 0, MN_("<Branch>")},
     {N_("/Bookmarks/tearoff"), NULL, 0, 0, MN_("<Tearoff>")},
     {N_("/Bookmarks/Add bookmark"), "<control>A", add_bookmark, 0,
@@ -336,7 +325,7 @@
 
 
 static GtkWidget *
-CreateToolbar (GtkWidget * parent)
+CreateConnectToolbar (GtkWidget * parent)
 {
   const GtkTargetEntry possible_types[] = {
     {"STRING", 0, 0},
@@ -473,10 +462,34 @@
   gtk_box_pack_start (GTK_BOX (box), stop_btn, FALSE, FALSE, 0);
 
   gtk_widget_grab_focus (GTK_COMBO (hostedit)->entry);
+
   return (toolbar);
 }
 
 
+static GtkWidget *
+CreateCommandToolbar (void)
+{
+  GtkWidget * box, * tempwid;
+
+  gftpui_command_toolbar = gtk_handle_box_new ();
+
+  box = gtk_hbox_new (FALSE, 4);
+  gtk_container_add (GTK_CONTAINER (gftpui_command_toolbar), box);
+  gtk_container_border_width (GTK_CONTAINER (box), 5);
+
+  tempwid = gtk_label_new (_("Command: "));
+  gtk_box_pack_start (GTK_BOX (box), tempwid, FALSE, FALSE, 0);
+
+  gftpui_command_widget = gtk_entry_new ();
+  gtk_box_pack_start (GTK_BOX (box), gftpui_command_widget, TRUE, TRUE, 0);
+  gtk_signal_connect (GTK_OBJECT (gftpui_command_widget), "activate",
+		      GTK_SIGNAL_FUNC (gftpui_run_command), NULL);
+
+  return (gftpui_command_toolbar);
+}
+
+
 static void
 setup_column (GtkWidget * listbox, int column, int width)
 {
@@ -492,10 +505,11 @@
 static void
 list_doaction (gftp_window_data * wdata)
 {
-  int num, dir, success;
   intptr_t list_dblclk_action;
   GList *templist, *filelist;
+  int num, dir, success;
   gftp_file *tempfle;
+  char *directory;
 
   gftp_lookup_request_option (wdata->request, "list_dblclk_action", 
                               &list_dblclk_action);
@@ -507,13 +521,18 @@
   tempfle = (gftp_file *) filelist->data;
 
   dir = tempfle->isdir;
-  success = 0;
 
   if (check_reconnect (wdata) < 0) 
     return;
 
   if (tempfle->islink || tempfle->isdir)
-    success = chdir_dialog (wdata);
+    {
+      directory = gftp_build_path (wdata->request->directory, tempfle->file, NULL);
+      success = gftpui_run_chdir (wdata, directory);
+      g_free (directory);
+    }
+  else
+    success = 0;
 
   if (!dir && !success)
     {
@@ -749,7 +768,10 @@
   tempwid = CreateMenus (ui);
   gtk_box_pack_start (GTK_BOX (mainvbox), tempwid, FALSE, FALSE, 0);
 
-  tempwid = CreateToolbar (ui);
+  tempwid = CreateConnectToolbar (ui);
+  gtk_box_pack_start (GTK_BOX (mainvbox), tempwid, FALSE, FALSE, 0);
+
+  tempwid = CreateCommandToolbar ();
   gtk_box_pack_start (GTK_BOX (mainvbox), tempwid, FALSE, FALSE, 0);
 
   winpane = gtk_hpaned_new ();
@@ -887,6 +909,7 @@
   gtk_box_pack_start (GTK_BOX (mainvbox), logpane, TRUE, TRUE, 0);
 
   gtk_widget_show_all (mainvbox);
+  gftpui_show_or_hide_command ();
   return (mainvbox);
 }
 
@@ -1123,8 +1146,8 @@
 
   signal (SIGCHLD, sig_child);
   signal (SIGPIPE, SIG_IGN);
-  signal (SIGALRM, signal_handler);
-  signal (SIGINT, signal_handler);
+  signal (SIGALRM, gftpui_common_signal_handler);
+  signal (SIGINT, gftpui_common_signal_handler);
 
   graphic_hash_table = g_hash_table_new (string_hash_function, string_hash_compare);
  
@@ -1163,13 +1186,7 @@
   gtk_container_add (GTK_CONTAINER (window), ui);
   gtk_widget_show (window);
 
-  ftp_log (gftp_logging_misc, NULL,
-	   "%s, Copyright (C) 1998-2003 Brian Masney <", gftp_version);
-  ftp_log (gftp_logging_recv, NULL, "masneyb@gftp.org");
-  ftp_log (gftp_logging_misc, NULL,
-	   _(">. If you have any questions, comments, or suggestions about this program, please feel free to email them to me. You can always find out the latest news about gFTP from my website at http://www.gftp.org/\n"));
-  ftp_log (gftp_logging_misc, NULL,
-	   _("gFTP comes with ABSOLUTELY NO WARRANTY; for details, see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; for details, see the COPYING file\n"));
+  gftpui_common_about (ftp_log, NULL);
 
   gtk_timeout_add (1000, update_downloads, NULL);
   if (gftp_protocols[GFTP_LOCAL_NUM].init (window1.request) == 0)
@@ -1188,6 +1205,9 @@
   sortrows (GTK_CLIST (window2.listbox), -1, &window2);
 
   init_gftp (argc, argv, window);
+  gftpui_common_init (&window1, window1.request,
+                      &window2, window2.request);
+
 
   GDK_THREADS_ENTER ();
   gtk_main ();
@@ -1195,4 +1215,15 @@
   return (0);
 }
 
+void
+gftpui_show_or_hide_command (void)
+{
+  intptr_t cmd_in_gui;
 
+  gftp_lookup_global_option ("cmd_in_gui", &cmd_in_gui);
+  if (cmd_in_gui)
+    gtk_widget_show (gftpui_command_toolbar);
+  else
+    gtk_widget_hide (gftpui_command_toolbar);
+}
+
--- a/src/gtk/gftp-gtk.h	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/gftp-gtk.h	Sun Dec 28 16:02:07 2003 +0000
@@ -23,6 +23,7 @@
 #define __GFTP_GTK_H
 
 #include "../../lib/gftp.h"
+#include "../uicommon/gftpui.h"
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 #include <pthread.h>
@@ -171,7 +172,8 @@
 
 extern gftp_window_data window1, window2, * other_wdata, * current_wdata;
 extern GtkWidget * stop_btn, * hostedit, * useredit, * passedit,
-                 * portedit, * logwdw, * dlwdw, * protocol_menu, * optionmenu;
+                 * portedit, * logwdw, * dlwdw, * protocol_menu, * optionmenu,
+                 * gftpui_command_widget;
 extern GtkAdjustment * logwdw_vadj;
 #if GTK_MAJOR_VERSION > 1
 extern GtkTextMark * logwdw_textmark;
@@ -182,8 +184,6 @@
 extern GtkItemFactory * factory;
 extern pthread_mutex_t transfer_mutex, log_mutex;
 extern gftp_graphic * gftp_icon;
-extern sigjmp_buf jmp_environment;
-extern volatile int use_jmp_environment;
 extern pthread_t main_thread_id;
 extern GList * viewedit_processes;
 extern volatile sig_atomic_t viewedit_process_done;
@@ -241,6 +241,29 @@
 void stop_button				( GtkWidget * widget,
 						  gpointer data );
 
+void gftpui_show_or_hide_command 		( void );
+
+/* gtkui.c */
+void gftpui_run_command 			( GtkWidget * widget,
+						  gpointer data );
+
+void gftpui_run_function_callback 		( gftp_window_data * wdata,
+						  gftp_dialog_data * ddata );
+
+void gftpui_run_function_cancel_callback 	( gftp_window_data * wdata,
+						  gftp_dialog_data * ddata );
+
+void gftpui_mkdir_dialog 			( gpointer data );
+
+void gftpui_rename_dialog			( gpointer data );
+
+void gftpui_site_dialog 			( gpointer data );
+
+int gftpui_run_chdir 				( gpointer uidata,
+						  char *directory );
+
+void gftpui_chdir_dialog 			( gpointer data );
+
 /* menu_items.c */
 void change_setting 				( gftp_window_data *wdata,
 						  int menuitem,
@@ -264,13 +287,9 @@
 
 void deselectall 				( gpointer data );
 
-void site_dialog 				( gpointer data );
-
 int chdir_edit					( GtkWidget * widget,
 						  gpointer data );
 
-int chdir_dialog 				( gpointer data );
-
 void clearlog 					( gpointer data );
 
 void viewlog 					( gpointer data );
@@ -293,8 +312,6 @@
 						  const char *string,
 						  ... ) GFTP_LOG_FUNCTION_ATTRIBUTES;
 
-void refresh 					( gftp_window_data * wdata );
-
 void update_window_info				( void );
 
 void update_window				( gftp_window_data * wdata );
@@ -359,22 +376,13 @@
 
 void update_directory_download_progress 	( gftp_transfer * transfer );
 
-void *generic_thread 				( void * (*func) 
-                                                         (void *), 
-						  gftp_window_data * wdata );
-
 int progress_timeout 				( gpointer data );
 
 void display_cached_logs			( void );
 
-RETSIGTYPE signal_handler			(int signo);
-
 char * get_xpm_path 				( char *filename, 
 						  int quit_on_err );
 
-/* mkdir_dialog.c */
-void mkdir_dialog 				( gpointer data );
-
 /* options_dialog.c */
 void options_dialog 				( gpointer data );
 
@@ -383,9 +391,6 @@
 
 void gftp_gtk_save_bookmark_options 		( gftp_bookmarks_var * bm );
 
-/* rename_dialog.c */
-void rename_dialog				( gpointer data );
-
 /* transfer.c */
 int ftp_list_files				( gftp_window_data * wdata,
 						  int usecache );
--- a/src/gtk/menu-items.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/menu-items.c	Sun Dec 28 16:02:07 2003 +0000
@@ -354,122 +354,6 @@
 }
 
 
-static void
-dosite (gftp_window_data * wdata, gftp_dialog_data * ddata)
-{
-  const char *edttext;
-
-  edttext = gtk_entry_get_text (GTK_ENTRY (ddata->edit));
-  if (*edttext == '\0')
-    {
-      ftp_log (gftp_logging_misc, NULL,
-               _("SITE: Operation canceled...you must enter a string\n"));
-      return;
-    }
-
-  if (check_reconnect (wdata) < 0)
-    return;
-  gftp_site_cmd (wdata->request, edttext);
-
-  if (!GFTP_IS_CONNECTED (wdata->request))
-    disconnect (wdata);
-}
-
-
-void
-site_dialog (gpointer data)
-{
-  gftp_window_data * wdata;
-
-  wdata = data;
-  if (!check_status (_("Site"), wdata, 0, 0, 0, wdata->request->site != NULL))
-    return;
-
-  MakeEditDialog (_("Site"), _("Enter site-specific command"), NULL, 1,
-                  NULL, gftp_dialog_button_ok, dosite, wdata, NULL, NULL);
-}
-
-
-static void *
-do_change_dir_thread (void * data)
-{
-  int success, sj;
-  intptr_t network_timeout;
-  gftp_window_data * wdata;
-
-  wdata = data;
-
-  if (wdata->request->use_threads)
-    {
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
-    }
-  else
-    sj = 0;
-
-  gftp_lookup_request_option (wdata->request, "network_timeout", 
-                              &network_timeout);
-
-  success = 0;
-  if (sj == 0) 
-    {
-      if (network_timeout > 0)
-        alarm (network_timeout);
-      success = gftp_set_directory (wdata->request, wdata->request->directory);
-      alarm (0);
-    }
-  else
-    {
-      gftp_disconnect (wdata->request);
-      wdata->request->logging_function (gftp_logging_error,
-                                        wdata->request,
-                                        _("Operation canceled\n"));
-    }
-
-  if (wdata->request->use_threads)
-    use_jmp_environment = 0;
-
-  wdata->request->stopable = 0;
-  return (GINT_TO_POINTER (success));
-}
-
-
-static int
-do_change_dir (gftp_window_data * wdata, char *directory)
-{
-  char *olddir;
-  int ret;
-
-  if (directory != wdata->request->directory)
-    {
-      olddir = wdata->request->directory;
-      wdata->request->directory = g_strdup (directory);
-    }
-  else
-    olddir = NULL;
-
-  ret = GPOINTER_TO_INT (generic_thread (do_change_dir_thread, wdata));
-
-  if (!GFTP_IS_CONNECTED (wdata->request))
-    {
-      disconnect (wdata);
-      if (olddir != NULL)
-        g_free (olddir);
-      return (-2);
-    }
-
-  if (ret != 0)
-    {
-      g_free (wdata->request->directory);
-      wdata->request->directory = olddir;
-    }
-  else
-    g_free (olddir);
-
-  return (ret);
-}
-
-
 int
 chdir_edit (GtkWidget * widget, gpointer data)
 {
@@ -478,85 +362,29 @@
   char *tempstr;
 
   wdata = data;
-  edttxt = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (wdata->combo)->entry));
+  if (!check_status (_("Chdir"), wdata, gftpui_common_use_threads (wdata->request), 1, 0,
+                     wdata->request->chdir != NULL))
+    return (0);
 
   if (check_reconnect (wdata) < 0)
     return (0);
 
+  edttxt = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (wdata->combo)->entry));
+
   if (!GFTP_IS_CONNECTED (wdata->request) && *edttxt != '\0')
     {
       toolbar_hostedit (NULL, NULL);
       return (0);
     }
 
-  if (!check_status (_("Chdir"), wdata, wdata->request->use_threads, 0, 0, 
-                     wdata->request->chdir != NULL))
-    return (FALSE);
-
   if ((tempstr = expand_path (edttxt)) == NULL)
     return (FALSE);
 
-  if (check_reconnect (wdata) < 0)
-    return (FALSE);
-
-  if (do_change_dir (wdata, tempstr) == 0)
-    {
-      gtk_clist_freeze (GTK_CLIST (wdata->listbox));
-      remove_files_window (wdata);
-      ftp_list_files (wdata, 1);
-      gtk_clist_thaw (GTK_CLIST (wdata->listbox));
-      add_history (wdata->combo, wdata->history, wdata->histlen, tempstr);
-    }
+  if (gftpui_run_chdir (wdata, tempstr))
+    add_history (wdata->combo, wdata->history, wdata->histlen, edttxt);
 
   g_free (tempstr);
-  return (FALSE);
-}
-
-
-int
-chdir_dialog (gpointer data)
-{
-  GList * templist, * filelist;
-  gftp_window_data * wdata;
-  char *newdir, *tempstr;
-  gftp_file *tempfle;
-  int num, ret;
-
-  wdata = data;
-  if (!check_status (_("Chdir"), wdata, wdata->request->use_threads, 1, 0, 
-                     wdata->request->chdir != NULL))
-    return (0);
-
-  filelist = wdata->files;
-  templist = GTK_CLIST (wdata->listbox)->selection;
-  num = 0;
-  templist = get_next_selection (templist, &filelist, &num);
-  tempfle = filelist->data;
-
-  newdir = gftp_build_path (wdata->request->directory, tempfle->file, NULL);
-
-  if ((tempstr = expand_path (newdir)) == NULL)
-    {
-      g_free (newdir);
-      return (0);
-    }
-
-  g_free (newdir);
-
-  if (check_reconnect (wdata) < 0)
-    return (0);
-
-  ret = 0; 
-  if (do_change_dir (wdata, tempstr) == 0)
-    {
-      gtk_clist_freeze (GTK_CLIST (wdata->listbox));
-      remove_files_window (wdata);
-      ftp_list_files (wdata, 1);
-      gtk_clist_thaw (GTK_CLIST (wdata->listbox));
-      ret = 1;
-    }
-  g_free (tempstr);
-  return (ret);
+  return (0);
 }
 
 
--- a/src/gtk/misc-gtk.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/misc-gtk.c	Sun Dec 28 16:02:07 2003 +0000
@@ -206,23 +206,6 @@
 
 
 void
-refresh (gftp_window_data * wdata)
-{
-  if (!check_status (_("Refresh"), wdata, 0, 0, 0, 1))
-    return;
-
-  if (check_reconnect (wdata) < 0) 
-    return;
-
-  gtk_clist_freeze (GTK_CLIST (wdata->listbox));
-  remove_files_window (wdata);
-  gftp_delete_cache_entry (wdata->request, NULL, 0);
-  ftp_list_files (wdata, 0);
-  gtk_clist_thaw (GTK_CLIST (wdata->listbox));
-}
-
-
-void
 update_window_info (void)
 {
   char *tempstr, empty[] = "";
@@ -895,6 +878,9 @@
 #else
   switch (okbutton)
     {
+      case gftp_dialog_button_ok:
+        yes_text = GTK_STOCK_OK;
+        break;
       case gftp_dialog_button_create:
         yes_text = GTK_STOCK_ADD;
         break;
@@ -966,6 +952,9 @@
 #if GTK_MAJOR_VERSION == 1
   switch (okbutton)
     {
+      case gftp_dialog_button_ok:
+        yes_text = GTK_STOCK_OK;
+        break;
       case gftp_dialog_button_create:
         yes_text = _("Add");
         break;
@@ -1168,40 +1157,6 @@
 }
 
 
-void *
-generic_thread (void * (*func) (void *), gftp_window_data * wdata)
-{
-  void * ret;
-
-  if (wdata->request->use_threads)
-    {
-      wdata->request->stopable = 1;
-      gtk_widget_set_sensitive (stop_btn, 1);
-      pthread_create (&wdata->tid, NULL, func, wdata);
-
-      while (wdata->request->stopable)
-        {
-          GDK_THREADS_LEAVE ();
-#if GTK_MAJOR_VERSION == 1
-          g_main_iteration (TRUE);
-#else
-          g_main_context_iteration (NULL, TRUE);
-#endif
-        }
-
-      pthread_join (wdata->tid, &ret);
-      gtk_widget_set_sensitive (stop_btn, 0);
-    }
-  else
-    ret = func (wdata);
-
-  if (!GFTP_IS_CONNECTED (wdata->request))
-    disconnect (wdata);
-
-  return (ret); 
-}
-
-
 int
 progress_timeout (gpointer data)
 {
@@ -1246,18 +1201,6 @@
 }
 
 
-RETSIGTYPE 
-signal_handler (int signo)
-{
-  signal (signo, signal_handler);
-
-  if (use_jmp_environment)
-    siglongjmp (jmp_environment, signo == SIGINT ? 1 : 2);
-  else if (signo == SIGINT)
-    exit (1);
-}
-
-
 char *
 get_xpm_path (char *filename, int quit_on_err)
 {
--- a/src/gtk/mkdir_dialog.c	Sat Dec 20 22:00:04 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*****************************************************************************/
-/*  mkdir_dialog.c - make directory dialog box and ftp routines              */
-/*  Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>                  */
-/*                                                                           */
-/*  This program is free software; you can redistribute it and/or modify     */
-/*  it under the terms of the GNU General Public License as published by     */
-/*  the Free Software Foundation; either version 2 of the License, or        */
-/*  (at your option) any later version.                                      */
-/*                                                                           */
-/*  This program is distributed in the hope that it will be useful,          */
-/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
-/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
-/*  GNU General Public License for more details.                             */
-/*                                                                           */
-/*  You should have received a copy of the GNU General Public License        */
-/*  along with this program; if not, write to the Free Software              */
-/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
-/*****************************************************************************/
-
-#include "gftp-gtk.h"
-static const char cvsid[] = "$Id$";
-
-static const char *edttext;
-
-
-static void *
-do_make_dir_thread (void * data)
-{
-  int success, sj;
-  intptr_t network_timeout;
-  gftp_window_data * wdata;
-
-  wdata = data;
-
-  gftp_lookup_request_option (wdata->request, "network_timeout", 
-                              &network_timeout);
-
-  if (wdata->request->use_threads)
-    {
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
-    }
-  else
-    sj = 0;
-
-  success = 0;
-  if (sj == 0)
-    {
-      if (network_timeout > 0)
-        alarm (network_timeout);
-      success = gftp_make_directory (wdata->request, edttext) == 0;
-      alarm (0);
-    }
-  else
-    {
-      gftp_disconnect (wdata->request);
-      wdata->request->logging_function (gftp_logging_error,
-                                        wdata->request,
-                                        _("Operation canceled\n"));
-    }
-
-  if (wdata->request->use_threads)
-    use_jmp_environment = 0;
-
-  wdata->request->stopable = 0;
-  return (GINT_TO_POINTER (success));
-}
-
-
-static void
-domkdir (gftp_window_data * wdata, gftp_dialog_data * ddata)
-{
-  int ret;
-
-  edttext = gtk_entry_get_text (GTK_ENTRY (ddata->edit));
-  if (*edttext == '\0')
-    {
-      ftp_log (gftp_logging_misc, NULL,
-	       _("Mkdir: Operation canceled...you must enter a string\n"));
-      return;
-    }
-
-  if (check_reconnect (wdata) < 0)
-    return;
-
-  ret = GPOINTER_TO_INT (generic_thread (do_make_dir_thread, wdata));
-  if (ret)
-    {
-      gftp_delete_cache_entry (wdata->request, NULL, 0);
-      refresh (wdata);
-    }
-}
-
-
-void
-mkdir_dialog (gpointer data)
-{
-  gftp_window_data * wdata;
-
-  wdata = data;
-  if (!check_status (_("Mkdir"), wdata, wdata->request->use_threads, 0, 0, 
-                     wdata->request->mkdir != NULL))
-    return;
-
-  MakeEditDialog (_("Make Directory"), _("Enter name of directory to create"),
-		  NULL, 1, NULL, gftp_dialog_button_create, domkdir, wdata, 
-                  NULL, NULL);
-}
-
--- a/src/gtk/options_dialog.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/options_dialog.c	Sun Dec 28 16:02:07 2003 +0000
@@ -719,6 +719,7 @@
 
   proxy_hosts->list = new_proxy_hosts;
   new_proxy_hosts = NULL;
+  gftpui_show_or_hide_command ();
 }
 
 
--- a/src/gtk/rename_dialog.c	Sat Dec 20 22:00:04 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*****************************************************************************/
-/*  rename_dialog.c - rename dialog box and ftp routines                     */
-/*  Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>                  */
-/*                                                                           */
-/*  This program is free software; you can redistribute it and/or modify     */
-/*  it under the terms of the GNU General Public License as published by     */
-/*  the Free Software Foundation; either version 2 of the License, or        */
-/*  (at your option) any later version.                                      */
-/*                                                                           */
-/*  This program is distributed in the hope that it will be useful,          */
-/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
-/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
-/*  GNU General Public License for more details.                             */
-/*                                                                           */
-/*  You should have received a copy of the GNU General Public License        */
-/*  along with this program; if not, write to the Free Software              */
-/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
-/*****************************************************************************/
-
-#include "gftp-gtk.h"
-static const char cvsid[] = "$Id$";
-
-static const char *edttext;
-static gftp_file * curfle;
-
-
-static void *
-do_rename_thread (void * data)
-{
-  int success, sj;
-  intptr_t network_timeout;
-  gftp_window_data * wdata;
-
-  wdata = data;
-
-  gftp_lookup_request_option (wdata->request, "network_timeout", 
-                              &network_timeout);
-
-  if (wdata->request->use_threads)
-    { 
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
-    }
-  else
-    sj = 0;
-
-  success = 0;
-  if (sj == 0)
-    {
-      if (network_timeout > 0)
-        alarm (network_timeout);
-      success = gftp_rename_file (wdata->request, curfle->file, edttext) == 0;
-      alarm (0);
-    }
-  else
-    {
-      gftp_disconnect (wdata->request);
-      wdata->request->logging_function (gftp_logging_error,
-                                        wdata->request,
-                                        _("Operation canceled\n"));
-    }
-
-  if (wdata->request->use_threads)
-    use_jmp_environment = 0;
-
-  wdata->request->stopable = 0;
-  return (GINT_TO_POINTER (success));
-}
-
-
-static void
-dorenCB (gftp_window_data * wdata, gftp_dialog_data * ddata)
-{
-  int ret;
-
-  edttext = gtk_entry_get_text (GTK_ENTRY (ddata->edit));
-  if (*edttext == '\0')
-    {
-      ftp_log (gftp_logging_misc, NULL,
-	       _("Rename: Operation canceled...you must enter a string\n"));
-      return;
-    }
-
-  if (check_reconnect (wdata) < 0) 
-    return;
-
-  ret = GPOINTER_TO_INT (generic_thread (do_rename_thread, wdata));
-  if (ret)
-    refresh ((gpointer) wdata);
-}
-
-
-void
-rename_dialog (gpointer data)
-{
-  GList *templist, *filelist;
-  gftp_window_data * wdata;
-  char *tempstr;
-  int num;
-
-  wdata = data;
-  if (!check_status (_("Rename"), wdata, wdata->request->use_threads, 1, 1, 
-                     wdata->request->rename != NULL))
-    return;
-
-  templist = GTK_CLIST (wdata->listbox)->selection;
-  num = 0;
-  filelist = wdata->files;
-  templist = get_next_selection (templist, &filelist, &num);
-  curfle = filelist->data;
-
-  tempstr = g_strdup_printf (_("What would you like to rename %s to?"), 
-                             curfle->file);
-  MakeEditDialog (_("Rename"), tempstr, curfle->file, 1, NULL,
-                  gftp_dialog_button_rename, dorenCB, wdata, NULL, NULL);
-  g_free (tempstr);
-}
-
--- a/src/gtk/transfer.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/gtk/transfer.c	Sun Dec 28 16:02:07 2003 +0000
@@ -79,10 +79,10 @@
 
   request = data;
   
-  if (request->use_threads)
+  if (gftpui_common_use_threads (request))
     {
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
+      sj = sigsetjmp (gftpui_common_jmp_environment, 1);
+      gftpui_common_use_jmp_environment = 1;
     }
   else
     sj = 0;
@@ -92,8 +92,8 @@
     {
       if (gftp_list_files (request) != 0 || !GFTP_IS_CONNECTED (request))
         {
-          if (request->use_threads)
-            use_jmp_environment = 0;
+          if (gftpui_common_use_threads (request))
+            gftpui_common_use_jmp_environment = 0;
 
           request->stopable = 0;
           if (request->wakeup_main_thread[1] > 0)
@@ -129,8 +129,8 @@
 
       if (!GFTP_IS_CONNECTED (request))
         {
-          if (request->use_threads)
-            use_jmp_environment = 0;
+          if (gftpui_common_use_threads (request))
+            gftpui_common_use_jmp_environment = 0;
 
           request->stopable = 0;
           if (request->wakeup_main_thread[1] > 0)
@@ -154,8 +154,8 @@
         }
     }
 
-  if (request->use_threads)
-    use_jmp_environment = 0;
+  if (gftpui_common_use_threads (request))
+    gftpui_common_use_jmp_environment = 0;
 
   request->stopable = 0;
   if (request->wakeup_main_thread[1] > 0)
@@ -180,7 +180,7 @@
 
       gtk_clist_freeze (GTK_CLIST (wdata->listbox));
       wdata->request->stopable = 1;
-      if (wdata->request->use_threads)
+      if (gftpui_common_use_threads (wdata->request))
         {
           gtk_widget_set_sensitive (stop_btn, 1);
 
@@ -251,10 +251,10 @@
   gftp_lookup_request_option (request, "network_timeout", &network_timeout);
 
   conn_num = 0;
-  if (request->use_threads)
+  if (gftpui_common_use_threads (request))
     {
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
+      sj = sigsetjmp (gftpui_common_jmp_environment, 1);
+      gftpui_common_use_jmp_environment = 1;
     }
   else
     sj = 0;
@@ -294,8 +294,8 @@
         }  
     }
 
-  if (request->use_threads)
-    use_jmp_environment = 0;
+  if (gftpui_common_use_threads (request))
+    gftpui_common_use_jmp_environment = 0;
 
   request->stopable = 0;
   if (request->wakeup_main_thread[1] > 0)
@@ -347,7 +347,7 @@
         gftp_set_password (request, "");
     }
 
-  if (wdata && wdata->request == request && request->use_threads)
+  if (wdata && wdata->request == request && gftpui_common_use_threads (request))
     {
       request->stopable = 1;
       if (wdata)       
@@ -455,8 +455,8 @@
       gftp_swap_socks (transfer->fromreq, fromwdata->request);
       gftp_swap_socks (transfer->toreq, towdata->request);
 
-      if (transfer->fromreq->use_threads || 
-          (transfer->toreq && transfer->toreq->use_threads))
+      if (gftpui_common_use_threads (transfer->fromreq) || 
+          (transfer->toreq && gftpui_common_use_threads (transfer->toreq)))
         {
           transfer->fromreq->stopable = 1;
           pthread_create (&fromwdata->tid, NULL, do_getdir_thread, transfer);
@@ -517,11 +517,11 @@
 
   transfer = data;
 
-  if (transfer->fromreq->use_threads || 
-      (transfer->toreq && transfer->toreq->use_threads))
+  if (gftpui_common_use_threads (transfer->fromreq) || 
+      (transfer->toreq && gftpui_common_use_threads (transfer->toreq)))
     {
-      sj = sigsetjmp (jmp_environment, 1);
-      use_jmp_environment = 1;
+      sj = sigsetjmp (gftpui_common_jmp_environment, 1);
+      gftpui_common_use_jmp_environment = 1;
     }
   else
     sj = 0;
@@ -539,9 +539,9 @@
                                            _("Operation canceled\n"));
     }
 
-  if (transfer->fromreq->use_threads || 
-      (transfer->toreq && transfer->toreq->use_threads))
-    use_jmp_environment = 0;
+  if (gftpui_common_use_threads (transfer->fromreq) || 
+      (transfer->toreq && gftpui_common_use_threads (transfer->toreq)))
+    gftpui_common_use_jmp_environment = 0;
 
   transfer->fromreq->stopable = 0;
   return (GINT_TO_POINTER (success));
@@ -1098,7 +1098,7 @@
   if (refresh_files && tdata->curfle && tdata->curfle->next &&
       compare_request (tdata->toreq, 
                        ((gftp_window_data *) tdata->towdata)->request, 1))
-    refresh (tdata->towdata);
+    gftpui_refresh (tdata->towdata);
 }
 
 
@@ -1253,7 +1253,7 @@
 
       if (tdata->towdata != NULL && compare_request (tdata->toreq,
                            ((gftp_window_data *) tdata->towdata)->request, 1))
-        refresh (tdata->towdata);
+        gftpui_refresh (tdata->towdata);
 
       num_transfers_in_progress--;
     }
--- a/src/text/Makefile.am	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/text/Makefile.am	Sun Dec 28 16:02:07 2003 +0000
@@ -2,8 +2,8 @@
 
 bin_PROGRAMS = @GFTP_TEXT@
 EXTRA_PROGRAMS = gftp-text
-gftp_text_SOURCES=gftp-text.c 
+gftp_text_SOURCES=gftp-text.c textui.c
 INCLUDES=@GLIB_CFLAGS@ -DSHARE_DIR=\"$(datadir)/gftp\" -I../../intl
-LDADD = ../../lib/libgftp.a @GLIB_LIBS@ @EXTRA_LIBS@ @READLINE_LIBS@ @SSL_LIBS@
+LDADD = ../../lib/libgftp.a ../uicommon/libgftpui.a @GLIB_LIBS@ @EXTRA_LIBS@ @READLINE_LIBS@ @SSL_LIBS@
 noinst_HEADERS=gftp-text.h
 localedir=$(datadir)/locale
--- a/src/text/gftp-text.c	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/text/gftp-text.c	Sun Dec 28 16:02:07 2003 +0000
@@ -22,221 +22,25 @@
 
 static gftp_request * gftp_text_locreq = NULL;
 static gftp_request * gftp_text_remreq = NULL;
-static volatile int cancel = 0;
-static int number_commands = 30;
-
-struct _gftp_text_methods gftp_text_methods[] = {
-        {N_("about"), 	2, gftp_text_about,	NULL,
-         N_("Shows gFTP information"), NULL},
-        {N_("ascii"),	2, gftp_text_ascii,	&gftp_text_remreq,
-         N_("Sets the current file transfer mode to Ascii (only for FTP)"), NULL},
-	{N_("binary"),	1, gftp_text_binary,	&gftp_text_remreq,
-         N_("Sets the current file transfer mode to Binary (only for FTP)"), NULL},
-        {N_("cd"), 	2, gftp_text_cd, 	&gftp_text_remreq,
-         N_("Changes the remote working directory"), NULL},
-        {N_("chdir"), 	3, gftp_text_cd, 	&gftp_text_remreq,
-         N_("Changes the remote working directory"), NULL},
-        {N_("chmod"), 	3, gftp_text_chmod,	&gftp_text_remreq,
-         N_("Changes the permissions of a remote file"), NULL},
-        {N_("clear"),	3, gftp_text_clear,	NULL,
-         N_("Available options: cache"), 	gftp_text_clear_show_subhelp},
-        {N_("close"), 	3, gftp_text_close, 	&gftp_text_remreq,
-         N_("Disconnects from the remote site"), NULL},
-        {N_("delete"), 	1, gftp_text_delete,	&gftp_text_remreq,
-         N_("Removes a remote file"), NULL},
-        {N_("get"),	1, gftp_text_mget_file,	NULL,
-         N_("Downloads remote file(s)"), NULL},
-        {N_("help"), 	1, gftp_text_help, 	NULL,
-         N_("Shows this help screen"), NULL},
-        {N_("lcd"), 	3, gftp_text_cd, 	&gftp_text_locreq,
-         N_("Changes the local working directory"), NULL},
-        {N_("lchdir"), 	4, gftp_text_cd, 	&gftp_text_locreq,
-         N_("Changes the local working directory"), NULL},
-        {N_("lchmod"), 	4, gftp_text_chmod, 	&gftp_text_locreq,
-         N_("Changes the permissions of a local file"), NULL},
-        {N_("ldelete"), 2, gftp_text_delete, 	&gftp_text_locreq,
-         N_("Removes a local file"), NULL},
-	{N_("lls"), 	2, gftp_text_ls, 	&gftp_text_locreq,
-         N_("Shows the directory listing for the current local directory"), NULL},
-        {N_("lmkdir"), 	2, gftp_text_mkdir, 	&gftp_text_locreq,
-         N_("Creates a local directory"), NULL},
-        {N_("lpwd"), 	2, gftp_text_pwd, 	&gftp_text_locreq,
-         N_("Show current local directory"), NULL},
-        {N_("lrename"), 3, gftp_text_rename, 	&gftp_text_locreq,
-         N_("Rename a local file"), NULL},
-        {N_("lrmdir"), 	3, gftp_text_rmdir, 	&gftp_text_locreq,
-         N_("Remove a local directory"), NULL},
-	{N_("ls"), 	2, gftp_text_ls,	&gftp_text_remreq,
-         N_("Shows the directory listing for the current remote directory"), NULL},
-        {N_("mget"),	2, gftp_text_mget_file,	NULL,
-         N_("Downloads remote file(s)"), NULL},
-        {N_("mkdir"), 	2, gftp_text_mkdir,	&gftp_text_remreq,
-         N_("Creates a remote directory"), NULL},
-        {N_("mput"),	2, gftp_text_mput_file,	NULL,
-         N_("Uploads local file(s)"), NULL},
-        {N_("open"), 	1, gftp_text_open, 	&gftp_text_remreq,
-         N_("Opens a connection to a remote site"), NULL},
-        {N_("put"),	2, gftp_text_mput_file,	NULL,
-         N_("Uploads local file(s)"), NULL},
-        {N_("pwd"), 	2, gftp_text_pwd, 	&gftp_text_remreq,
-         N_("Show current remote directory"), NULL},
-        {N_("quit"), 	1, gftp_text_quit, 	NULL,
-         N_("Exit from gFTP"), NULL},
-        {N_("rename"), 	2, gftp_text_rename,	&gftp_text_remreq,
-         N_("Rename a remote file"), NULL},
-        {N_("rmdir"), 	2, gftp_text_rmdir,	&gftp_text_remreq,
-         N_("Remove a remote directory"), NULL},
-        {N_("set"), 	1, gftp_text_set, 	NULL,
-         N_("Show configuration file variables. You can also set variables by set var=val"), gftp_text_set_show_subhelp},
-        {NULL, 		0, NULL,		NULL, 	NULL}};
 
 int
-main (int argc, char **argv)
+gftp_text_get_win_size (void)
 {
-  char *pos, *stpos, *startup_directory;
-  gftp_request * request;
-  size_t len, cmdlen;
-  int i;
-#if HAVE_LIBREADLINE
-  char *tempstr, prompt[20];
-#else
-  char tempstr[512];
-#endif
-
-  gftp_locale_init ();
-
-  signal (SIGCHLD, sig_child);
-  signal (SIGPIPE, SIG_IGN); 
-
-  gftp_read_config_file (SHARE_DIR);
-
-  if (gftp_parse_command_line (&argc, &argv) != 0)
-    exit (0);
-
-  /* SSH doesn't support reading the password with askpass via the command 
-     line */
-
-  gftp_text_remreq = gftp_request_new ();
-  gftp_set_request_option (gftp_text_remreq, "ssh_use_askpass", 
-                           GINT_TO_POINTER(0));
-  gftp_set_request_option (gftp_text_remreq, "sshv2_use_sftp_subsys", 
-                           GINT_TO_POINTER(0));
-  gftp_text_remreq->logging_function = gftp_text_log;
-
-  gftp_text_locreq = gftp_request_new ();
-  gftp_set_request_option (gftp_text_locreq, "ssh_use_askpass", 
-                           GINT_TO_POINTER(0));
-  gftp_set_request_option (gftp_text_locreq, "sshv2_use_sftp_subsys", 
-                           GINT_TO_POINTER(0));
-
-  gftp_text_locreq->logging_function = gftp_text_log;
-  if (gftp_protocols[GFTP_LOCAL_NUM].init (gftp_text_locreq) == 0)
-    {
-      gftp_lookup_request_option (gftp_text_locreq, "startup_directory", 
-                                  &startup_directory);
-      if (*startup_directory != '\0')
-        gftp_set_directory (gftp_text_locreq, startup_directory);
-
-      gftp_connect (gftp_text_locreq);
-    }
-
-  gftp_text_log (gftp_logging_misc, NULL, "%s, Copyright (C) 1998-2003 Brian Masney <", gftp_version);
-  gftp_text_log (gftp_logging_recv, NULL, "masneyb@gftp.org");
-  gftp_text_log (gftp_logging_misc, NULL, _(">.\nIf you have any questions, comments, or suggestions about this program, please feel free to email them to me. You can always find out the latest news about gFTP from my website at http://www.gftp.org/\n"));
-  gftp_text_log (gftp_logging_misc, NULL, "\n");
-  gftp_text_log (gftp_logging_misc, NULL, _("gFTP comes with ABSOLUTELY NO WARRANTY; for details, see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; for details, see the COPYING file\n"));
-  gftp_text_log (gftp_logging_misc, NULL, "\n");
-
-  if (argc == 3 && strcmp (argv[1], "-d") == 0)
-    {
-      if ((pos = strrchr (argv[2], '/')) != NULL)
-        *pos = '\0';
-      gftp_text_open (gftp_text_remreq, argv[2], NULL);
-
-      if (pos != NULL)
-        *pos = '/';
-
-      gftp_text_mget_file (gftp_text_remreq, pos + 1, NULL);
-      exit (0);
-    }
-  else if (argc == 2)
-    gftp_text_open (gftp_text_remreq, argv[1], NULL);
+  struct winsize size;
+  int ret;
 
-#if HAVE_LIBREADLINE
-  g_snprintf (prompt, sizeof (prompt), "%sftp%s> ", COLOR_BLUE, COLOR_DEFAULT);
-  while ((tempstr = readline (prompt)))
-#else
-  printf ("%sftp%s> ", COLOR_BLUE, COLOR_DEFAULT);
-  while (fgets (tempstr, sizeof (tempstr), stdin) != NULL)
-#endif
-    {
-      len = strlen (tempstr);
-      if (tempstr[len - 1] == '\n')
-        tempstr[--len] = '\0';
-      if (tempstr[len - 1] == '\r')
-        tempstr[--len] = '\0';
-
-      for (stpos = tempstr; *stpos == ' '; stpos++);
-
-      for (pos = tempstr + len - 1; 
-           (*pos == ' ' || *pos == '\t') && pos > tempstr; 
-           pos--)
-        *pos = '\0';
-
-      if (*stpos == '\0')
-        {
-#if !HAVE_LIBREADLINE
-          printf ("%sftp%s> ", COLOR_BLUE, COLOR_DEFAULT);
-#endif
-          continue;
-        }
-
-#if HAVE_LIBREADLINE
-      add_history (tempstr);
-#endif
-
-      if ((pos = strchr (stpos, ' ')) != NULL)
-        *pos = '\0';
-      cmdlen = strlen (stpos);
+  if (ioctl (0, TIOCGWINSZ, (char *) &size) < 0)
+    ret = 80;
+  else
+    ret = size.ws_col;
 
-      for (i=0; gftp_text_methods[i].command != NULL; i++)
-        {
-          if (strcmp (gftp_text_methods[i].command, stpos) == 0)
-            break;
-          else if (cmdlen >= gftp_text_methods[i].minlen &&
-                   strncmp (gftp_text_methods[i].command, stpos, cmdlen) == 0)
-            break;
-        }
+  return (ret);
+}
 
-      if (pos != NULL)
-        pos++;
-      else
-        pos = "";
 
-      if (gftp_text_methods[i].command != NULL)
-        {
-          if (gftp_text_methods[i].request != NULL)
-            request = *gftp_text_methods[i].request;
-          else
-            request = NULL;
-
-          if (gftp_text_methods[i].func (request, pos, NULL) == 0)
-            break;
-        }
-      else
-        gftp_text_log (gftp_logging_error, NULL, 
-                       _("Error: Command not recognized\n"));
-
-#if HAVE_LIBREADLINE
-     free (tempstr);
-#else
-     printf ("%sftp%s> ", COLOR_BLUE, COLOR_DEFAULT);
-#endif
-    }
- 
-  gftp_text_quit (NULL, NULL, NULL);
-
-  return (0);
+void
+sig_child (int signo)
+{
 }
 
 
@@ -253,16 +57,16 @@
   switch (level)
     {
       case gftp_logging_send:
-        printf ("%s", COLOR_GREEN);
+        printf ("%s", GFTPUI_COMMON_COLOR_GREEN);
         break;
       case gftp_logging_recv:
-        printf ("%s", COLOR_YELLOW);
+        printf ("%s", GFTPUI_COMMON_COLOR_YELLOW);
         break;
       case gftp_logging_error:
-        printf ("%s", COLOR_RED);
+        printf ("%s", GFTPUI_COMMON_COLOR_RED);
         break;
       default:
-        printf ("%s", COLOR_DEFAULT);
+        printf ("%s", GFTPUI_COMMON_COLOR_DEFAULT);
         break;
     }
 
@@ -312,13 +116,167 @@
     }
   while (stpos != endpos);
   
-  printf ("%s", COLOR_DEFAULT);
+  printf ("%s", GFTPUI_COMMON_COLOR_DEFAULT);
 
   if (utf8_str != NULL)
     g_free (utf8_str);
 }
 
 
+char *
+gftp_text_ask_question (const char *question, int echo, char *buf, size_t size)
+{
+  struct termios term, oldterm;
+  sigset_t sig, sigsave;
+  char *pos, *termname;
+  FILE *infd;
+
+  if (!echo)
+    {
+      sigemptyset (&sig);
+      sigaddset (&sig, SIGINT);
+      sigaddset (&sig, SIGTSTP);
+      sigprocmask (SIG_BLOCK, &sig, &sigsave);
+
+      termname = ctermid (NULL);
+      if ((infd = fopen (termname, "r+")) == NULL)
+        {
+          
+          gftp_text_log (gftp_logging_error, NULL, 
+                         _("Cannot open controlling terminal %s\n"), termname);
+          return (NULL);
+        }
+
+      tcgetattr (0, &term);
+      oldterm = term;
+      term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 
+      tcsetattr (fileno (infd), TCSAFLUSH, &term);
+    }
+  else
+    infd = stdin;
+
+  printf ("%s%s%s: ", GFTPUI_COMMON_COLOR_BLUE, question, GFTPUI_COMMON_COLOR_DEFAULT);
+
+  if (fgets (buf, size, infd) == NULL)
+    return (NULL);
+  buf[size - 1] = '\0';
+
+  if (!echo)
+    {
+      printf ("\n");
+      tcsetattr (fileno (infd), TCSAFLUSH, &oldterm);
+      fclose (infd);
+      sigprocmask (SIG_SETMASK, &sigsave, NULL);
+    }
+
+  for (pos = buf + strlen (buf) - 1; *pos == ' ' || *pos == '\r' ||
+                                     *pos == '\n'; pos--);
+  *(pos+1) = '\0';
+
+  for (pos = buf; *pos == ' '; pos++);  
+  if (*pos == '\0')
+    return (NULL);
+
+  return (pos);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  char *startup_directory;
+#if HAVE_LIBREADLINE
+  char *tempstr, prompt[20];
+#else
+  char tempstr[512];
+#endif
+
+  gftp_locale_init ();
+
+  signal (SIGCHLD, sig_child);
+  signal (SIGPIPE, SIG_IGN); 
+
+  gftp_read_config_file (SHARE_DIR);
+
+  if (gftp_parse_command_line (&argc, &argv) != 0)
+    exit (0);
+
+  /* SSH doesn't support reading the password with askpass via the command 
+     line */
+
+  gftp_text_remreq = gftp_request_new ();
+  gftp_set_request_option (gftp_text_remreq, "ssh_use_askpass", 
+                           GINT_TO_POINTER(0));
+  gftp_set_request_option (gftp_text_remreq, "sshv2_use_sftp_subsys", 
+                           GINT_TO_POINTER(0));
+  gftp_text_remreq->logging_function = gftp_text_log;
+
+  gftp_text_locreq = gftp_request_new ();
+  gftp_set_request_option (gftp_text_locreq, "ssh_use_askpass", 
+                           GINT_TO_POINTER(0));
+  gftp_set_request_option (gftp_text_locreq, "sshv2_use_sftp_subsys", 
+                           GINT_TO_POINTER(0));
+
+  gftp_text_locreq->logging_function = gftp_text_log;
+  if (gftp_protocols[GFTP_LOCAL_NUM].init (gftp_text_locreq) == 0)
+    {
+      gftp_lookup_request_option (gftp_text_locreq, "startup_directory", 
+                                  &startup_directory);
+      if (*startup_directory != '\0')
+        gftp_set_directory (gftp_text_locreq, startup_directory);
+
+      gftp_connect (gftp_text_locreq);
+    }
+
+  gftpui_common_about (gftp_text_log, NULL);
+  gftp_text_log (gftp_logging_misc, NULL, "\n");
+
+/* FIXME
+  if (argc == 3 && strcmp (argv[1], "-d") == 0)
+    {
+      if ((pos = strrchr (argv[2], '/')) != NULL)
+        *pos = '\0';
+      gftp_text_open (gftp_text_remreq, argv[2], NULL);
+
+      if (pos != NULL)
+        *pos = '/';
+
+      gftp_text_mget_file (gftp_text_remreq, pos + 1, NULL);
+      exit (0);
+    }
+  else if (argc == 2)
+    gftp_text_open (gftp_text_remreq, argv[1], NULL);
+*/
+
+  gftpui_common_init (NULL, gftp_text_locreq,
+                      NULL, gftp_text_remreq);
+
+#if HAVE_LIBREADLINE
+  g_snprintf (prompt, sizeof (prompt), "%sftp%s> ", GFTPUI_COMMON_COLOR_BLUE, GFTPUI_COMMON_COLOR_DEFAULT);
+  while ((tempstr = readline (prompt)))
+    {
+      if (gftpui_common_process_command (tempstr) == 0)
+        break;
+   
+      add_history (tempstr);
+      free (tempstr);
+    }
+#else
+  printf ("%sftp%s> ", GFTPUI_COMMON_COLOR_BLUE, GFTPUI_COMMON_COLOR_DEFAULT);
+  while (fgets (tempstr, sizeof (tempstr), stdin) != NULL)
+    {
+      if (gftpui_common_process_command (tempstr) == 0)
+        break;
+
+      printf ("%sftp%s> ", GFTPUI_COMMON_COLOR_BLUE, GFTPUI_COMMON_COLOR_DEFAULT);
+    }
+#endif
+ 
+  return (0);
+}
+
+
+#if 0
 int
 gftp_text_open (gftp_request * request, char *command, gpointer *data)
 {
@@ -368,363 +326,6 @@
 
 
 int
-gftp_text_close (gftp_request * request, char *command, gpointer *data)
-{
-  gftp_disconnect (request);
-  return (1);
-}
-
-
-int
-gftp_text_about (gftp_request * request, char *command, gpointer *data)
-{
-  char *str;
-
-  gftp_text_log (gftp_logging_misc, request,
-      "%s. Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>\n", 
-      gftp_version);
-
-  str = _("Translated by");
-  if (strcmp (str, "Translated by") != 0)
-    gftp_text_log (gftp_logging_misc, request, "%s\n", str);
-  return (1);
-}
-
-
-int
-gftp_text_quit (gftp_request * request, char *command, gpointer *data)
-{
-  gftp_request_destroy (gftp_text_locreq, 1);
-  gftp_request_destroy (gftp_text_remreq, 1);
-  gftp_shutdown();
-
-  return (0);
-}
-
-
-int
-gftp_text_pwd (gftp_request * request, char *command, gpointer *data)
-{
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-  gftp_text_log (gftp_logging_misc, request, "%s\n", request->directory);
-  return (1);
-}
-
-
-int
-gftp_text_cd (gftp_request * request, char *command, gpointer *data)
-{
-  char *tempstr, *newdir = NULL;
-
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-  else if (*command == '\0')
-    {
-      gftp_text_log (gftp_logging_error, request, 
-                     _("usage: chdir <directory>\n"));
-      return (1);
-    }
-  else if (request->protonum == GFTP_LOCAL_NUM)
-    {
-      if (*command != '/' && request->directory != NULL)
-        {
-          tempstr = g_strconcat (request->directory, "/", command, NULL);
-          newdir = expand_path (tempstr);
-          g_free (tempstr);
-        }
-      else
-        newdir = expand_path (command);
-
-      if (newdir == NULL)
-        {
-          gftp_text_log (gftp_logging_error, request, 
-                         _("usage: chdir <directory>\n"));
-          return (1);
-        }
-    }
-
-  gftp_set_directory (request, newdir != NULL ? newdir : command);
-
-  if (newdir != NULL)
-    g_free (newdir);
-
-  return (1);
-}
-
-
-int
-gftp_text_mkdir (gftp_request * request, char *command, gpointer *data)
-{
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  if (*command == '\0')
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("usage: mkdir <new directory>\n"));
-    }
-  else
-    {
-      gftp_make_directory (request, command);
-    }
-  return (1);
-}
-
-
-int
-gftp_text_rmdir (gftp_request * request, char *command, gpointer *data)
-{
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request, 
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  if (*command == '\0')
-    {
-      gftp_text_log (gftp_logging_error, request, 
-                     _("usage: rmdir <directory>\n"));
-    }
-  else
-    {
-      gftp_remove_directory (request, command);
-    }
-  return (1);
-}
-
-
-int
-gftp_text_delete (gftp_request * request, char *command, gpointer *data)
-{
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  if (*command == '\0')
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("usage: delete <file>\n"));
-    }
-  else
-    {
-      if (gftp_remove_file (request, command) == 0)
-        gftp_delete_cache_entry (request, NULL, 0);
-    }
-  return (1);
-}
-
-
-int
-gftp_text_rename (gftp_request * request, char *command, gpointer *data)
-{
-  char *pos;
-
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  if ((pos = strchr (command, ' ')) != NULL)
-    *pos++ = '\0';
-
-  if (*command == '\0' || pos == NULL || *pos == '\0')
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("usage: rename <old name> <new name>\n"));
-    }
-  else
-    {
-      gftp_rename_file (request, command, pos);
-    }
-  return (1);
-}
-
-
-int
-gftp_text_chmod (gftp_request * request, char *command, gpointer *data)
-{
-  char *pos;
-
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  if ((pos = strchr (command, ' ')) != NULL)
-    *pos++ = '\0';
-
-  if (*command == '\0' || pos == NULL || *pos == '\0')
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("usage: chmod <mode> <file>\n"));
-    }
-  else
-    {
-      gftp_chmod (request, pos, strtol (command, NULL, 10));
-    }
-  return (1);
-}
-
-
-int
-gftp_text_ls (gftp_request * request, char *command, gpointer *data)
-{
-  GList * files, * templist, * delitem;
-  char *color, *filespec, *tempstr;
-  intptr_t sortcol, sortasds;
-  int got;
-  gftp_file * fle;
-  time_t curtime;
-
-  time (&curtime);
-  if (!GFTP_IS_CONNECTED (request))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  filespec = *command != '\0' ? command : NULL;
-  if (gftp_list_files (request) != 0)
-    return (1);
-
-  files = NULL;
-  fle = g_malloc0 (sizeof (*fle));
-  while ((got = gftp_get_next_file (request, NULL, fle)) > 0 ||
-         got == GFTP_ERETRYABLE)
-    {
-      if (got < 0 || strcmp (fle->file, ".") == 0)
-        {
-          gftp_file_destroy (fle);
-          continue;
-        }
-      files = g_list_prepend (files, fle);
-      fle = g_malloc0 (sizeof (*fle));
-    }
-  g_free (fle);
-
-  if (files == NULL)
-    {
-      gftp_end_transfer (request);
-      return (1);
-    }
-
-  if (request == gftp_text_locreq)
-    {
-      gftp_lookup_request_option (request, "local_sortcol", &sortcol);
-      gftp_lookup_request_option (request, "local_sortasds", &sortasds);
-    }
-  else
-    {
-      gftp_lookup_request_option (request, "remote_sortcol", &sortcol);
-      gftp_lookup_request_option (request, "remote_sortasds", &sortasds);
-    }
-
-  files = gftp_sort_filelist (files, sortcol, sortasds);
-  delitem = NULL;
-  for (templist = files; templist != NULL; templist = templist->next)
-    {
-      if (delitem != NULL)
-        {
-          fle = delitem->data;
-          gftp_file_destroy (fle);
-          g_free (fle);
-          delitem = NULL;
-        }
-
-      fle = templist->data;
-
-      if (*fle->attribs == 'd')
-        color = COLOR_BLUE;
-      else if (*fle->attribs == 'l')
-        color = COLOR_WHITE;
-      else if (strchr (fle->attribs, 'x') != NULL)
-        color = COLOR_GREEN;
-      else
-        color = COLOR_DEFAULT;
-
-      tempstr = gftp_gen_ls_string (fle, color, COLOR_DEFAULT);
-      printf ("%s\n", tempstr);
-      g_free (tempstr);
-
-      delitem = templist;
-    }
-
-  gftp_end_transfer (request);
-
-  if (delitem != NULL)
-    {
-      fle = delitem->data;
-      gftp_file_destroy (fle);
-      g_free (fle);
-      delitem = NULL;
-    }
-
-  if (files != NULL)
-    g_list_free (files);
-
-  return (1);
-}
-
-
-int
-gftp_text_binary (gftp_request * request, char *command, gpointer *data)
-{
-  if (!GFTP_IS_CONNECTED (gftp_text_remreq))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  gftp_set_request_option (gftp_text_remreq, "ascii_transfers", 
-                           GINT_TO_POINTER(0));
-  gftp_set_request_option (gftp_text_locreq, "ascii_transfers", 
-                           GINT_TO_POINTER(0));
-  return (1);
-}
-
-
-int
-gftp_text_ascii (gftp_request * request, char *command, gpointer *data)
-{
-  if (!GFTP_IS_CONNECTED (gftp_text_remreq))
-    {
-      gftp_text_log (gftp_logging_error, request,
-                     _("Error: Not connected to a remote site\n"));
-      return (1);
-    }
-
-  gftp_set_request_option (gftp_text_remreq, "ascii_transfers", 
-                           GINT_TO_POINTER(1));
-  gftp_set_request_option (gftp_text_locreq, "ascii_transfers", 
-                           GINT_TO_POINTER(1));
-  return (1);
-}
-
-
-int
 gftp_text_mget_file (gftp_request * request, char *command, gpointer *data)
 {
   gftp_transfer * transfer;
@@ -980,263 +581,4 @@
   return (1);
 }
 
-
-int
-gftp_text_help (gftp_request * request, char *command, gpointer *data)
-{
-  int i, j, ele, numrows, numcols = 6, handled;
-  char *pos;
-
-  if (command != NULL && *command != '\0')
-    {
-      for (pos = command; *pos != ' ' && *pos != '\0'; pos++);
-      if (*pos == ' ')
-        {
-          *pos++ = '\0';
-          if (*pos == '\0')
-            pos = NULL;
-        }
-      else
-        pos = NULL;
-
-      for (i=0; gftp_text_methods[i].command != NULL; i++)
-        {
-          if (strcmp (gftp_text_methods[i].command, command) == 0)
-            break;
-        }
-
-      if (gftp_text_methods[i].cmd_description != NULL)
-        {
-          if (pos != NULL && gftp_text_methods[i].subhelp_func != NULL)
-            handled = gftp_text_methods[i].subhelp_func (pos);
-          else
-            handled = 0;
-
-          if (!handled)
-            printf ("%s\n", _(gftp_text_methods[i].cmd_description));
-        }
-      else
-        *command = '\0';
-    }
-
-  if (command == NULL || *command == '\0')
-    {
-      numrows = number_commands / numcols;
-      if (number_commands % numcols != 0)
-        numrows++;
-
-      printf (_("Supported commands:\n\n"));
-      for (i=0; i<numrows; i++)
-        {
-          printf ("     ");
-          for (j=0; j<numcols; j++)
-            { 
-              ele = i + j * numrows;
-              if (ele >= number_commands)
-                break;
-              printf ("%-10s", gftp_text_methods[ele].command);
-            }
-         printf ("\n");
-        }
-
-      printf ("\n");
-    }
-  return (1);
-}
-
-
-int
-gftp_text_set (gftp_request * request, char *command, gpointer *data)
-{
-  gftp_config_vars * cv, newcv;
-  char *pos, *backpos;
-  GList * templist;
-  int i;
-
-  if (command == NULL || *command == '\0')
-    {
-      for (templist = gftp_options_list; 
-           templist != NULL; 
-           templist = templist->next)
-        {
-          cv = templist->data;
-
-          for (i=0; cv[i].key != NULL; i++)
-            {
-              if (!(cv[i].ports_shown & GFTP_PORT_TEXT))
-                continue;
-
-              if (*cv[i].key == '\0' || 
-                  gftp_option_types[cv[i].otype].write_function == NULL)
-                continue;
-
-              printf ("%s = ", cv[i].key);
-              gftp_option_types[cv[i].otype].write_function (&cv[i], stdout, 0);
-              printf ("\n");
-            }
-        }
-    }
-  else
-    {
-      if ((pos = strchr (command, '=')) == NULL)
-        {
-          gftp_text_log (gftp_logging_error, request,
-                         _("usage: set [variable = value]\n"));
-          return (1);
-        }
-      *pos = '\0';
-
-      for (backpos = pos - 1; 
-           (*backpos == ' ' || *backpos == '\t') && backpos > command; 
-           backpos--)
-        *backpos = '\0';
-      for (++pos; *pos == ' ' || *pos == '\t'; pos++);
-
-      if ((cv = g_hash_table_lookup (gftp_global_options_htable, command)) == NULL)
-        {
-          gftp_text_log (gftp_logging_error, request,
-                         _("Error: Variable %s is not a valid configuration variable.\n"), command);
-          return (1);
-        }
-
-      if (!(cv->ports_shown & GFTP_PORT_TEXT))
-        {
-          gftp_text_log (gftp_logging_error, request,
-                         _("Error: Variable %s is not available in the text port of gFTP\n"), command);
-          return (1);
-        }
-
-      if (gftp_option_types[cv->otype].read_function != NULL)
-        {
-          memcpy (&newcv, cv, sizeof (newcv));
-          newcv.flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
-
-          gftp_option_types[cv->otype].read_function (pos, &newcv, 1);
-
-          gftp_set_global_option (command, newcv.value);
-
-          if (newcv.flags & GFTP_CVARS_FLAGS_DYNMEM)
-            g_free (newcv.value);
-        }
-    }
-
-  return (1);
-}
-
-
-int
-gftp_text_clear (gftp_request * request, char *command, gpointer *data)
-{
-  if (strcasecmp (command, "cache") == 0)
-    gftp_clear_cache_files ();
-  else
-    gftp_text_log (gftp_logging_error, request, _("Invalid argument\n"));
-  return (1);
-}
-
-
-char *
-gftp_text_ask_question (const char *question, int echo, char *buf, size_t size)
-{
-  struct termios term, oldterm;
-  sigset_t sig, sigsave;
-  char *pos, *termname;
-  FILE *infd;
-
-  if (!echo)
-    {
-      sigemptyset (&sig);
-      sigaddset (&sig, SIGINT);
-      sigaddset (&sig, SIGTSTP);
-      sigprocmask (SIG_BLOCK, &sig, &sigsave);
-
-      termname = ctermid (NULL);
-      if ((infd = fopen (termname, "r+")) == NULL)
-        {
-          
-          gftp_text_log (gftp_logging_error, NULL, 
-                         _("Cannot open controlling terminal %s\n"), termname);
-          return (NULL);
-        }
-
-      tcgetattr (0, &term);
-      oldterm = term;
-      term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 
-      tcsetattr (fileno (infd), TCSAFLUSH, &term);
-    }
-  else
-    infd = stdin;
-
-  printf ("%s%s%s: ", COLOR_BLUE, question, COLOR_DEFAULT);
-
-  if (fgets (buf, size, infd) == NULL)
-    return (NULL);
-  buf[size - 1] = '\0';
-
-  if (!echo)
-    {
-      printf ("\n");
-      tcsetattr (fileno (infd), TCSAFLUSH, &oldterm);
-      fclose (infd);
-      sigprocmask (SIG_SETMASK, &sigsave, NULL);
-    }
-
-  for (pos = buf + strlen (buf) - 1; *pos == ' ' || *pos == '\r' ||
-                                     *pos == '\n'; pos--);
-  *(pos+1) = '\0';
-
-  for (pos = buf; *pos == ' '; pos++);  
-  if (*pos == '\0')
-    return (NULL);
-
-  return (pos);
-}
-
-
-int
-gftp_text_get_win_size (void)
-{
-  struct winsize size;
-  int ret;
-
-  if (ioctl (0, TIOCGWINSZ, (char *) &size) < 0)
-    ret = 80;
-  else
-    ret = size.ws_col;
-  return (ret);
-}
-
-
-void
-sig_child (int signo)
-{
-}
-
-
-int
-gftp_text_set_show_subhelp (char *topic)
-{
-  gftp_config_vars * cv;
-
-  if ((cv = g_hash_table_lookup (gftp_global_options_htable, topic)) != NULL)
-    {
-      printf ("%s\n", cv->comment);
-      return (1);
-    }
-
-  return (0);
-}
-
-
-int
-gftp_text_clear_show_subhelp (char *topic)
-{
-  if (strcmp (topic, "cache") == 0)
-    {
-      printf (_("Clear the directory cache\n"));
-      return (1);
-    }
-
-  return (0);
-}
-
+#endif
--- a/src/text/gftp-text.h	Sat Dec 20 22:00:04 2003 +0000
+++ b/src/text/gftp-text.h	Sun Dec 28 16:02:07 2003 +0000
@@ -23,103 +23,12 @@
 #define __GFTP_TEXT_H
 
 #include "../../lib/gftp.h"
+#include "../uicommon/gftpui.h"
 
 #if HAVE_LIBREADLINE
 #include <readline/readline.h>
 #include <readline/history.h>
 #endif
 
-#define COLOR_BLACK     "\033[30m"
-#define COLOR_RED       "\033[31m"
-#define COLOR_GREEN     "\033[32m"
-#define COLOR_YELLOW    "\033[33m"
-#define COLOR_BLUE      "\033[34m"
-#define COLOR_MAGENTA   "\033[35m"
-#define COLOR_CYAN      "\033[36m"
-#define COLOR_WHITE     "\033[37m"
-#define COLOR_GREY      "\033[38m"
-#define COLOR_DEFAULT   "\033[39m"
-
-struct _gftp_text_methods
-{
-  char *command;
-  int minlen;
-  int (*func)(gftp_request * request, char *command, gpointer *data);
-  gftp_request ** request;
-  char *cmd_description;
-  int (*subhelp_func) (char *topic);
-};
-
-/* gftp-text.h */
-void gftp_text_log				( gftp_logging_level level, 
-						  gftp_request * request, 
-						  const char *string, ... ) GFTP_LOG_FUNCTION_ATTRIBUTES;
-int gftp_text_open				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data );
-int gftp_text_close				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data );
-int gftp_text_about				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data );
-int gftp_text_quit 				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data );
-int gftp_text_pwd 				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_cd				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_mkdir				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_rmdir				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_delete				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_rename				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_chmod				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_ls				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_binary				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_ascii				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_mget_file				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_mput_file				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_transfer_files 			( gftp_transfer * transfer );
-int gftp_text_help				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_set				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-int gftp_text_clear				( gftp_request * request, 
-						  char *command, 
-						  gpointer *data);
-char *gftp_text_ask_question 			( const char *question, 
-						  int echo,
-						  char *buf,
-						  size_t size );
-int gftp_text_get_win_size 			( void );
-void sig_child 					( int signo );
-int gftp_text_set_show_subhelp			( char *topic );
-int gftp_text_clear_show_subhelp		( char *topic );
-
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uicommon/Makefile.am	Sun Dec 28 16:02:07 2003 +0000
@@ -0,0 +1,7 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libgftpui.a
+libgftpui_a_SOURCES = gftpui.c gftpuicallbacks.c
+INCLUDES = @GLIB_CFLAGS@ @PTHREAD_CFLAGS@ -I../intl -DSHARE_DIR=\"$(datadir)/gftp\"
+noinst_HEADERS = gftpui.h
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uicommon/gftpui.c	Sun Dec 28 16:02:07 2003 +0000
@@ -0,0 +1,849 @@
+/*****************************************************************************/
+/*  gftpui.c - UI related functions for gFTP                                 */
+/*  Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>                  */
+/*                                                                           */
+/*  This program is free software; you can redistribute it and/or modify     */
+/*  it under the terms of the GNU General Public License as published by     */
+/*  the Free Software Foundation; either version 2 of the License, or        */
+/*  (at your option) any later version.                                      */
+/*                                                                           */
+/*  This program is distributed in the hope that it will be useful,          */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
+/*  GNU General Public License for more details.                             */
+/*                                                                           */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program; if not, write to the Free Software              */
+/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
+/*****************************************************************************/
+
+#include "gftpui.h"
+static const char cvsid[] = "$Id$";
+
+sigjmp_buf gftpui_common_jmp_environment;
+volatile int gftpui_common_use_jmp_environment = 0;
+
+static void *gftpui_common_local_uidata, *gftpui_common_remote_uidata;
+static gftp_request * gftpui_common_local_request, * gftpui_common_remote_request;
+
+
+static gftp_logging_func
+_gftpui_common_log (gftp_request * request)
+{
+  if (request == NULL)
+    return (gftpui_common_local_request->logging_function);
+  else
+    return (request->logging_function);
+}
+
+
+static void *
+_gftpui_common_thread_callback (void * data)
+{ 
+  gftpui_callback_data * cdata;
+  intptr_t network_timeout;
+  int success, sj;
+
+  cdata = data;
+  gftp_lookup_request_option (cdata->request, "network_timeout",
+                              &network_timeout);
+
+  sj = sigsetjmp (gftpui_common_jmp_environment, 1);
+  gftpui_common_use_jmp_environment = 1;
+
+  success = 0;
+  if (sj == 0)
+    {
+      if (network_timeout > 0)
+        alarm (network_timeout);
+
+      success = cdata->run_function (cdata);
+
+      alarm (0);
+    }
+  else
+    {
+      gftp_disconnect (cdata->request);
+      cdata->request->logging_function (gftp_logging_error, cdata->request,
+                                        _("Operation canceled\n"));
+    }
+
+  gftpui_common_use_jmp_environment = 0;
+  cdata->request->stopable = 0;
+
+  return (GINT_TO_POINTER (success));
+}
+
+
+int
+gftpui_common_run_callback_function (gftpui_callback_data * cdata)
+{
+  int ret;
+
+  if (gftpui_check_reconnect (cdata) < 0)
+    return (0);
+
+  if (gftp_protocols[cdata->request->protonum].use_threads)
+    ret = GPOINTER_TO_INT (gftpui_generic_thread (_gftpui_common_thread_callback, cdata));
+  else
+    ret = GPOINTER_TO_INT (cdata->run_function (cdata));
+
+  if (ret)
+    gftpui_refresh (cdata->uidata);
+
+  return (ret);
+}
+
+
+RETSIGTYPE
+gftpui_common_signal_handler (int signo)
+{
+  signal (signo, gftpui_common_signal_handler);
+
+  if (gftpui_common_use_jmp_environment)
+    siglongjmp (gftpui_common_jmp_environment, signo == SIGINT ? 1 : 2);
+  else if (signo == SIGINT)
+    exit (1);
+}
+
+
+void
+gftpui_common_about (gftp_logging_func logging_function, gpointer logdata)
+{
+  char *str;
+
+  logging_function (gftp_logging_misc, logdata, "%s, Copyright (C) 1998-2003 Brian Masney <", gftp_version);
+  logging_function (gftp_logging_recv, logdata, "masneyb@gftp.org");
+  logging_function (gftp_logging_misc, logdata, _(">. If you have any questions, comments, or suggestions about this program, please feel free to email them to me. You can always find out the latest news about gFTP from my website at http://www.gftp.org/\n"));
+  logging_function (gftp_logging_misc, logdata, _("gFTP comes with ABSOLUTELY NO WARRANTY; for details, see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; for details, see the COPYING file\n"));
+
+  str = _("Translated by");
+  if (strcmp (str, "Translated by") != 0)
+    logging_function (gftp_logging_misc, logdata, "%s\n", str);
+}
+
+
+static int
+gftpui_common_cmd_about (void *uidata, gftp_request * request, char *command)
+{
+  gftpui_common_about (_gftpui_common_log (request),
+                       gftpui_common_local_request);
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_ascii (void *uidata, gftp_request * request, char *command)
+{
+  if (gftpui_common_local_request != NULL)
+    gftp_set_request_option (gftpui_common_local_request, "ascii_transfers",
+                             GINT_TO_POINTER(1));
+
+  if (gftpui_common_remote_request != NULL)
+    gftp_set_request_option (gftpui_common_remote_request, "ascii_transfers",
+                             GINT_TO_POINTER(1));
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_binary (void *uidata, gftp_request * request, char *command)
+{
+  if (gftpui_common_local_request != NULL)
+    gftp_set_request_option (gftpui_common_local_request, "ascii_transfers",
+                             GINT_TO_POINTER(0));
+
+  if (gftpui_common_remote_request != NULL)
+    gftp_set_request_option (gftpui_common_remote_request, "ascii_transfers",
+                             GINT_TO_POINTER(0));
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_chmod (void *uidata, gftp_request * request, char *command)
+{
+  char *pos;
+
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Error: Not connected to a remote site\n"));
+
+      return (1);
+    }
+
+  if ((pos = strchr (command, ' ')) != NULL)
+    *pos++ = '\0';
+
+  if (*command == '\0' || pos == NULL || *pos == '\0')
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("usage: chmod <mode> <file>\n"));
+    }
+  else
+    {
+      if (gftp_chmod (request, pos, strtol (command, NULL, 10)) == 0)
+        gftp_delete_cache_entry (request, NULL, 0);
+    }
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_rename (void *uidata, gftp_request * request, char *command)
+{
+  char *pos;
+  
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Error: Not connected to a remote site\n"));
+      return (1);
+    }
+    
+  if ((pos = strchr (command, ' ')) != NULL)
+    *pos++ = '\0';
+    
+  if (*command == '\0' || pos == NULL || *pos == '\0')
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("usage: rename <old name> <new name>\n"));
+    }
+  else
+    {
+      if (gftp_rename_file (request, command, pos) == 0)
+        gftp_delete_cache_entry (request, NULL, 0);
+    }
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_delete (void *uidata, gftp_request * request, char *command)
+{
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Error: Not connected to a remote site\n"));
+      return (1);
+    }
+  else if (*command == '\0')
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("usage: delete <file>\n"));
+    }
+  else
+    {
+      if (gftp_remove_file (request, command) == 0)
+        gftp_delete_cache_entry (request, NULL, 0);
+    }
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_rmdir (void *uidata, gftp_request * request, char *command)
+{
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Error: Not connected to a remote site\n"));
+      return (1);
+    }
+  else if (*command == '\0')
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("usage: rmdir <directory>\n"));
+    }
+  else
+    {
+      if (gftp_remove_directory (request, command) == 0)
+        gftp_delete_cache_entry (request, NULL, 0);
+    }
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_mkdir (void *uidata, gftp_request * request, char *command)
+{
+  gftpui_callback_data * cdata;
+
+
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Error: Not connected to a remote site\n"));
+      return (1);
+    }
+  else if (*command == '\0')
+    {
+      request->logging_function (gftp_logging_error, request,
+                     _("usage: mkdir <new directory>\n"));
+    }
+  else
+    {
+      cdata = g_malloc0 (sizeof (*cdata));
+      cdata->request = request;
+      cdata->uidata = uidata;
+      cdata->input_string = command;
+      cdata->run_function = gftpui_common_run_mkdir;
+
+      gftpui_common_run_callback_function (cdata);
+
+      g_free (cdata);
+    }
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_chdir (void *uidata, gftp_request * request, char *command)
+{
+  char *tempstr, *newdir = NULL;
+
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Error: Not connected to a remote site\n"));
+      return (1);
+    }
+  else if (*command == '\0')
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("usage: chdir <directory>\n"));
+      return (1);
+    }
+  else if (request->protonum == GFTP_LOCAL_NUM)
+    {
+      if (*command != '/' && request->directory != NULL)
+        {
+          tempstr = g_strconcat (request->directory, "/", command, NULL);
+          newdir = expand_path (tempstr);
+          g_free (tempstr);
+        }
+      else
+        newdir = expand_path (command);
+
+      if (newdir == NULL)
+        {
+          request->logging_function (gftp_logging_error, request,
+                                     _("usage: chdir <directory>\n"));
+          return (1);
+        }
+    }
+
+  if (gftp_set_directory (request, newdir != NULL ? newdir : command) == 0)
+    gftpui_refresh (uidata);
+
+  if (newdir != NULL)
+    g_free (newdir);
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_close (void *uidata, gftp_request * request, char *command)
+{
+  gftp_disconnect (request);
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_pwd (void *uidata, gftp_request * request, char *command)
+{
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Error: Not connected to a remote site\n"));
+      return (1);
+    }
+
+  request->logging_function (gftp_logging_misc, request,
+                             "%s\n", request->directory);
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_quit (void *uidata, gftp_request * request, char *command)
+{
+  gftp_shutdown();
+
+  return (0);
+}
+
+
+static int
+gftpui_common_cmd_clear (void *uidata, gftp_request * request, char *command)
+{
+  gftp_logging_func logfunc;
+
+  if (strcasecmp (command, "cache") == 0)
+    gftp_clear_cache_files ();
+  else
+    {
+      logfunc = _gftpui_common_log (request);
+      logfunc (gftp_logging_error, request, _("Invalid argument\n"));
+    }
+
+  return (1);
+}
+
+
+static int
+gftpui_common_clear_show_subhelp (char *topic)
+{
+  gftp_logging_func logfunc;
+
+  logfunc = gftpui_common_local_request->logging_function;
+  if (strcmp (topic, "cache") == 0)
+    {
+      logfunc (gftp_logging_misc, NULL, _("Clear the directory cache\n"));
+      return (1);
+    }
+
+  return (0);
+}
+
+
+static int
+gftpui_common_set_show_subhelp (char *topic)
+{ 
+  gftp_logging_func logfunc;
+  gftp_config_vars * cv;
+    
+  logfunc = gftpui_common_local_request->logging_function;
+  if ((cv = g_hash_table_lookup (gftp_global_options_htable, topic)) != NULL)
+    {
+      logfunc (gftp_logging_misc, NULL, "%s\n", cv->comment);
+      return (1);
+    }
+
+  return (0);
+}   
+
+
+int
+gftpui_common_cmd_ls (void *uidata, gftp_request * request, char *command)
+{
+  char *startcolor, *endcolor, *filespec, *tempstr;
+  GList * files, * templist, * delitem;
+  intptr_t sortcol, sortasds;
+  gftp_file * fle;
+  time_t curtime;
+  int got;
+
+  time (&curtime);
+  if (!GFTP_IS_CONNECTED (request))
+    {
+      request->logging_function (gftp_logging_error, request,
+                     _("Error: Not connected to a remote site\n"));
+      return (1);
+    }
+
+  filespec = *command != '\0' ? command : NULL;
+  if (gftp_list_files (request) != 0)
+    return (1);
+
+  files = NULL;
+  fle = g_malloc0 (sizeof (*fle));
+  while ((got = gftp_get_next_file (request, NULL, fle)) > 0 ||
+         got == GFTP_ERETRYABLE)
+    {
+      if (got < 0 || strcmp (fle->file, ".") == 0)
+        {
+          gftp_file_destroy (fle);
+          continue;
+        }
+      files = g_list_prepend (files, fle);
+      fle = g_malloc0 (sizeof (*fle));
+    }
+  g_free (fle);
+
+  if (files == NULL)
+    {
+      gftp_end_transfer (request);
+      return (1);
+    }
+
+  if (request == gftpui_common_local_request)
+    {
+      gftp_lookup_request_option (request, "local_sortcol", &sortcol);
+      gftp_lookup_request_option (request, "local_sortasds", &sortasds);
+    }
+  else
+    {
+      gftp_lookup_request_option (request, "remote_sortcol", &sortcol);
+      gftp_lookup_request_option (request, "remote_sortasds", &sortasds);
+    }
+
+  files = gftp_sort_filelist (files, sortcol, sortasds);
+  delitem = NULL;
+  for (templist = files; templist != NULL; templist = templist->next)
+    {
+      if (delitem != NULL)
+        {
+          fle = delitem->data;
+          gftp_file_destroy (fle);
+          g_free (fle);
+          delitem = NULL;
+        }
+
+      fle = templist->data;
+
+      gftpui_lookup_file_colors (fle, &startcolor, &endcolor);
+      tempstr = gftp_gen_ls_string (fle, startcolor, endcolor);
+
+      request->logging_function (gftp_logging_misc, request, "%s\n", tempstr);
+
+      g_free (tempstr);
+
+      delitem = templist;
+    }
+
+  gftp_end_transfer (request);
+
+  if (delitem != NULL)
+    {
+      fle = delitem->data;
+      gftp_file_destroy (fle);
+      g_free (fle);
+      delitem = NULL;
+    }
+
+  if (files != NULL)
+    g_list_free (files);
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_set (void *uidata, gftp_request * request, char *command)
+{
+  gftp_config_vars * cv, newcv;
+  gftp_logging_func logfunc;
+  char *pos, *backpos;
+  GList * templist;
+  int i;
+  
+  logfunc = _gftpui_common_log (request);
+
+  if (command == NULL || *command == '\0')
+    {
+      for (templist = gftp_options_list;
+           templist != NULL; 
+           templist = templist->next)
+        {
+          cv = templist->data;
+
+          for (i=0; cv[i].key != NULL; i++)
+            { 
+              if (!(cv[i].ports_shown & GFTP_PORT_TEXT))
+                continue;
+
+              if (*cv[i].key == '\0' ||
+                  gftp_option_types[cv[i].otype].write_function == NULL)
+                continue;
+
+              printf ("%s = ", cv[i].key);
+              gftp_option_types[cv[i].otype].write_function (&cv[i], stdout, 0);
+              printf ("\n");
+            }
+        }
+    }
+  else
+    {
+      if ((pos = strchr (command, '=')) == NULL)
+        {
+          logfunc (gftp_logging_error, request,
+                   _("usage: set [variable = value]\n"));
+          return (1);
+        }
+      *pos = '\0';
+
+      for (backpos = pos - 1;
+           (*backpos == ' ' || *backpos == '\t') && backpos > command;
+           backpos--)
+        *backpos = '\0';
+      for (++pos; *pos == ' ' || *pos == '\t'; pos++);
+
+      if ((cv = g_hash_table_lookup (gftp_global_options_htable, command)) == NULL)
+        {
+          logfunc (gftp_logging_error, request,
+                   _("Error: Variable %s is not a valid configuration variable.\n"), command);
+          return (1);
+        }
+
+      if (!(cv->ports_shown & GFTP_PORT_TEXT))
+        {
+          logfunc (gftp_logging_error, request,
+                   _("Error: Variable %s is not available in the text port of gFTP\n"), command);
+          return (1);
+        }
+
+      if (gftp_option_types[cv->otype].read_function != NULL)
+        {
+          memcpy (&newcv, cv, sizeof (newcv));
+          newcv.flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
+
+          gftp_option_types[cv->otype].read_function (pos, &newcv, 1);
+
+          gftp_set_global_option (command, newcv.value);
+
+          if (newcv.flags & GFTP_CVARS_FLAGS_DYNMEM)
+            g_free (newcv.value);
+        }
+    }
+
+  return (1);
+}
+
+
+static int
+gftpui_common_cmd_help (void *uidata, gftp_request * request, char *command)
+{
+  int i, j, ele, numrows, numcols = 6, handled, number_commands;
+  char *pos;
+
+  for (number_commands=0;
+       gftpui_common_commands[number_commands].command != NULL;
+       number_commands++);
+
+  if (command != NULL && *command != '\0')
+    {
+      for (pos = command; *pos != ' ' && *pos != '\0'; pos++);
+      if (*pos == ' ')
+        {
+          *pos++ = '\0';
+          if (*pos == '\0')
+            pos = NULL;
+        }
+      else
+        pos = NULL;
+
+      for (i=0; gftpui_common_commands[i].command != NULL; i++)
+        {
+          if (strcmp (gftpui_common_commands[i].command, command) == 0)
+            break;
+        }
+
+      if (gftpui_common_commands[i].cmd_description != NULL)
+        {
+          if (pos != NULL && gftpui_common_commands[i].subhelp_func != NULL)
+            handled = gftpui_common_commands[i].subhelp_func (pos);
+          else
+            handled = 0;
+
+          if (!handled)
+            printf ("%s\n", _(gftpui_common_commands[i].cmd_description));
+        }
+      else
+        *command = '\0';
+    }
+  
+  if (command == NULL || *command == '\0')
+    {
+      numrows = number_commands / numcols;
+      if (number_commands % numcols != 0)
+        numrows++;
+
+      printf (_("Supported commands:\n\n"));
+      for (i=0; i<numrows; i++)
+        {
+          printf ("     ");
+          for (j=0; j<numcols; j++)
+            {
+              ele = i + j * numrows;
+              if (ele >= number_commands)
+                break;
+              printf ("%-10s", gftpui_common_commands[ele].command);
+            }
+         printf ("\n");
+        }
+
+      printf ("\n");
+    }
+  return (1);
+}
+
+
+gftpui_common_methods gftpui_common_commands[] = {
+        {N_("about"),   2, gftpui_common_cmd_about, gftpui_common_request_none,
+         N_("Shows gFTP information"), NULL},
+        {N_("ascii"),   2, gftpui_common_cmd_ascii, gftpui_common_request_remote,
+         N_("Sets the current file transfer mode to Ascii (only for FTP)"), NULL},
+        {N_("binary"),  1, gftpui_common_cmd_binary, gftpui_common_request_remote,
+         N_("Sets the current file transfer mode to Binary (only for FTP)"), NULL},
+        {N_("cd"),      2, gftpui_common_cmd_chdir, gftpui_common_request_remote,
+         N_("Changes the remote working directory"), NULL},
+        {N_("chdir"),   3, gftpui_common_cmd_chdir, gftpui_common_request_remote,
+         N_("Changes the remote working directory"), NULL},
+        {N_("chmod"),   3, gftpui_common_cmd_chmod, gftpui_common_request_remote,
+         N_("Changes the permissions of a remote file"), NULL},
+        {N_("clear"),   3, gftpui_common_cmd_clear, gftpui_common_request_none,
+         N_("Available options: cache"), gftpui_common_clear_show_subhelp},
+        {N_("close"),   3, gftpui_common_cmd_close, gftpui_common_request_remote,
+         N_("Disconnects from the remote site"), NULL},
+        {N_("delete"),  1, gftpui_common_cmd_delete,    gftpui_common_request_remote,
+         N_("Removes a remote file"), NULL},
+/* FIXME
+        {N_("get"),     1, gftp_text_mget_file, gftpui_common_request_none,
+         N_("Downloads remote file(s)"), NULL},
+*/
+        {N_("help"),    1, gftpui_common_cmd_help, gftpui_common_request_none,
+         N_("Shows this help screen"), NULL},
+        {N_("lcd"),     3, gftpui_common_cmd_chdir, gftpui_common_request_local,
+         N_("Changes the local working directory"), NULL},
+        {N_("lchdir"),  4, gftpui_common_cmd_chdir, gftpui_common_request_local,
+         N_("Changes the local working directory"), NULL},
+        {N_("lchmod"),  4, gftpui_common_cmd_chmod,     gftpui_common_request_local,
+         N_("Changes the permissions of a local file"), NULL},
+        {N_("ldelete"), 2, gftpui_common_cmd_delete,    gftpui_common_request_local,
+         N_("Removes a local file"), NULL},
+        {N_("lls"),     2, gftpui_common_cmd_ls, gftpui_common_request_local,
+         N_("Shows the directory listing for the current local directory"), NULL},
+        {N_("lmkdir"),  2, gftpui_common_cmd_mkdir, gftpui_common_request_local,
+         N_("Creates a local directory"), NULL},
+        {N_("lpwd"),    2, gftpui_common_cmd_pwd, gftpui_common_request_local,
+         N_("Show current local directory"), NULL},
+        {N_("lrename"), 3, gftpui_common_cmd_rename, gftpui_common_request_local,
+         N_("Rename a local file"), NULL},
+        {N_("lrmdir"),  3, gftpui_common_cmd_rmdir, gftpui_common_request_local,
+         N_("Remove a local directory"), NULL},
+        {N_("ls"),      2, gftpui_common_cmd_ls, gftpui_common_request_remote,
+         N_("Shows the directory listing for the current remote directory"), NULL},
+/* FIXME
+        {N_("mget"),    2, gftp_text_mget_file, gftpui_common_request_none,
+         N_("Downloads remote file(s)"), NULL},
+*/
+        {N_("mkdir"),   2, gftpui_common_cmd_mkdir,     gftpui_common_request_remote,
+         N_("Creates a remote directory"), NULL},
+/* FIXME
+        {N_("mput"),    2, gftp_text_mput_file, gftpui_common_request_none,
+         N_("Uploads local file(s)"), NULL},
+        {N_("open"),    1, gftp_text_open,      gftpui_common_request_remote,
+         N_("Opens a connection to a remote site"), NULL},
+        {N_("put"),     2, gftp_text_mput_file, gftpui_common_request_none,
+         N_("Uploads local file(s)"), NULL},
+*/
+        {N_("pwd"),     2, gftpui_common_cmd_pwd, gftpui_common_request_remote,
+         N_("Show current remote directory"), NULL},
+        {N_("quit"),    1, gftpui_common_cmd_quit, gftpui_common_request_none,
+         N_("Exit from gFTP"), NULL},
+        {N_("rename"),  2, gftpui_common_cmd_rename, gftpui_common_request_remote,
+         N_("Rename a remote file"), NULL},
+        {N_("rmdir"),   2, gftpui_common_cmd_rmdir, gftpui_common_request_remote,
+         N_("Remove a remote directory"), NULL},
+        {N_("set"),     1, gftpui_common_cmd_set, gftpui_common_request_none,
+         N_("Show configuration file variables. You can also set variables by set var=val"), gftpui_common_set_show_subhelp},
+        {NULL,          0, NULL,                gftpui_common_request_none,
+	 NULL, NULL}};
+
+
+int
+gftpui_common_init (void *locui, gftp_request * locreq,
+                    void *remui, gftp_request * remreq)
+{
+  gftpui_common_local_uidata = locui;
+  gftpui_common_local_request = locreq;
+
+  gftpui_common_remote_uidata = remui;
+  gftpui_common_remote_request = remreq;
+
+  return (0);
+}
+
+
+int
+gftpui_common_process_command (const char *command)
+{
+  const char *stpos;
+  char *pos, *newstr;
+  gftp_request * request;
+  size_t cmdlen;
+  void *uidata;
+  int ret, i;
+  size_t len;
+
+  for (stpos = command; *stpos == ' ' || *stpos == '\t'; stpos++);
+
+  newstr = g_strdup (stpos);
+  len = strlen (newstr);
+
+  if (len > 0 && newstr[len - 1] == '\n')
+    newstr[--len] = '\0';
+  if (len > 0 && newstr[len - 1] == '\r')
+    newstr[--len] = '\0';
+
+  for (pos = newstr + len - 1;
+       (*pos == ' ' || *pos == '\t') && pos > newstr;
+       pos--)
+    *pos = '\0';
+
+  if (*stpos == '\0')
+    {
+      g_free (newstr);
+      return (1);
+    }
+
+  if ((pos = strchr (newstr, ' ')) != NULL)
+    *pos = '\0'; 
+
+  cmdlen = strlen (newstr);
+  for (i=0; gftpui_common_commands[i].command != NULL; i++)
+    {
+      if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
+        break;
+      else if (cmdlen >= gftpui_common_commands[i].minlen &&
+               strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
+        break; 
+    }
+
+  if (pos != NULL)
+    pos++;
+  else
+    pos = "";
+  
+  if (gftpui_common_commands[i].command != NULL)
+    {
+      if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
+        {
+          request = gftpui_common_local_request;
+          uidata = gftpui_common_local_uidata;
+        }
+      else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
+        {
+          request = gftpui_common_remote_request;
+          uidata = gftpui_common_remote_uidata;
+        }
+      else
+        {
+          request = NULL;
+          uidata = NULL;
+        }
+     
+      ret = gftpui_common_commands[i].func (uidata, request, pos);
+    }
+  else
+    {
+      gftpui_common_local_request->logging_function (gftp_logging_error,
+                                       gftpui_common_local_request,
+                                       _("Error: Command not recognized\n"));
+      ret = 1;
+    }
+
+  g_free (newstr);
+  return (ret);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uicommon/gftpui.h	Sun Dec 28 16:02:07 2003 +0000
@@ -0,0 +1,113 @@
+/*****************************************************************************/
+/*  gftpui.h - UI related functions for gFTP                                 */
+/*  Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>                  */
+/*                                                                           */
+/*  This program is free software; you can redistribute it and/or modify     */
+/*  it under the terms of the GNU General Public License as published by     */
+/*  the Free Software Foundation; either version 2 of the License, or        */
+/*  (at your option) any later version.                                      */
+/*                                                                           */
+/*  This program is distributed in the hope that it will be useful,          */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
+/*  GNU General Public License for more details.                             */
+/*                                                                           */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program; if not, write to the Free Software              */
+/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
+/*****************************************************************************/
+
+/* $Id$ */
+
+#ifndef __GFTPUI_H
+#define __GFTPUI_H
+
+#include "../../lib/gftp.h"
+
+typedef struct _gftpui_callback_data gftpui_callback_data;
+
+struct _gftpui_callback_data
+{
+  gftp_request * request;
+  void *uidata;
+  char *input_string,
+       *source_string;
+  int (*run_function) (gftpui_callback_data * cdata);
+};
+
+
+typedef enum _gftpui_common_request_type
+{
+  gftpui_common_request_none,
+  gftpui_common_request_local,
+  gftpui_common_request_remote
+} gftpui_common_request_type;
+
+
+typedef struct _gftpui_common_methods
+{
+  char *command;
+  int minlen;
+  int (*func)(void *uidata, gftp_request * request, char *command);
+  gftpui_common_request_type reqtype;
+  char *cmd_description;
+  int (*subhelp_func) (char *topic);
+} gftpui_common_methods;
+
+#define gftpui_common_use_threads(request)	(gftp_protocols[(request)->protonum].use_threads)
+
+#define GFTPUI_COMMON_COLOR_BLACK     "\033[30m"
+#define GFTPUI_COMMON_COLOR_RED       "\033[31m"
+#define GFTPUI_COMMON_COLOR_GREEN     "\033[32m"
+#define GFTPUI_COMMON_COLOR_YELLOW    "\033[33m"
+#define GFTPUI_COMMON_COLOR_BLUE      "\033[34m"
+#define GFTPUI_COMMON_COLOR_MAGENTA   "\033[35m"
+#define GFTPUI_COMMON_COLOR_CYAN      "\033[36m"
+#define GFTPUI_COMMON_COLOR_WHITE     "\033[37m"
+#define GFTPUI_COMMON_COLOR_GREY      "\033[38m"
+#define GFTPUI_COMMON_COLOR_DEFAULT   "\033[39m"
+#define GFTPUI_COMMON_COLOR_NONE	""
+
+extern sigjmp_buf gftpui_common_jmp_environment;
+extern volatile int gftpui_common_use_jmp_environment;
+extern gftpui_common_methods gftpui_common_commands[];
+
+/* gftpui.c */
+int gftpui_run_callback_function	( gftpui_callback_data * cdata );
+
+int gftpui_common_run_callback_function ( gftpui_callback_data * cdata );
+
+RETSIGTYPE gftpui_common_signal_handler ( int signo );
+
+void gftpui_common_about 		( gftp_logging_func logging_function,
+					  gpointer logdata );
+
+int gftpui_common_init			( void *locui,
+					  gftp_request * locreq,
+					  void *remui,
+					  gftp_request * remreq );
+
+int gftpui_common_process_command 	( const char *command );
+
+/* gftpuicallback.c */
+int gftpui_common_run_mkdir 		( gftpui_callback_data * cdata );
+
+int gftpui_common_run_rename 		( gftpui_callback_data * cdata );
+
+int gftpui_common_run_site 		( gftpui_callback_data * cdata );
+
+int gftpui_common_run_chdir 		( gftpui_callback_data * cdata );
+
+/* UI Functions that must be implemented by each distinct UI */
+void gftpui_lookup_file_colors 		( gftp_file * fle,
+					  char **start_color,
+					  char ** end_color );
+
+int gftpui_check_reconnect		( gftpui_callback_data * cdata );
+
+void gftpui_refresh 			( void *uidata );
+
+void *gftpui_generic_thread 		( void *(*run_function)(void *data),
+					  void *data);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uicommon/gftpuicallbacks.c	Sun Dec 28 16:02:07 2003 +0000
@@ -0,0 +1,67 @@
+/*****************************************************************************/
+/*  gftpui.c - UI related functions for gFTP. All of these functions must be */
+/*             reentrant.                                                    */
+/*  Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>                  */
+/*                                                                           */
+/*  This program is free software; you can redistribute it and/or modify     */
+/*  it under the terms of the GNU General Public License as published by     */
+/*  the Free Software Foundation; either version 2 of the License, or        */
+/*  (at your option) any later version.                                      */
+/*                                                                           */
+/*  This program is distributed in the hope that it will be useful,          */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
+/*  GNU General Public License for more details.                             */
+/*                                                                           */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program; if not, write to the Free Software              */
+/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
+/*****************************************************************************/
+
+#include "gftpui.h"
+static const char cvsid[] = "$Id$";
+
+int
+gftpui_common_run_mkdir (gftpui_callback_data * cdata)
+{
+  int ret;
+
+  ret = gftp_make_directory (cdata->request, cdata->input_string) == 0;
+
+  return (ret);
+}
+
+
+int
+gftpui_common_run_rename (gftpui_callback_data * cdata)
+{
+  int ret;
+
+  ret = gftp_rename_file (cdata->request, cdata->source_string,
+                          cdata->input_string) == 0;
+
+  return (ret);
+}
+
+
+int
+gftpui_common_run_site (gftpui_callback_data * cdata)
+{
+  int ret;
+
+  ret = gftp_site_cmd (cdata->request, cdata->input_string) == 0;
+
+  return (ret);
+}
+
+
+int
+gftpui_common_run_chdir (gftpui_callback_data * cdata)
+{
+  int ret;
+
+  ret = gftp_set_directory (cdata->request, cdata->input_string) == 0;
+
+  return (ret);
+}
+