changeset 58:c01d91c10f6c

2002-11-20 Brian Masney <masneyb@gftp.org> * lib/protocols.c lib/gftp.h - added gftp_get_line(), gftp_read(), gftp_write(), gftp_writefmt(), and gftp_set_sockblocking() functions. Added struct_gftp_getline_buffer for gftp_get_line function() * lib/cache.c lib/gftp.h lib/local.c lib/misc.c lib/protocols.c lib/rfc2068.c lib/rfc959.c lib/ssh.c lib/sshv2.c - *_get_file() returns off_t instead of long. *_{get,put}_next_file_chunk returns ssize_t instead of size_t. Added *_set_config_options function to gftp_request structure and protocol files. Use the new network functions documented above. Convert usage of ANSI C IO (FILE *) to standard BSD sockets so that I can use timeouts properly with select * lib/misc.c (ssh_start_login_sequence) - use gftp_set_sockblock(), gftp_read() and gftp_write() functions * lib/protocols.c - move some protocol specific code to the protocol specific files * lib/local.c - log succesful messages to gftp_logging_misc instead of gftp_logging_error * lib/cache.c - log some more error conditions to the user * lib/rfc959.c - added rfc959_getcwd(). In, rfc959_accept_active_connection(), set set socket to blocking mode before calling accept() * src/text/gftk-text.c - If we get no files in gftp_text_ls(), return instead of segfaulting * src/gtk/gftp-gtk.c - expand the port field in the toolbar to be 45 pixels wide * src/text/gftp-text.c src/gtk/misc-gtk.c src/gtk/transfer.c src/gtk/view_dialog.c - changes for conversion of request->{sock,data} from ANSI C IO (FILE *) to standard BSD sockets
author masneyb
date Thu, 21 Nov 2002 00:33:51 +0000
parents 72f6ca02c83a
children 618423504fe0
files ChangeLog aclocal.m4 configure.in lib/cache.c lib/config_file.c lib/gftp.h lib/local.c lib/misc.c lib/protocols.c lib/rfc2068.c lib/rfc959.c lib/ssh.c lib/sshv2.c src/gtk/dnd.c src/gtk/gftp-gtk.c src/gtk/misc-gtk.c src/gtk/transfer.c src/gtk/view_dialog.c src/text/gftp-text.c
diffstat 19 files changed, 1181 insertions(+), 1110 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Nov 12 00:04:44 2002 +0000
+++ b/ChangeLog	Thu Nov 21 00:33:51 2002 +0000
@@ -1,3 +1,41 @@
+2002-11-20 Brian Masney <masneyb@gftp.org>
+	* lib/protocols.c lib/gftp.h - added gftp_get_line(), gftp_read(), 
+	gftp_write(), gftp_writefmt(), and gftp_set_sockblocking() functions. 
+	Added struct_gftp_getline_buffer for gftp_get_line function()
+
+	* lib/cache.c lib/gftp.h lib/local.c lib/misc.c lib/protocols.c 
+	lib/rfc2068.c lib/rfc959.c lib/ssh.c lib/sshv2.c - *_get_file() returns
+	off_t instead of long. *_{get,put}_next_file_chunk returns ssize_t 
+	instead of size_t. Added *_set_config_options function to gftp_request
+	structure and protocol files. Use the new network functions
+	documented above. Convert usage of ANSI C IO (FILE *) to standard BSD 
+	sockets so that I can use timeouts properly with select
+
+	* lib/misc.c (ssh_start_login_sequence) - use gftp_set_sockblock(),
+	gftp_read() and gftp_write() functions
+
+	* lib/protocols.c - move some protocol specific code to the protocol
+	specific files
+
+	* lib/local.c - log succesful messages to gftp_logging_misc instead
+	of gftp_logging_error
+
+	* lib/cache.c - log some more error conditions to the user
+
+	* lib/rfc959.c - added rfc959_getcwd(). In, 
+	rfc959_accept_active_connection(), set set socket to blocking mode
+	before calling accept()
+
+	* src/text/gftk-text.c - If we get no files in gftp_text_ls(),
+	return instead of segfaulting
+
+	* src/gtk/gftp-gtk.c - expand the port field in the toolbar to be 45
+	pixels wide
+
+	* src/text/gftp-text.c src/gtk/misc-gtk.c src/gtk/transfer.c 
+	src/gtk/view_dialog.c - changes for conversion of request->{sock,data} 
+	from ANSI C IO (FILE *) to standard BSD sockets
+
 2002-11-11 Brian Masney <masneyb@gftp.org>
 	* configure.in - compile GTK+ 2.0 port by default
 
@@ -202,7 +240,7 @@
 
 	* cvsclean - added this script
 
-	* *.[ch] - added $Id: ChangeLog,v 1.32 2002/11/12 00:04:44 masneyb Exp $ tags
+	* *.[ch] - added $Id: ChangeLog,v 1.33 2002/11/21 00:33:49 masneyb Exp $ tags
 
 	* debian/* - updated files from Debian maintainer
 
--- a/aclocal.m4	Tue Nov 12 00:04:44 2002 +0000
+++ b/aclocal.m4	Thu Nov 21 00:33:51 2002 +0000
@@ -414,6 +414,64 @@
   $1_FALSE=
 fi])
 
+
+dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
+dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
+dnl also defines GSTUFF_PKG_ERRORS on error
+AC_DEFUN(PKG_CHECK_MODULES, [
+  succeeded=no
+
+  if test -z "$PKG_CONFIG"; then
+    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+  fi
+
+  if test "$PKG_CONFIG" = "no" ; then
+     echo "*** The pkg-config script could not be found. Make sure it is"
+     echo "*** in your path, or set the PKG_CONFIG environment variable"
+     echo "*** to the full path to pkg-config."
+     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+  else
+     PKG_CONFIG_MIN_VERSION=0.9.0
+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+        AC_MSG_CHECKING(for $2)
+
+        if $PKG_CONFIG --exists "$2" ; then
+            AC_MSG_RESULT(yes)
+            succeeded=yes
+
+            AC_MSG_CHECKING($1_CFLAGS)
+            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
+            AC_MSG_RESULT($$1_CFLAGS)
+
+            AC_MSG_CHECKING($1_LIBS)
+            $1_LIBS=`$PKG_CONFIG --libs "$2"`
+            AC_MSG_RESULT($$1_LIBS)
+        else
+            $1_CFLAGS=""
+            $1_LIBS=""
+            ## If we have a custom action on failure, don't print errors, but 
+            ## do set a variable so people can do so.
+            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+            ifelse([$4], ,echo $$1_PKG_ERRORS,)
+        fi
+
+        AC_SUBST($1_CFLAGS)
+        AC_SUBST($1_LIBS)
+     else
+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
+     fi
+  fi
+
+  if test $succeeded = yes; then
+     ifelse([$3], , :, [$3])
+  else
+     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
+  fi
+])
+
+
+
 # Configure paths for GLIB
 # Owen Taylor     97-11-3
 
@@ -612,64 +670,6 @@
 ])
 
 
-dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
-dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
-dnl also defines GSTUFF_PKG_ERRORS on error
-AC_DEFUN(PKG_CHECK_MODULES, [
-  succeeded=no
-
-  if test -z "$PKG_CONFIG"; then
-    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
-  fi
-
-  if test "$PKG_CONFIG" = "no" ; then
-     echo "*** The pkg-config script could not be found. Make sure it is"
-     echo "*** in your path, or set the PKG_CONFIG environment variable"
-     echo "*** to the full path to pkg-config."
-     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
-  else
-     PKG_CONFIG_MIN_VERSION=0.9.0
-     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
-        AC_MSG_CHECKING(for $2)
-
-        if $PKG_CONFIG --exists "$2" ; then
-            AC_MSG_RESULT(yes)
-            succeeded=yes
-
-            AC_MSG_CHECKING($1_CFLAGS)
-            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
-            AC_MSG_RESULT($$1_CFLAGS)
-
-            AC_MSG_CHECKING($1_LIBS)
-            $1_LIBS=`$PKG_CONFIG --libs "$2"`
-            AC_MSG_RESULT($$1_LIBS)
-        else
-            $1_CFLAGS=""
-            $1_LIBS=""
-            ## If we have a custom action on failure, don't print errors, but 
-            ## do set a variable so people can do so.
-            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
-            ifelse([$4], ,echo $$1_PKG_ERRORS,)
-        fi
-
-        AC_SUBST($1_CFLAGS)
-        AC_SUBST($1_LIBS)
-     else
-        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
-        echo "*** See http://www.freedesktop.org/software/pkgconfig"
-     fi
-  fi
-
-  if test $succeeded = yes; then
-     ifelse([$3], , :, [$3])
-  else
-     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
-  fi
-])
-
-
-
-
 # serial 1
 
 AC_DEFUN([AM_WITH_DMALLOC],
--- a/configure.in	Tue Nov 12 00:04:44 2002 +0000
+++ b/configure.in	Thu Nov 21 00:33:51 2002 +0000
@@ -247,4 +247,4 @@
 
 AM_GNU_GETTEXT
 
-AC_OUTPUT(Makefile docs/Makefile docs/sample.gftp/Makefile src/gftp src/Makefile src/gtk/Makefile src/text/Makefile lib/Makefile gftp.spec intl/Makefile po/Makefile.in )
+AC_OUTPUT(Makefile docs/Makefile docs/sample.gftp/Makefile src/gftp src/Makefile src/gtk/Makefile src/text/Makefile lib/Makefile gftp.spec)
--- a/lib/cache.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/cache.c	Thu Nov 21 00:33:51 2002 +0000
@@ -31,65 +31,90 @@
 }
 
 
-FILE *
+int
 gftp_new_cache_entry (gftp_request * request)
 {
-  char *cachedir, tempstr[BUFSIZ];
-  int cache_fd;
-  FILE *fd;
+  char *cachedir, *tempstr, *temp1str;
+  int cache_fd, fd;
+  ssize_t ret;
 
-  if ((fd = gftp_find_cache_entry (request)) != NULL)
+  if ((fd = gftp_find_cache_entry (request)) > 0)
     return (fd);
 
   cachedir = expand_path (BASE_CONF_DIR "/cache");
   if (access (cachedir, F_OK) == -1)
     {
-      if (mkdir (cachedir, 0x1C0) < 0)
-        return (NULL);
+      if (mkdir (cachedir, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
+        {
+          if (request != NULL)
+            request->logging_function (gftp_logging_error, request->user_data,
+                                 _("Error: Could not make directory %s: %s\n"),
+                                 cachedir, g_strerror (errno));
+
+          return (-1);
+        }
     }
 
-  g_snprintf (tempstr, sizeof (tempstr), "%s/index.db", cachedir);
-  if ((fd = fopen (tempstr, "ab+")) == NULL)
+  tempstr = g_strdup_printf ("%s/index.db", cachedir);
+  if ((fd = open (tempstr, O_WRONLY | O_APPEND | O_CREAT, 
+                  S_IRUSR | S_IWUSR)) == -1)
     {
+      if (request != NULL)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error: Cannot open local file %s: %s\n"),
+                                   tempstr, g_strerror (errno));
+
+      g_free (tempstr);
       g_free (cachedir);
-      return (NULL);
+      return (-1);
     }
+  g_free (tempstr);
 
-  g_snprintf (tempstr, sizeof (tempstr), "%s/cache.XXXXXX", cachedir);
+  tempstr = g_strdup_printf ("%s/cache.XXXXXX", cachedir);
   if ((cache_fd = mkstemp (tempstr)) < 0)
-    return (NULL);
+    {
+      g_free (tempstr);
+      if (request != NULL)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                 _("Error: Cannot create temporary file: %s\n"),
+                                 g_strerror (errno));
+      return (-1);
+    }
   g_free (cachedir);
 
-  fseek (fd, 0, SEEK_END);
-  fprintf (fd, "%s://%s@%s:%d%s\t%s\n", 
-              gftp_cache_get_url_prefix (request),
-              request->username == NULL ? "" : request->username,
-              request->hostname == NULL ? "" : request->hostname,
-              request->port, 
-              request->directory == NULL ? "" : request->directory,
-              tempstr);
+  lseek (fd, 0, SEEK_END);
+  temp1str = g_strdup_printf ("%s://%s@%s:%d%s\t%s\n", 
+                           gftp_cache_get_url_prefix (request),
+                           request->username == NULL ? "" : request->username,
+                           request->hostname == NULL ? "" : request->hostname,
+                           request->port, 
+                           request->directory == NULL ? "" : request->directory,
+                           tempstr);
+  g_free (tempstr);
+  ret = gftp_write (NULL, temp1str, strlen (temp1str), fd);
+  g_free (temp1str);
 
-  if (fclose (fd) != 0)
+  if (close (fd) != 0 || ret < 0)
     {
+      if (request != NULL)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error closing file descriptor: %s\n"),
+                                   g_strerror (errno));
+
       close (cache_fd);
-      return (NULL);
+      return (-1);
     }
 
-  if ((fd = fdopen (cache_fd, "wb+")) == NULL)
-    {
-      close (cache_fd);
-      return (NULL);
-    }
-
-  return (fd);
+  return (cache_fd);
 }
 
 
-FILE *
+int
 gftp_find_cache_entry (gftp_request * request)
 {
   char *indexfile, *pos, buf[BUFSIZ], description[BUFSIZ];
-  FILE *indexfd, *cachefd;
+  gftp_getline_buffer * rbuf;
+  int indexfd, cachefd;
   size_t len;
 
   g_snprintf (description, sizeof (description), "%s://%s@%s:%d%s",
@@ -100,14 +125,20 @@
               request->directory == NULL ? "" : request->directory);
 
   indexfile = expand_path (BASE_CONF_DIR "/cache/index.db");
-  if ((indexfd = fopen (indexfile, "rb")) == NULL)
+  if ((indexfd = open (indexfile, O_RDONLY)) == -1)
     {
+      if (request != NULL)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error: Cannot open local file %s: %s\n"),
+                                   indexfile, g_strerror (errno));
+
       g_free (indexfile);
-      return (NULL);
+      return (-1);
     }
   g_free (indexfile);
 
-  while (fgets (buf, sizeof (buf), indexfd))
+  rbuf = NULL;
+  while (gftp_get_line (NULL, &rbuf, buf, sizeof (buf) - 1, indexfd) > 0)
     {
       len = strlen (buf);
       if (buf[len - 1] == '\n')
@@ -125,24 +156,47 @@
       if (strncmp (buf, description, len) == 0)
 	{
 	  pos++;
-	  if (fclose (indexfd) != 0)
-            return (NULL);
-
-	  if ((cachefd = fopen (pos, "rb+")) == NULL)
-            return (NULL);
+	  if (close (indexfd) != 0)
+            {
+              if (request != NULL)
+                request->logging_function (gftp_logging_error, 
+                                       request->user_data,
+                                       _("Error closing file descriptor: %s\n"),
+                                       g_strerror (errno));
+              return (-1);
+            }
 
-          fseek (cachefd, 0, SEEK_END);
-          if (ftell (cachefd) == 0)
+	  if ((cachefd = open (pos, O_RDONLY)) == -1)
+            {
+              if (request != NULL)
+                request->logging_function (gftp_logging_error, 
+                                   request->user_data,
+                                   _("Error: Cannot open local file %s: %s\n"),
+                                   pos, g_strerror (errno));
+              return (-1);
+            }
+
+          if (lseek (cachefd, 0, SEEK_END) == 0)
             { 
-              fclose (cachefd); 
-              return (NULL);
+              close (cachefd); 
+              return (-1);
             } 
-          fseek (cachefd, 0, SEEK_SET);
+
+          if (lseek (cachefd, 0, SEEK_SET) == -1)
+            {
+              if (request != NULL)
+                request->logging_function (gftp_logging_error, 
+                                       request->user_data,
+                                       _("Error: Cannot seek on file %s: %s\n"),
+                                       pos, g_strerror (errno));
+
+            }
+
 	  return (cachefd);
 	}
     }
-  fclose (indexfd);
-  return (NULL);
+  close (indexfd);
+  return (-1);
 }
 
 
@@ -150,17 +204,19 @@
 gftp_clear_cache_files (void)
 {
   char *indexfile, buf[BUFSIZ], *pos;
-  FILE *indexfd;
+  gftp_getline_buffer * rbuf;
+  int indexfd;
   size_t len;
 
   indexfile = expand_path (BASE_CONF_DIR "/cache/index.db");
-  if ((indexfd = fopen (indexfile, "rb")) == NULL)
+  if ((indexfd = open (indexfile, O_RDONLY)) == -1)
     {
       g_free (indexfile);
       return;
     }
 
-  while (fgets (buf, sizeof (buf), indexfd))
+  rbuf = NULL;
+  while (gftp_get_line (NULL, &rbuf, buf, sizeof (buf) - 1, indexfd) > 0)
     {
       len = strlen (buf);
       if (buf[len - 1] == '\n')
@@ -169,14 +225,11 @@
         buf[--len] = '\0';
 
       if (!((pos = strrchr (buf, '\t')) != NULL && *(pos + 1) != '\0'))
-        {
-          printf (_("Error: Invalid line %s in cache index file\n"), buf);
-	  continue;
-        }
+	continue;
       unlink (pos + 1);
     }
 
-  fclose (indexfd);
+  close (indexfd);
   unlink (indexfile);
   g_free (indexfile);
 }
@@ -186,7 +239,8 @@
 gftp_delete_cache_entry (gftp_request * request, int ignore_directory)
 {
   char *oldindexfile, *newindexfile, *pos, buf[BUFSIZ], description[BUFSIZ];
-  FILE *indexfd, *newfd;
+  gftp_getline_buffer * rbuf;
+  int indexfd, newfd;
   size_t len, buflen;
   int remove;
 
@@ -198,22 +252,34 @@
               ignore_directory || request->directory == NULL ? "" : request->directory);
 
   oldindexfile = expand_path (BASE_CONF_DIR "/cache/index.db");
-  if ((indexfd = fopen (oldindexfile, "rb")) == NULL)
+  if ((indexfd = open (oldindexfile, O_RDONLY)) == -1)
     {
+      if (request != NULL)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error: Cannot open local file %s: %s\n"),
+                                   oldindexfile, g_strerror (errno));
+
       g_free (oldindexfile);
       return;
     }
 
   newindexfile = expand_path (BASE_CONF_DIR "/cache/index.db.new");
-  if ((newfd = fopen (newindexfile, "wb")) == NULL)
+  if ((newfd = open (newindexfile, O_WRONLY | O_CREAT, 
+                     S_IRUSR | S_IWUSR)) == -1)
     {
+      if (request != NULL)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error: Cannot open local file %s: %s\n"),
+                                   newindexfile, g_strerror (errno));
+
       g_free (oldindexfile);
       g_free (newindexfile);
       return;
     }
 
+  rbuf = NULL;
   buflen = strlen (description);
-  while (fgets (buf, sizeof (buf) - 1, indexfd))
+  while (gftp_get_line (NULL, &rbuf, buf, sizeof (buf) - 1, indexfd) > 0)
     {
       len = strlen (buf);
       if (buf[len - 1] == '\n')
@@ -223,7 +289,11 @@
 
       if (!((pos = strrchr (buf, '\t')) != NULL && *(pos + 1) != '\0'))
         {
-          printf (_("Error: Invalid line %s in cache index file\n"), buf);
+          if (request != NULL)
+            request->logging_function (gftp_logging_error, request->user_data,
+                            _("Error: Invalid line %s in cache index file\n"), 
+                            buf);
+
           continue;
         }
 
@@ -245,12 +315,13 @@
       else
         {
           buf[strlen (buf)] = '\n';
-          fwrite (buf, 1, strlen (buf), newfd);
+          if (gftp_write (NULL, buf, strlen (buf), newfd) < 0)
+            break;
         }
     }
 
-  fclose (indexfd);
-  fclose (newfd);
+  close (indexfd);
+  close (newfd);
 
   unlink (oldindexfile);
   rename (newindexfile, oldindexfile);
--- a/lib/config_file.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/config_file.c	Thu Nov 21 00:33:51 2002 +0000
@@ -248,7 +248,7 @@
       temp1str = expand_path (BASE_CONF_DIR);
       if (access (temp1str, F_OK) == -1)
 	{
-	  if (mkdir (temp1str, 0700) != 0)
+	  if (mkdir (temp1str, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
 	    {
 	      printf (_("gFTP Error: Could not make directory %s: %s\n"),
 		      temp1str, g_strerror (errno));
@@ -268,7 +268,7 @@
       copyfile (temp1str, tempstr);
       g_free (temp1str);
     }
-  chmod (tempstr, S_IRUSR | S_IWUSR);
+
   if ((conffile = fopen (tempstr, "r")) == NULL)
     {
       printf (_("gFTP Error: Cannot open config file %s: %s\n"), CONFIG_FILE,
@@ -539,18 +539,6 @@
 
   if (access (tempstr, F_OK) == -1)
     {
-      temp1str = expand_path (BASE_CONF_DIR);
-      if (access (temp1str, F_OK) == -1)
-	{
-	  if (mkdir (temp1str, 0700) != 0)
-	    {
-	      printf (_("gFTP Error: Could not make directory %s: %s\n"),
-		      temp1str, g_strerror (errno));
-	      exit (-1);
-	    }
-	}
-      g_free (temp1str);
-
       temp1str = g_strdup_printf ("%s/bookmarks", SHARE_DIR);
       if (access (temp1str, F_OK) == -1)
 	{
@@ -562,7 +550,7 @@
       copyfile (temp1str, tempstr);
       g_free (temp1str);
     }
-  chmod (tempstr, S_IRUSR | S_IWUSR);
+
   if ((bmfile = fopen (tempstr, "r")) == NULL)
     {
       printf (_("gFTP Error: Cannot open bookmarks file %s: %s\n"), tempstr,
--- a/lib/gftp.h	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/gftp.h	Thu Nov 21 00:33:51 2002 +0000
@@ -165,7 +165,7 @@
                is_fd : 1;	/* Is this a file descriptor? */
   char transfer_action;		/* See the GFTP_TRANS_ACTION_* vars above */
   void *node;			/* Pointer to the node for the gui */
-  FILE * fd;
+  int fd;
 };
 
 
@@ -202,10 +202,9 @@
   unsigned int port,		/* Port of remote site */
                proxy_port;	/* Port of the proxy server */
 
-  FILE *sockfd,			/* Control connection (read) */
-       *sockfd_write,		/* Control connection (write) */
-       *datafd,			/* Data connection */
-       *cachefd;		/* For the directory cache */
+  int sockfd,			/* Control connection (read) */
+      datafd,			/* Data connection */
+      cachefd;			/* For the directory cache */
   int wakeup_main_thread[2];	/* FD that gets written to by the threads
                                    to wakeup the parent */
         
@@ -239,13 +238,13 @@
   void (*destroy)			( gftp_request * request );
   int (*connect)			( gftp_request * request );
   void (*disconnect) 			( gftp_request * request );
-  long (*get_file) 			( gftp_request * request, 
+  off_t (*get_file) 			( gftp_request * request, 
 					  const char *filename, 
-					  FILE * fd,
+					  int fd,
 					  off_t startsize );
   int (*put_file) 			( gftp_request * request, 
 					  const char *filename, 
-					  FILE * fd,
+					  int fd,
 					  off_t startsize,
 					  off_t totalsize );
   long (*transfer_file) 		( gftp_request * fromreq, 
@@ -254,10 +253,10 @@
 					  gftp_request * toreq, 
 					  const char *tofile, 
 					  off_t tosize );
-  size_t (*get_next_file_chunk) 	( gftp_request * request, 
+  ssize_t (*get_next_file_chunk) 	( gftp_request * request, 
 					  char *buf, 
 					  size_t size );
-  size_t (*put_next_file_chunk) 	( gftp_request * request, 
+  ssize_t (*put_next_file_chunk) 	( gftp_request * request, 
 					  char *buf, 
 					  size_t size );
   int (*end_transfer) 			( gftp_request * request );
@@ -265,7 +264,7 @@
   int (*list_files) 			( gftp_request * request );
   int (*get_next_file)			( gftp_request * request, 
 					  gftp_file *fle, 
-					  FILE *fd );
+					  int fd );
   int (*set_data_type)			( gftp_request * request, 
 					  int data_type );
   off_t (*get_file_size) 		( gftp_request * request, 
@@ -291,6 +290,7 @@
 					  const char *filename );
   int (*parse_url)			( gftp_request * request,
 					  const char *url );
+  void (*set_config_options)		( gftp_request * request );
 
   /* Options */
   gftp_transfer_type transfer_type;	/* Passive or non-passive (FTP only) */
@@ -451,6 +451,14 @@
 
 #define GFTP_CUSTOM_PROXY_NUM        8
 
+typedef struct gftp_getline_buffer_tag
+{
+  char *buffer,
+       *curpos;
+  size_t max_bufsize,
+         cur_bufsize;
+} gftp_getline_buffer;
+
 /* Global config options */
 extern supported_gftp_protocols gftp_protocols[];
 extern char version[], *emailaddr, *edit_program, *view_program, 
@@ -488,9 +496,9 @@
 extern gftp_color send_color, recv_color, error_color, misc_color;
 
 /* cache.c */
-FILE * gftp_new_cache_entry 		( gftp_request * request );
+int gftp_new_cache_entry 		( gftp_request * request );
 
-FILE * gftp_find_cache_entry 		( gftp_request * request );
+int gftp_find_cache_entry 		( gftp_request * request );
 
 void gftp_clear_cache_files 		( void );
 
@@ -589,7 +597,6 @@
 					  int asds );
 
 /* protocols.c */
-#define GFTP_CONNECTED(request)			(request->sockfd != NULL)
 #define GFTP_GET_HOSTNAME(request)		(request->hostname)
 #define GFTP_GET_USERNAME(request)		(request->username)
 #define GFTP_GET_PASSWORD(request)		(request->password)
@@ -624,15 +631,16 @@
 #define GFTP_TYPE_BINARY			1
 #define GFTP_TYPE_ASCII				2   
 #define GFTP_IS_CONNECTED(request)		((request) != NULL && \
-                                                 ((request)->sockfd != NULL || \
-                                                  (request)->cached))
+                                                 ((request)->sockfd > 0 || \
+                                                  (request)->cached || \
+                                                  (request)->always_connected))
 
 
 void rfc959_init 			( gftp_request * request );
 
 int rfc959_get_next_file 		( gftp_request * request, 
 					  gftp_file *fle, 
-					  FILE *fd );
+					  int fd );
 
 void rfc2068_init 			( gftp_request * request );
 
@@ -654,31 +662,31 @@
 
 void gftp_disconnect 			( gftp_request * request );
 
-size_t gftp_get_file 			( gftp_request * request, 
+off_t gftp_get_file 			( gftp_request * request, 
 					  const char *filename, 
-					  FILE * fd,
+					  int fd,
 					  size_t startsize );
 
 int gftp_put_file 			( gftp_request * request, 
 					  const char *filename, 
-					  FILE * fd,
+					  int fd,
 					  size_t startsize,
 					  size_t totalsize );
 
 long gftp_transfer_file 		( gftp_request *fromreq, 
 					  const char *fromfile, 
-					  FILE * fromfd,
+					  int fromfd,
 					  size_t fromsize, 
 					  gftp_request *toreq, 
 					  const char *tofile, 
-					  FILE * tofd,
+					  int tofd,
 					  size_t tosize );
 
-size_t gftp_get_next_file_chunk 	( gftp_request * request, 
+ssize_t gftp_get_next_file_chunk 	( gftp_request * request, 
 					  char *buf, 
 					  size_t size );
 
-size_t gftp_put_next_file_chunk 	( gftp_request * request, 
+ssize_t gftp_put_next_file_chunk 	( gftp_request * request, 
 					  char *buf, 
 					  size_t size );
 
@@ -760,7 +768,7 @@
 void gftp_set_proxy_config 		( gftp_request * request, 
 					  const char *proxy_config );
 
-long gftp_get_file_size 		( gftp_request * request, 
+off_t gftp_get_file_size 		( gftp_request * request, 
 					  const char *filename );
 
 int gftp_need_proxy 			( gftp_request * request,
@@ -809,15 +817,30 @@
 
 void print_file_list 			( GList * list );
 
-char *gftp_fgets 			( gftp_request * request, 
+ssize_t gftp_get_line 			( gftp_request * request, 
+					  gftp_getline_buffer ** rbuf,
 					  char * str, 
 					  size_t len, 
-					  FILE * fd );
+					  int fd );
+
+ssize_t gftp_read 			( gftp_request * request, 
+					  void *ptr, 
+					  size_t size, 
+					  int fd );
 
-size_t gftp_fwrite 			( gftp_request * request, 
-					  const void *ptr, 
+ssize_t gftp_write 			( gftp_request * request, 
+					  const char *ptr, 
 					  size_t size, 
-					  FILE * fd );
+					  int fd );
+
+ssize_t gftp_writefmt 			( gftp_request * request, 
+					  int fd, 
+					  const char *fmt, 
+					  ... );
+
+int gftp_set_sockblocking 		( gftp_request * request, 
+					  int fd, 
+					  int non_blocking );
 
 #endif
 
--- a/lib/local.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/local.c	Thu Nov 21 00:33:51 2002 +0000
@@ -59,9 +59,6 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2);
 
-  /* Just to simulate that we are actually connected */
-  request->sockfd = (void *) 1;
-
   if (request->directory)
     {
       if (chdir (request->directory) != 0)
@@ -95,81 +92,62 @@
   g_return_if_fail (request != NULL);
   g_return_if_fail (request->protonum == GFTP_LOCAL_NUM);
 
-  if (request->datafd != NULL)
+  if (request->datafd != -1)
     {
-      if (fclose (request->datafd) < 0)
+      if (close (request->datafd) < 0)
         request->logging_function (gftp_logging_error, request->user_data,
                                    _("Error closing file descriptor: %s\n"),
                                    g_strerror (errno));
-      request->datafd = NULL;
+      request->datafd = -1;
     }
-  request->sockfd = NULL;
 }
 
 
-static long 
-local_get_file (gftp_request * request, const char *filename, FILE * fd,
+static off_t
+local_get_file (gftp_request * request, const char *filename, int fd,
                 off_t startsize)
 {
-  size_t size;
-  int sock, flags;
+  off_t size;
+  int flags;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2);
   g_return_val_if_fail (filename != NULL, -2);
 
-  if (fd == NULL)
+  if (fd > 0)
     {
       flags = O_RDONLY;
 #if defined (_LARGEFILE_SOURCE)
       flags |= O_LARGEFILE;
 #endif
 
-      if ((sock = open (filename, flags)) < 0)
+      if ((request->datafd = open (filename, flags)) < 0)
         {
           request->logging_function (gftp_logging_error, request->user_data,
                                    _("Error: Cannot open local file %s: %s\n"),
                                    filename, g_strerror (errno));
           return (-2);
         }
-
-      if ((request->datafd = fdopen (sock, "rb")) == NULL)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Cannot fdopen() socket for %s: %s\n"),
-                                     filename, g_strerror (errno));
-          close (sock);
-          return (-2);
-        }
     }
   else
     request->datafd = fd;
 
-  if (lseek (fileno (request->datafd), 0, SEEK_END) == -1)
+  if ((size = lseek (request->datafd, 0, SEEK_END)) == -1)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                                  _("Error: Cannot seek on file %s: %s\n"),
                                  filename, g_strerror (errno));
-      fclose (request->datafd);
-      request->datafd = NULL;
+      gftp_disconnect (request);
+      return (-1);
     }
 
-  if ((size = ftell (request->datafd)) == -1)
+  if (lseek (request->datafd, startsize, SEEK_SET) == -1)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                                  _("Error: Cannot seek on file %s: %s\n"),
                                  filename, g_strerror (errno));
-      fclose (request->datafd);
-      request->datafd = NULL;
-    }
-
-  if (lseek (fileno (request->datafd), startsize, SEEK_SET) == -1)
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Error: Cannot seek on file %s: %s\n"),
-                                 filename, g_strerror (errno));
-      fclose (request->datafd);
-      request->datafd = NULL;
+      gftp_disconnect (request);
+      return (-1);
     }
 
   return (size);
@@ -177,16 +155,16 @@
 
 
 static int
-local_put_file (gftp_request * request, const char *filename, FILE * fd,
+local_put_file (gftp_request * request, const char *filename, int fd,
                 off_t startsize, off_t totalsize)
 {
-  int sock, flags;
+  int flags;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, -2);
   g_return_val_if_fail (filename != NULL, -2);
 
-  if (fd == NULL)
+  if (fd > 0)
     {
       flags = O_WRONLY | O_CREAT;
       if (startsize > 0)
@@ -195,43 +173,32 @@
       flags |= O_LARGEFILE;
 #endif
 
-      if ((sock = open (filename, flags, S_IRUSR | S_IWUSR)) < 0)
+      if ((request->datafd = open (filename, flags, S_IRUSR | S_IWUSR)) < 0)
         {
           request->logging_function (gftp_logging_error, request->user_data,
                                    _("Error: Cannot open local file %s: %s\n"),
                                    filename, g_strerror (errno));
           return (-2);
         }
-
-      if ((request->datafd = fdopen (sock, "ab")) == NULL)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Cannot fdopen() socket for %s: %s\n"),
-                                     filename, g_strerror (errno));
-          close (sock);
-          return (-2);
-        }
     }
   else
     request->datafd = fd;
 
-  if (ftruncate (fileno (request->datafd), startsize) == -1)
+  if (ftruncate (request->datafd, startsize) == -1)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                                _("Error: Cannot truncate local file %s: %s\n"),
                                filename, g_strerror (errno));
-      fclose (request->datafd);
-      request->datafd = NULL;
-      return (-2);
+      gftp_disconnect (request);
+      return (-1);
     }
     
-  if (fseek (request->datafd, startsize, SEEK_SET) == -1)
+  if (lseek (request->datafd, startsize, SEEK_SET) == -1)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                                  _("Error: Cannot seek on file %s: %s\n"),
                                  filename, g_strerror (errno));
-      fclose (request->datafd);
-      request->datafd = NULL;
+      gftp_disconnect (request);
       return (-2);
     }
   return (0);
@@ -250,14 +217,14 @@
       lpd->dir = NULL;
     }
 
-  if (request->datafd != NULL)
+  if (request->datafd > 0)
     {
-      if (fclose (request->datafd) < 0)
+      if (close (request->datafd) < 0)
         request->logging_function (gftp_logging_error, request->user_data,
                                    _("Error closing file descriptor: %s\n"),
                                    g_strerror (errno));
 
-      request->datafd = NULL;
+      request->datafd = -1;
     }
 
   return (0);
@@ -351,7 +318,7 @@
 
 
 static int
-local_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd)
+local_get_next_file (gftp_request * request, gftp_file * fle, int fd)
 {
   local_protocol_data * lpd;
   struct dirent *dirp;
@@ -503,7 +470,7 @@
 
   if (chdir (directory) == 0)
     {
-      request->logging_function (gftp_logging_error, request->user_data,
+      request->logging_function (gftp_logging_misc, request->user_data,
                           _("Successfully changed local directory to %s\n"),
                           directory);
       if (request->directory != directory)
@@ -538,7 +505,7 @@
 
   if (rmdir (directory) == 0)
     {
-      request->logging_function (gftp_logging_error, request->user_data,
+      request->logging_function (gftp_logging_misc, request->user_data,
                                  _("Successfully removed %s\n"), directory);
       return (0);
     }
@@ -561,7 +528,7 @@
 
   if (unlink (file) == 0)
     {
-      request->logging_function (gftp_logging_error, request->user_data,
+      request->logging_function (gftp_logging_misc, request->user_data,
                                  _("Successfully removed %s\n"), file);
       return (0);
     }
@@ -584,7 +551,7 @@
 
   if (mkdir (directory, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0)
     {
-      request->logging_function (gftp_logging_error, request->user_data,
+      request->logging_function (gftp_logging_misc, request->user_data,
                                  _("Successfully made directory %s\n"),
                                  directory);
       return (0);
@@ -610,7 +577,7 @@
 
   if (rename (oldname, newname) == 0)
     {
-      request->logging_function (gftp_logging_error, request->user_data,
+      request->logging_function (gftp_logging_misc, request->user_data,
                                  _("Successfully renamed %s to %s\n"),
                                  oldname, newname);
       return (0);
@@ -640,7 +607,7 @@
 
   if (chmod (file, newmode) == 0) 
     {
-      request->logging_function (gftp_logging_error, request->user_data, 
+      request->logging_function (gftp_logging_misc, request->user_data, 
                                  _("Successfully changed mode of %s to %d\n"),
                                  file, mode);
       return (0);
@@ -716,6 +683,7 @@
   request->set_file_time = local_set_file_time;
   request->site = NULL;
   request->parse_url = NULL;
+  request->set_config_options = NULL;
   request->url_prefix = "file";
   request->protocol_name = "Local";
   request->need_hostport = 0;
--- a/lib/misc.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/misc.c	Thu Nov 21 00:33:51 2002 +0000
@@ -259,24 +259,43 @@
 int
 copyfile (char *source, char *dest)
 {
-  FILE *srcfd, *destfd;
+  int srcfd, destfd;
   char buf[8192];
-  size_t n;
+  ssize_t n;
 
-  if ((srcfd = fopen (source, "rb")) == NULL)
-    return (0);
+  if ((srcfd = open (source, O_RDONLY)) == -1)
+    {
+      printf (_("Error: Cannot open local file %s: %s\n"),
+              source, g_strerror (errno));
+      exit (1);
+    }
 
-  if ((destfd = fopen (dest, "wb")) == NULL)
+  if ((destfd = open (dest, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1)
     {
-      fclose (srcfd);
-      return (0);
+      printf (_("Error: Cannot open local file %s: %s\n"),
+              dest, g_strerror (errno));
+      close (srcfd);
+      exit (1);
     }
 
-  while ((n = fread (buf, 1, sizeof (buf), srcfd)) > 0)
-    fwrite (buf, 1, n, destfd);
+  while ((n = read (srcfd, buf, sizeof (buf))) > 0)
+    {
+      if (write (destfd, buf, n) == -1)
+        {
+          printf (_("Error: Could not write to socket: %s\n"), 
+                  g_strerror (errno));
+          exit (1);
+        }
+    }
 
-  fclose (srcfd);
-  fclose (destfd);
+  if (n == -1)
+    {
+      printf (_("Error: Could not read from socket: %s\n"), g_strerror (errno));
+      exit (1);
+    }
+
+  close (srcfd);
+  close (destfd);
 
   return (1);
 }
@@ -429,8 +448,8 @@
     g_free (fle->attribs);
   if (fle->destfile)
     g_free (fle->destfile);
-  if (fle->fd)
-    fclose (fle->fd);
+  if (fle->fd > 0)
+    close (fle->fd);
   g_free (fle);
 }
 
@@ -481,13 +500,11 @@
 {
   dest->sockfd = source->sockfd;
   dest->datafd = source->datafd;
-  dest->sockfd_write = source->sockfd_write;
   dest->cached = 0;
   if (!source->always_connected)
     {
-      source->sockfd = NULL;
-      source->datafd = NULL;
-      source->sockfd_write = NULL;
+      source->sockfd = -1;
+      source->datafd = -1;
       source->cached = 1;
     }
 }
@@ -584,12 +601,10 @@
   newreq->proxy_account = NULL;
   newreq->last_ftp_response = NULL;
   newreq->last_dir_entry = NULL;
-  newreq->sockfd = NULL;
-  newreq->sockfd_write = NULL;
-  newreq->datafd = NULL;
-  newreq->cachefd = NULL;
+  newreq->sockfd = -1;
+  newreq->datafd = -1;
+  newreq->cachefd = -1;
   newreq->hostp = NULL;
-  newreq->protocol_data = NULL;
   
   if (req->proxy_config != NULL)
     newreq->proxy_config = g_strdup (req->proxy_config);
@@ -848,10 +863,8 @@
 ssh_start_login_sequence (gftp_request * request, int fd)
 {
   size_t rem, len, diff, lastdiff;
-  int flags, wrotepw, ok;
-  struct timeval tv;
-  char *tempstr;
-  fd_set rdfds;
+  int wrotepw, ok;
+  char *tempstr, *pwstr;
   ssize_t rd;
 
   rem = len = 100;
@@ -860,42 +873,16 @@
   wrotepw = 0;
   ok = 1;
 
-  if ((flags = fcntl (fd, F_GETFL, 0)) < 0) 
-    {
-      g_free (tempstr);
-      return (NULL);
-    }
+  if (gftp_set_sockblocking (request, request->datafd, 1) == -1)
+    return (NULL);
 
-  if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
-    {
-      g_free (tempstr);
-      return (NULL);
-    }
+  pwstr = g_strconcat (request->password, "\n", NULL);
 
   errno = 0;
   while (1)
     {
-      FD_ZERO (&rdfds);
-      FD_SET (fd, &rdfds);
-      tv.tv_sec = 5;
-      tv.tv_usec = 0;
-      if (select (fd + 1, &rdfds, NULL, NULL, &tv) < 0)
+      if ((rd = gftp_read (request, tempstr + diff, rem -1, fd)) <= 0)
         {
-          if (errno == EINTR && !request->cancel)
-            continue;
-          ok = 0;
-          break;
-        }
-
-      if ((rd = read (fd, tempstr + diff, rem - 1)) < 0)
-        {
-          if (errno == EINTR && !request->cancel)
-            continue;
-          ok = 0;
-          break;
-        }
-      else if (rd == 0)
-        { 
           ok = 0;
           break;
         }
@@ -918,8 +905,11 @@
                                            "password: ") == 0)
         {
           wrotepw = 1;
-          write (fd, request->password, strlen (request->password));
-          write (fd, "\n", 1);
+          if (gftp_write (request, pwstr, strlen (pwstr), fd) < 0)
+            {
+              ok = 0;
+              break;
+            }
         }
 
       else if (!wrotepw && 
@@ -927,21 +917,22 @@
                strstr (tempstr, "Enter passphrase for key '") != NULL))
         {
           wrotepw = 1;
-          write (fd, request->password, strlen (request->password));
-          write (fd, "\n", 1);
+          if (gftp_write (request, pwstr, strlen (pwstr), fd) < 0)
+            {
+              ok = 0;
+              break;
+            }
         }
       else if (strlen (tempstr) >= 5 && 
                strcmp (tempstr + strlen (tempstr) - 5, "xsftp") == 0)
         break;
     }
 
+  g_free (pwstr);
   tempstr[diff] = '\0';
   request->logging_function (gftp_logging_recv, request->user_data,
                              "%s\n", tempstr + lastdiff);
 
-  if (ok && fcntl (fd, F_SETFL, flags) < 0)
-    ok = 0;
-
   if (!ok)
     {
       g_free (tempstr);
--- a/lib/protocols.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/protocols.c	Thu Nov 21 00:33:51 2002 +0000
@@ -26,8 +26,7 @@
   gftp_request *request;
 
   request = g_malloc0 (sizeof (*request));
-  request->sockfd = NULL;
-  request->datafd = NULL;
+  request->sockfd = -1;
   request->data_type = GFTP_TYPE_BINARY;
   return (request);
 }
@@ -107,20 +106,6 @@
   if (request->connect == NULL)
     return (-2);
 
-  if (request->sftpserv_path == NULL)
-    {
-      /* FIXME - move this to per protocol files */
-      switch (request->protonum)
-        {
-          case GFTP_SSH_NUM:
-            request->sftpserv_path = g_strdup (ssh1_sftp_path);
-            break;
-          case GFTP_SSHV2_NUM:
-            request->sftpserv_path = g_strdup (ssh2_sftp_path);
-            break;
-        }
-    }
-
   gftp_set_config_options (request);
 
   return (request->connect (request));
@@ -151,8 +136,8 @@
 }
 
 
-size_t
-gftp_get_file (gftp_request * request, const char *filename, FILE * fd,
+off_t
+gftp_get_file (gftp_request * request, const char *filename, int fd,
                size_t startsize)
 {
   g_return_val_if_fail (request != NULL, -2);
@@ -165,7 +150,7 @@
 
 
 int
-gftp_put_file (gftp_request * request, const char *filename, FILE * fd,
+gftp_put_file (gftp_request * request, const char *filename, int fd,
                size_t startsize, size_t totalsize)
 {
   g_return_val_if_fail (request != NULL, -2);
@@ -179,9 +164,9 @@
 
 long
 gftp_transfer_file (gftp_request * fromreq, const char *fromfile, 
-                    FILE * fromfd, size_t fromsize, 
+                    int fromfd, size_t fromsize, 
                     gftp_request * toreq, const char *tofile,
-                    FILE * tofd, size_t tosize)
+                    int tofd, size_t tosize)
 {
   long size;
 
@@ -215,150 +200,32 @@
 }
 
 
-size_t 
+ssize_t 
 gftp_get_next_file_chunk (gftp_request * request, char *buf, size_t size)
 {
-  struct timeval tv;
-  fd_set fset;
-  size_t len;
-  int ret;
-  
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (buf != NULL, -2);
 
   if (request->get_next_file_chunk != NULL)
     return (request->get_next_file_chunk (request, buf, size));
 
-  errno = 0;
-  len = 0;
-  do 
-    {
-      FD_ZERO (&fset);
-      FD_SET (fileno (request->datafd), &fset);
-      tv.tv_sec = request->network_timeout;
-      tv.tv_usec = 0;
-      ret = select (fileno (request->datafd) + 1, &fset, NULL, NULL, &tv);
-      if (ret == -1 && errno == EINTR)
-        {
-          if (request->cancel)
-            break;
-          else
-            continue;
-        }
-      else if (ret <= 0)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Connection to %s timed out\n"),
-                                     request->hostname);
-          gftp_disconnect (request);
-          return (-1);
-        }
-
-      if ((len = read (fileno (request->datafd), buf, size)) == -1)
-        {
-          if (errno == EINTR)
-            {
-              if (request->cancel)
-                break;
-              else
-                continue;
-            }
-
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Error reading from host %s: %s\n"),
-                                     request->hostname,
-                                     g_strerror (errno));
-          gftp_disconnect (request);
-          return (-1);
-        }
-    }
-  while (errno == EINTR && !request->cancel);
-
-  if (errno == EINTR && request->cancel)
-    {
-      gftp_disconnect (request);
-      return (-1);
-    }
-
-  return (len);
+  return (gftp_read (request, buf, size, request->datafd));
 }
 
 
-size_t 
+ssize_t 
 gftp_put_next_file_chunk (gftp_request * request, char *buf, size_t size)
 {
-  struct timeval tv;
-  size_t len, ret;
-  fd_set fset;
-  char *pos;
-  int sret;
-  
   g_return_val_if_fail (request != NULL, -2);
+  g_return_val_if_fail (buf != NULL, -2);
 
-  ret = size;
   if (request->put_next_file_chunk != NULL)
     return (request->put_next_file_chunk (request, buf, size));
 
   if (size == 0)
     return (0);
 
-  pos = buf;
-  while (size > 0)
-    {
-      errno = 0;
-      do 
-        {
-          FD_ZERO (&fset);
-          FD_SET (fileno (request->datafd), &fset);
-          tv.tv_sec = request->network_timeout;
-          tv.tv_usec = 0;
-          sret = select (fileno (request->datafd) + 1, NULL, &fset, NULL, &tv);
-          if (sret == -1 && errno == EINTR)
-            {
-              if (request->cancel)
-                break;
-              else
-                continue;
-            }
-          else if (sret <= 0)
-            {
-              request->logging_function (gftp_logging_error, request->user_data,
-                                         _("Connection to %s timed out\n"),
-                                         request->hostname);
-              gftp_disconnect (request);
-              return (-1);
-            }
-
-          if ((len = write (fileno (request->datafd), pos, size)) < 0)
-            {
-              if (sret == -1 && errno == EINTR)
-                {
-                  if (request->cancel)
-                    break;
-                  else
-                    continue;
-                }
-
-              request->logging_function (gftp_logging_error, request->user_data,
-                                         _("Error writing to host %s: %s\n"),
-                                         request->hostname,
-                                         g_strerror (errno));
-              gftp_disconnect (request);
-              return (-1);
-            }
-          size -= len;
-          pos += len;
-        }
-      while (errno == EINTR && !request->cancel);
-    }
-
-  if (errno == EINTR && request->cancel)
-    {
-      gftp_disconnect (request);
-      return (-1);
-    }
-
-  return (ret); 
+  return (gftp_write (request, buf, size, request->datafd));
 }
 
 
@@ -375,10 +242,10 @@
   else
     ret = 0;
 
-  if (request->cachefd != NULL)
+  if (request->cachefd > 0)
     {
-      fclose (request->cachefd);
-      request->cachefd = NULL;
+      close (request->cachefd);
+      request->cachefd = -1;
     }
 
   if (request->last_dir_entry)
@@ -407,12 +274,12 @@
 int
 gftp_list_files (gftp_request * request)
 {
-  FILE * fd;
+  int fd;
 
   g_return_val_if_fail (request != NULL, -2);
 
   request->cached = 0;
-  if (request->use_cache && (fd = gftp_find_cache_entry (request)) != NULL)
+  if (request->use_cache && (fd = gftp_find_cache_entry (request)) > 0)
     {
       request->logging_function (gftp_logging_misc, request->user_data,
                                  _("Loading directory listing %s from cache\n"),
@@ -437,8 +304,7 @@
 int
 gftp_get_next_file (gftp_request * request, char *filespec, gftp_file * fle)
 {
-  FILE * fd;
-  int ret;
+  int fd, ret;
 #if GLIB_MAJOR_VERSION > 1
   gsize bread, bwrite;
   char *tempstr;
@@ -450,7 +316,7 @@
   if (request->get_next_file == NULL)
     return (-2);
 
-  if (request->cached && request->cachefd != NULL)
+  if (request->cached && request->cachefd > 0)
     fd = request->cachefd;
   else
     fd = request->datafd;
@@ -477,18 +343,15 @@
         }
 #endif
 
-      if (ret >= 0 && !request->cached && request->cachefd != NULL && 
+      if (ret >= 0 && !request->cached && request->cachefd > 0&& 
           request->last_dir_entry != NULL)
         {
-          fwrite (request->last_dir_entry, 1, request->last_dir_entry_len, 
-                  request->cachefd);
-          if (ferror (request->cachefd))
+          if (gftp_writefmt (request, request->cachefd, "%s\n",
+                             request->last_dir_entry) < 0)
             {
               request->logging_function (gftp_logging_error, request->user_data,
                                         _("Error: Cannot write to cache: %s\n"),
                                         g_strerror (errno));
-              fclose (request->cachefd);
-              request->cachefd = NULL;
             }
         }
     } while (ret > 0 && !gftp_match_filespec (fle->file, filespec));
@@ -678,7 +541,7 @@
   g_return_val_if_fail (directory != NULL, -2);
 
 
-  if (request->sockfd == NULL)
+  if (request->sockfd <= 0 && !request->always_connected)
     {
       if (directory != request->directory)
 	{
@@ -871,7 +734,7 @@
 }
 
 
-long
+off_t
 gftp_get_file_size (gftp_request * request, const char *filename)
 {
   g_return_val_if_fail (request != NULL, 0);
@@ -1917,6 +1780,13 @@
 
   request->logging_function (gftp_logging_misc, request->user_data,
 			     _("Connected to %s:%d\n"), connect_host, port);
+
+  if (gftp_set_sockblocking (request, sock, 1) == -1)
+    {
+      close (sock);
+      return (-1);
+    }
+
   return (sock);
 }
 
@@ -1924,57 +1794,13 @@
 void
 gftp_set_config_options (gftp_request * request)
 {
-  /* FIXME - move this to per protocol files */
-  request->transfer_type = passive_transfer ? gftp_transfer_passive : gftp_transfer_active;
   request->network_timeout = network_timeout;
   request->retries = retries;
   request->sleep_time = sleep_time;
   request->maxkbs = maxkbs;
 
-  if (request->protonum == GFTP_SSHV2_NUM || 
-      request->protonum == GFTP_SSH_NUM)
-    request->need_userpass = ssh_need_userpass;
-
-  /* Set up the proxy server settings. If we are using a HTTP proxy for FTP,
-     then set up the HTTP proxy settings */
-  if ((strcmp (request->protocol_name, "FTP") == 0 ||
-       strcmp (request->protocol_name, "HTTP") == 0) &&
-      proxy_config != NULL)
-    {
-      if (strcmp (request->protocol_name, "FTP") == 0 &&
-          strcmp (proxy_config, "http") != 0)
-        {
-          gftp_set_proxy_hostname (request, firewall_host);
-          gftp_set_proxy_port (request, firewall_port);
-          gftp_set_proxy_username (request, firewall_username);
-          gftp_set_proxy_password (request, firewall_password);
-          gftp_set_proxy_account (request, firewall_account);
-          gftp_set_proxy_config (request, proxy_config);
-        }
-      else 
-        {
-          gftp_set_proxy_hostname (request, http_proxy_host);
-          gftp_set_proxy_port (request, http_proxy_port);
-          gftp_set_proxy_username (request, http_proxy_username);
-          gftp_set_proxy_password (request, http_proxy_password);
-
-          
-          if (request->proxy_config == NULL)
-            {
-              if (strcmp (GFTP_GET_PROTOCOL_NAME (request), "FTP") == 0)
-                {
-                  gftp_protocols[GFTP_HTTP_NUM].init (request);
-                  request->proxy_config = g_malloc (4);
-                  strcpy (request->proxy_config, "ftp");
-                }
-              else
-                {
-                  request->proxy_config = g_malloc (5);
-                  strcpy (request->proxy_config, "http");
-                }
-            }
-        }
-    }
+  if (request->set_config_options != NULL)
+    request->set_config_options (request);
 }
 
 
@@ -2037,99 +1863,169 @@
 }
 
 
-char *
-gftp_fgets (gftp_request * request, char * str, size_t len, FILE * fd)
+static void
+gftp_free_getline_buffer (gftp_getline_buffer ** rbuf)
 {
-  char * ret = NULL;
-
-  errno = 0;
-  do 
-    {
-      ret = fgets (str, len, fd);
-      if (ferror (fd))
-        {
-          if (errno == EINTR)
-            {
-              clearerr (fd);
-              if (request->cancel)
-                break;
-              else
-                continue;
-            }
-
-          request->logging_function (gftp_logging_error, request->user_data,
-                                   _("Error: Could not read from socket: %s\n"),
-                                   g_strerror (errno));
-          gftp_disconnect (request);
-          return (NULL);
-        }
-    }
-  while (errno == EINTR && !request->cancel);
-
-  if (errno == EINTR && request->cancel)
-    {
-      gftp_disconnect (request);
-      return (NULL);
-    }
-
-  return (ret);
+  g_free ((*rbuf)->buffer);
+  g_free (*rbuf);
+  *rbuf = NULL;
 }
 
 
-size_t 
-gftp_fwrite (gftp_request * request, const void *ptr, size_t size, FILE * fd)
+ssize_t
+gftp_get_line (gftp_request * request, gftp_getline_buffer ** rbuf, 
+               char * str, size_t len, int fd)
 {
-  size_t ret;
+  ssize_t ret, retval, rlen, copysize;
+  char *pos, *nextpos;
+
+  if (*rbuf == NULL)
+    {
+      *rbuf = g_malloc0 (sizeof (**rbuf));
+      (*rbuf)->max_bufsize = len;
+      (*rbuf)->buffer = g_malloc ((*rbuf)->max_bufsize);
+      if ((ret = gftp_read (request, (*rbuf)->buffer, (*rbuf)->max_bufsize, 
+                            fd)) <= 0)
+        {
+          gftp_free_getline_buffer (rbuf);
+          return (ret);
+        }
+      (*rbuf)->cur_bufsize = ret;
+      (*rbuf)->curpos = (*rbuf)->buffer;
+    }
+
+  retval = -2;
+
+  do
+    {
+      if ((*rbuf)->cur_bufsize > 0 &&
+          ((pos = strchr ((*rbuf)->curpos, '\n')) != NULL ||
+           ((*rbuf)->curpos == (*rbuf)->buffer && 
+            (*rbuf)->max_bufsize == (*rbuf)->cur_bufsize)))
+        {
+          if (pos != NULL)
+            {
+              nextpos = pos + 1;
+              if (pos > (*rbuf)->curpos && *(pos - 1) == '\r')
+                pos--;
+              *pos = '\0';
+
+              if (len > pos - (*rbuf)->curpos + 1)
+                len = pos - (*rbuf)->curpos + 1;
+            }
+          else
+            {
+              nextpos = NULL;
+              if (len > (*rbuf)->cur_bufsize)
+                len = (*rbuf)->cur_bufsize;
+            }
+
+          strncpy (str, (*rbuf)->curpos, len);
+          str[len] = '\0';
+          retval = len;
+
+          if (pos != NULL)
+            {
+              if (nextpos - (*rbuf)->buffer >= (*rbuf)->cur_bufsize)
+                (*rbuf)->cur_bufsize = 0;
+              else
+                (*rbuf)->curpos = nextpos;
+            }
+
+          break;
+        }
+      else
+        {
+          if ((*rbuf)->cur_bufsize == 0 || *(*rbuf)->curpos == '\0')
+            {
+              rlen = (*rbuf)->max_bufsize;
+              pos = (*rbuf)->buffer;
+              copysize = 0;
+            }
+          else
+            {
+              copysize = (*rbuf)->cur_bufsize - ((*rbuf)->curpos - (*rbuf)->buffer);
+              memmove ((*rbuf)->buffer, (*rbuf)->curpos, copysize);
+              pos = (*rbuf)->buffer + copysize;
+              rlen = (*rbuf)->max_bufsize - copysize;
+            }
+          (*rbuf)->curpos = (*rbuf)->buffer;
+
+          if ((ret = gftp_read (request, pos, rlen, fd)) <= 0)
+            {
+              gftp_free_getline_buffer (rbuf);
+              return (ret);
+            }
+          (*rbuf)->cur_bufsize = ret + copysize;
+        }
+    }
+  while (retval == -2);
+
+  return (retval);
+}
+
+
+ssize_t 
+gftp_read (gftp_request * request, void *ptr, size_t size, int fd)
+{
+  struct timeval tv;
+  fd_set fset;
+  ssize_t ret;
 
   errno = 0;
   ret = 0;
   do
     {
-      ret = fwrite (ptr, size, 1, fd);
-      if (ferror (fd))
+      FD_ZERO (&fset);
+      FD_SET (fd, &fset);
+      if (request != NULL)
+        tv.tv_sec = request->network_timeout;
+      else
+        tv.tv_sec = network_timeout;
+      tv.tv_usec = 0;
+      ret = select (fd + 1, &fset, NULL, NULL, &tv);
+      if (ret == -1 && errno == EINTR)
         {
-          if (errno == EINTR)
+          if (request && request->cancel)
+            break;
+          else
+            continue;
+        }
+      else if (ret <= 0)
+        {
+          if (request != NULL)
             {
-              if (request->cancel)
-                break;
-              else
-                {
-                  clearerr (fd);
-                  continue;
-                }
-             }
- 
-          request->logging_function (gftp_logging_error, request->user_data,
-                                    _("Error: Could not write to socket: %s\n"),
-                                    g_strerror (errno));
-          gftp_disconnect (request);
+              request->logging_function (gftp_logging_error, request->user_data,
+                                         _("Connection to %s timed out\n"),
+                                         request->hostname);
+              gftp_disconnect (request);
+            }
           return (-1);
         }
 
-      fflush (request->sockfd_write);
-      if (ferror (fd))
+      if ((ret = read (fd, ptr, size)) < 0)
         {
           if (errno == EINTR)
             {
-              if (request->cancel)
+              if (request != NULL && request->cancel)
                 break;
               else
-                {
-                  clearerr (fd);
-                  continue;
-                }
+                continue;
              }
  
-          request->logging_function (gftp_logging_error, request->user_data,
-                                    _("Error: Could not write to socket: %s\n"),
+          if (request != NULL)
+            {
+              request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error: Could not read from socket: %s\n"),
                                     g_strerror (errno));
-          gftp_disconnect (request);
+              gftp_disconnect (request);
+            }
           return (-1);
         }
     }
-  while (errno == EINTR && !request->cancel);
+  while (errno == EINTR && !(request != NULL && request->cancel));
 
-  if (errno == EINTR && request->cancel)
+  if (errno == EINTR && request != NULL && request->cancel)
     {
       gftp_disconnect (request);
       return (-1);
@@ -2138,3 +2034,127 @@
   return (ret);
 }
 
+
+ssize_t 
+gftp_write (gftp_request * request, const char *ptr, size_t size, int fd)
+{
+  struct timeval tv;
+  size_t ret, w_ret;
+  fd_set fset;
+
+  errno = 0;
+  ret = 0;
+  do
+    {
+      FD_ZERO (&fset);
+      FD_SET (fd, &fset);
+      if (request != NULL)
+        tv.tv_sec = request->network_timeout;
+      else
+        tv.tv_sec = network_timeout;
+      tv.tv_usec = 0;
+      ret = select (fd + 1, NULL, &fset, NULL, &tv);
+      if (ret == -1 && errno == EINTR)
+        {
+          if (request != NULL && request->cancel)
+            break;
+          else
+            continue;
+        }
+      else if (ret <= 0)
+        {
+          if (request != NULL)
+            {
+              request->logging_function (gftp_logging_error, request->user_data,
+                                         _("Connection to %s timed out\n"),
+                                         request->hostname);
+              gftp_disconnect (request);
+            }
+          return (-1);
+        }
+
+      if ((w_ret = write (fd, ptr, size)) < 0)
+        {
+          if (errno == EINTR)
+            {
+              if (request != NULL && request->cancel)
+                break;
+              else
+                continue;
+             }
+ 
+          if (request != NULL)
+            {
+              request->logging_function (gftp_logging_error, request->user_data,
+                                    _("Error: Could not write to socket: %s\n"),
+                                    g_strerror (errno));
+              gftp_disconnect (request);
+            }
+          return (-1);
+        }
+
+      ptr += w_ret;
+      size -= w_ret;
+      ret += w_ret;
+    }
+  while (size > 0);
+
+  if (errno == EINTR && request != NULL && request->cancel)
+    {
+      gftp_disconnect (request);
+      return (-1);
+    }
+
+  return (ret);
+}
+
+
+ssize_t 
+gftp_writefmt (gftp_request * request, int fd, const char *fmt, ...)
+{
+  char *tempstr;
+  va_list argp;
+  ssize_t ret;
+
+  va_start (argp, fmt);
+  tempstr = g_strdup_vprintf (fmt, argp);
+  va_end (argp);
+
+  ret = gftp_write (request, tempstr, strlen (tempstr), fd);
+  g_free (tempstr);
+  return (ret);
+}
+
+
+int
+gftp_set_sockblocking (gftp_request * request, int fd, int non_blocking)
+{
+  int flags;
+
+  if ((flags = fcntl (fd, F_GETFL, 0)) == -1)
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+                                 _("Cannot get socket flags: %s\n"),
+                                 g_strerror (errno));
+      gftp_disconnect (request);
+      return (-1);
+    }
+
+  if (non_blocking)
+    flags |= O_NONBLOCK;
+  else
+    flags &= ~O_NONBLOCK;
+
+  if (fcntl (fd, F_SETFL, flags) == -1)
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+                                 _("Cannot set socket to non-blocking: %s\n"),
+                                 g_strerror (errno));
+      gftp_disconnect (request);
+      return (-1);
+    }
+
+  return (0);
+}
+
+
--- a/lib/rfc2068.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/rfc2068.c	Thu Nov 21 00:33:51 2002 +0000
@@ -76,20 +76,20 @@
 }
 
 
-static unsigned long
+static off_t 
 rfc2068_read_response (gftp_request * request)
 {
+  gftp_getline_buffer * rbuf;
   rfc2068_params * params;
   char tempstr[255];
 
   params = request->protocol_data;
   params->max_bytes = 0;
 
-  if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd))
-    {
-      gftp_disconnect (request);
-      return (0);
-    }
+  rbuf = NULL;
+  if (gftp_get_line (request, &rbuf, tempstr, sizeof (tempstr) - 1, 
+                     request->sockfd) < 0)
+    return (-1);
 
   if (request->last_ftp_response)
     g_free (request->last_ftp_response);
@@ -103,11 +103,9 @@
   while (1) 
     {
       /* Read rest of proxy header */
-      if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd))
-        {
-          gftp_disconnect (request);
-	  return (0);
-        }
+      if (gftp_get_line (request, &rbuf, tempstr, sizeof (tempstr) - 1, 
+                         request->sockfd) < 0)
+	return (-1);
 
       if (*tempstr == '\r' || *tempstr == '\n')
         break;
@@ -125,29 +123,28 @@
 }
 
 
-static unsigned long
+static off_t 
 rfc2068_send_command (gftp_request * request, const char *command,
                       const char *extrahdr)
 {
   char *tempstr, *str;
+  ssize_t ret;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2);
   g_return_val_if_fail (command != NULL, -2);
-  g_return_val_if_fail (request->sockfd_write != NULL, -2);
 
-  request->logging_function (gftp_logging_send, request->user_data, "%s",
-                             command);
+  tempstr = g_strdup_printf ("%sUser-Agent: %s\nHost: %s\n", command,
+                             version, request->hostname);
 
   request->logging_function (gftp_logging_send, request->user_data,
-                             "User-Agent: %s\n", version);
-  fprintf (request->sockfd_write, "%sUser-Agent: %s\nHost: %s\n", command, 
-           version, request->hostname);
-  if (ferror (request->sockfd_write) != 0)
-    {
-      gftp_disconnect (request);
-      return (-2);
-    }
+                             "%s", tempstr);
+
+  ret = gftp_write (request, tempstr, strlen (tempstr), request->sockfd);
+  g_free (tempstr);
+
+  if (ret < 0)
+    return (-1);
 
   if (request->use_proxy && request->proxy_username != NULL &&
       *request->proxy_username != '\0')
@@ -159,13 +156,11 @@
 
       request->logging_function (gftp_logging_send, request->user_data,
                                  "Proxy-authorization: Basic xxxx:xxxx\n");
-      fprintf (request->sockfd_write, "Proxy-authorization: Basic %s\n", str);
+      ret = gftp_writefmt (request, request->sockfd, 
+                           "Proxy-authorization: Basic %s\n", str);
       g_free (str);
-      if (ferror (request->sockfd_write) != 0)
-        {
-          gftp_disconnect (request);
-	  return (-2);
-        }
+      if (ret < 0)
+	return (-2);
     }
 
   if (request->username != NULL && *request->username != '\0')
@@ -176,35 +171,24 @@
 
       request->logging_function (gftp_logging_send, request->user_data,
                                  "Authorization: Basic xxxx\n");
-      fprintf (request->sockfd_write, "Authorization: Basic %s\n", str);
+      ret = gftp_writefmt (request, request->sockfd, 
+                           "Authorization: Basic %s\n", str);
       g_free (str);
-      if (ferror (request->sockfd_write) != 0)
-        {
-          gftp_disconnect (request);
-	  return (-2);
-        }
+      if (ret < 0)
+	return (-2);
     }
 
   if (extrahdr)
     {
-      request->logging_function (gftp_logging_send, request->user_data,
-                                 "%s", extrahdr);
       request->logging_function (gftp_logging_send, request->user_data, "%s",
                                  extrahdr);
-      fprintf (request->sockfd_write, "%s", extrahdr);
-      if (ferror (request->sockfd_write) != 0)
-        {
-          gftp_disconnect (request);
-          return (-2);
-        }
+      if (gftp_write (request, extrahdr, strlen (extrahdr), request->sockfd) < 0)
+        return (-1);
     }
 
-  fprintf (request->sockfd_write, "\n");
-  if (ferror (request->sockfd_write) != 0)
-    {
-      gftp_disconnect (request);
-      return (-2);
-    }
+  if (gftp_write (request, "\n", 1, request->sockfd) < 0)
+    return (-1);
+
   return (rfc2068_read_response (request));
 }
 
@@ -213,18 +197,17 @@
 rfc2068_connect (gftp_request * request)
 {
   char *service;
-  int sock;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2);
   g_return_val_if_fail (request->hostname != NULL, -2);
 
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     return (0);
 
   service = request->use_proxy && request->proxy_config != NULL && 
             *request->proxy_config != '\0' ? request->proxy_config : "http";
-  if ((sock = gftp_connect_server (request, service)) < 0)
+  if ((request->sockfd = gftp_connect_server (request, service)) < 0)
     return (-1);
 
   if (request->directory && *request->directory == '\0')
@@ -239,24 +222,6 @@
       strcpy (request->directory, "/");
     }
 
-  if ((request->sockfd = fdopen (sock, "rb+")) == NULL)
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Cannot fdopen() socket: %s\n"),
-                                 g_strerror (errno));
-      close (sock);
-      return (-2);
-    }
-
-  if ((request->sockfd_write = fdopen (sock, "wb+")) == NULL)
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Cannot fdopen() socket: %s\n"),
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (-2);
-    }
-
   return (0);
 }
 
@@ -267,25 +232,24 @@
   g_return_if_fail (request != NULL);
   g_return_if_fail (request->protonum == GFTP_HTTP_NUM);
 
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     {
       request->logging_function (gftp_logging_misc, request->user_data,
 				 _("Disconnecting from site %s\n"),
 				 request->hostname);
-      fclose (request->sockfd);
-      request->sockfd = NULL;
-    }
 
-  if (request->sockfd_write != NULL)
-    {
-      fclose (request->sockfd_write);
-      request->sockfd_write = NULL;
+      if (close (request->sockfd) < 0)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error closing file descriptor: %s\n"),
+                                   g_strerror (errno));
+
+      request->sockfd = -1;
     }
 }
 
 
-static long 
-rfc2068_get_file (gftp_request * request, const char *filename, FILE * fd,
+static off_t
+rfc2068_get_file (gftp_request * request, const char *filename, int fd,
                   off_t startsize)
 {
   char *tempstr, *extrahdr, *pos, *proto;
@@ -296,10 +260,10 @@
   g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2);
   g_return_val_if_fail (filename != NULL, -2);
 
-  if (fd != NULL)
+  if (fd > 0)
     request->sockfd = fd;
 
-  if (request->sockfd == NULL && rfc2068_connect (request) != 0)
+  if (request->sockfd < 0 && rfc2068_connect (request) != 0)
     return (-2);
 
   if (request->proxy_config != NULL && *request->proxy_config != '\0')
@@ -342,8 +306,8 @@
   g_free (tempstr);
   if (extrahdr)
     g_free (extrahdr);
-  if (request->sockfd == NULL)
-    return (-2);
+  if (size < 0)
+    return (-1);
 
   restarted = 0;
   if (strlen (request->last_ftp_response) > 9 
@@ -352,7 +316,7 @@
   else if (strlen (request->last_ftp_response) < 9 ||
            strncmp (request->last_ftp_response + 9, "200", 3) != 0)
     {
-      request->logging_function (gftp_logging_misc, request->user_data,
+      request->logging_function (gftp_logging_error, request->user_data,
 			         _("Cannot retrieve file %s\n"), filename);
       return (-2);
     }
@@ -361,7 +325,7 @@
 }
 
 
-static size_t
+static ssize_t
 rfc2068_get_next_file_chunk (gftp_request * request, char *buf, size_t size)
 {
   rfc2068_params * params;
@@ -371,36 +335,16 @@
   g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2);
 
   params = request->protocol_data;
-  if (params->max_bytes == params->read_bytes || feof (request->sockfd))
+  if (params->max_bytes == params->read_bytes)
     return (0);
 
-  errno = 0;
-  do
-    {
-      if (params->max_bytes > 0 && 
-          size + params->read_bytes > params->max_bytes)
-        size = params->max_bytes - params->read_bytes;
+  if (params->max_bytes > 0 && 
+      size + params->read_bytes > params->max_bytes)
+    size = params->max_bytes - params->read_bytes;
 
-      len = fread (buf, 1, size, request->sockfd);
-      if (ferror (request->sockfd))
-        {
-          if (errno == EINTR && !request->cancel)
-            {
-              clearerr (request->sockfd);
-              continue;
-            }
+  if ((len = gftp_read (request, buf, size, request->sockfd)) < 0)
+    return (-2);
 
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Error reading from host %s: %s\n"),
-                                     request->hostname,
-                                     g_strerror (errno));
-          gftp_disconnect (request);
-          return (-1);
-        }
-    }
-  while (errno == EINTR && !request->cancel);
-
-  params->read_bytes += len;
   return (len);
 }
 
@@ -412,15 +356,15 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
 
-  if (request->sockfd == NULL)
+  if (request->sockfd < 0)
     return (-2);
 
-  fclose (request->sockfd);
-  request->sockfd = NULL;
-  fclose (request->sockfd_write);
-  request->sockfd_write = NULL;
+  if (close (request->sockfd) < 0)
+    request->logging_function (gftp_logging_error, request->user_data,
+                               _("Error closing file descriptor: %s\n"),
+                               g_strerror (errno));
+  request->sockfd = -1;
 
   params = request->protocol_data;
   params->max_bytes = 0;
@@ -436,12 +380,13 @@
 {
   char *tempstr, *pos, *proto;
   rfc2068_params *params;
+  off_t ret;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2);
 
   params = request->protocol_data;
-  if (request->sockfd == NULL && rfc2068_connect (request) != 0)
+  if (request->sockfd < 0 && rfc2068_connect (request) != 0)
     return (-2);
 
   if (request->proxy_config != NULL && *request->proxy_config != '\0')
@@ -463,10 +408,10 @@
   else
     remove_double_slashes (tempstr);
 
-  rfc2068_send_command (request, tempstr, NULL);
+  ret = rfc2068_send_command (request, tempstr, NULL);
   g_free (tempstr);
-  if (request->sockfd == NULL)
-    return (-2);
+  if (ret < 0)
+    return (-1);
 
   params->read_bytes = 0;
   if (strlen (request->last_ftp_response) > 9 &&
@@ -485,13 +430,13 @@
 rfc2068_get_file_size (gftp_request * request, const char *filename)
 {
   char *tempstr, *pos, *proto;
-  unsigned long size;
+  off_t size;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2);
   g_return_val_if_fail (filename != NULL, -2);
 
-  if (request->sockfd == NULL && rfc2068_connect (request) != 0)
+  if (request->sockfd < 0 && rfc2068_connect (request) != 0)
     return (-2);
 
   if (request->proxy_config != NULL && *request->proxy_config != '\0')
@@ -514,7 +459,7 @@
 
   size = rfc2068_send_command (request, tempstr, NULL);
   g_free (tempstr);
-  if (request->sockfd == NULL)
+  if (size < 0)
     return (-2);
 
   return (size);
@@ -703,8 +648,9 @@
 
 
 static int
-rfc2068_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd)
+rfc2068_get_next_file (gftp_request * request, gftp_file * fle, int fd)
 {
+  gftp_getline_buffer * rbuf;
   rfc2068_params * params;
   char tempstr[255];
   size_t len;
@@ -720,25 +666,28 @@
       request->last_dir_entry = NULL;
     }
 
+  rbuf = NULL;
   while (1)
     {
-      if (!gftp_fgets (request, tempstr, sizeof (tempstr), fd))
-        {
-          gftp_file_destroy (fle);
-          return (-2);
-        }
+      if (gftp_get_line (request, &rbuf, tempstr, sizeof (tempstr) - 1, fd) < 0)
+        return (-2);
 
       tempstr[sizeof (tempstr) - 1] = '\0';
       params->read_bytes += strlen (tempstr);
 
       if (params->chunked_transfer && strcmp (tempstr, "0\r\n") == 0)
         {
-          while (gftp_fgets (request, tempstr, sizeof (tempstr), fd))
+          while ((len = gftp_get_line (request, &rbuf, tempstr, 
+                                       sizeof (tempstr) - 1, fd)) > 0)
             {
               if (strcmp (tempstr, "\r\n") == 0)
                 break;
             }
 	  gftp_file_destroy (fle);
+
+          if (len < 0)
+            return (-1);
+
           return (0);
         }
 
@@ -764,7 +713,7 @@
       strcpy (request->last_dir_entry, tempstr);
       request->last_dir_entry_len = len;
     }
-  return (feof (fd) ? 0 : len);
+  return (len);
 }
 
 
@@ -786,6 +735,23 @@
 }
 
 
+static void
+rfc2068_set_config_options (gftp_request * request)
+{
+  gftp_set_proxy_hostname (request, http_proxy_host);
+  gftp_set_proxy_port (request, http_proxy_port);
+  gftp_set_proxy_username (request, http_proxy_username);
+  gftp_set_proxy_password (request, http_proxy_password);
+
+
+  if (request->proxy_config == NULL)
+    {
+      request->proxy_config = g_malloc (5);
+      strcpy (request->proxy_config, "http");
+    }
+}
+
+
 void
 rfc2068_init (gftp_request * request)
 {
@@ -814,6 +780,8 @@
   request->rename = NULL;
   request->chmod = NULL;
   request->site = NULL;
+  request->parse_url = NULL;
+  request->set_config_options = rfc2068_set_config_options;
   request->url_prefix = "http";
   request->protocol_name = "HTTP";
   request->need_hostport = 1;
--- a/lib/rfc959.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/rfc959.c	Thu Nov 21 00:33:51 2002 +0000
@@ -20,14 +20,23 @@
 #include "gftp.h"
 static const char cvsid[] = "$Id$";
 
+typedef struct rfc959_params_tag
+{
+  gftp_getline_buffer * sockfd_rbuf,
+                      * datafd_rbuf;
+} rfc959_parms;
+
+
 static int
 rfc959_read_response (gftp_request * request)
 {
   char tempstr[255], code[4];
+  rfc959_parms * parms;
+  ssize_t num_read;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   *code = '\0';
   if (request->last_ftp_response)
@@ -36,13 +45,15 @@
       request->last_ftp_response = NULL;
     }
 
+  parms = request->protocol_data;
+
   do
     {
-      if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd))
+      if ((num_read = gftp_get_line (request, &parms->sockfd_rbuf, tempstr, 
+                                     sizeof (tempstr) - 1, 
+                                     request->sockfd)) <= 0)
 	break;
-      tempstr[strlen (tempstr) - 1] = '\0';
-      if (tempstr[strlen (tempstr) - 1] == '\r')
-	tempstr[strlen (tempstr) - 1] = '\0';
+
       if (isdigit ((int) *tempstr) && isdigit ((int) *(tempstr + 1))
 	  && isdigit ((int) *(tempstr + 2)))
 	{
@@ -54,14 +65,8 @@
     }
   while (strncmp (code, tempstr, 4) != 0);
 
-  if (ferror (request->sockfd)) 
-    {
-      request->logging_function (gftp_logging_send, request->user_data,
-                                 "Error reading from socket: %s\n",
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (-1);
-    }
+  if (num_read < 0)
+    return (-1);
 
   request->last_ftp_response = g_malloc (strlen (tempstr) + 1);
   strcpy (request->last_ftp_response, tempstr);
@@ -80,7 +85,7 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (command != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   if (strncmp (command, "PASS", 4) == 0)
     {
@@ -98,8 +103,8 @@
                                  command);
     }
 
-  if (gftp_fwrite (request, command, strlen (command), 
-                   request->sockfd_write) < 0)
+  if (gftp_write (request, command, strlen (command), 
+                   request->sockfd) < 0)
     return (-1);
 
   return (rfc959_read_response (request));
@@ -206,9 +211,58 @@
 
 
 static int
+rfc959_getcwd (gftp_request * request)
+{
+  char *pos, *dir;
+  int ret;
+
+  ret = rfc959_send_command (request, "PWD\r\n");
+  if (ret < 0)
+    return (-1);
+  else if (ret != '2')
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+				 _("Received invalid response to PWD command: '%s'\n"),
+                                 request->last_ftp_response);
+      gftp_disconnect (request);
+      return (-2);
+    }
+
+  if ((pos = strchr (request->last_ftp_response, '"')) == NULL)
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+				 _("Received invalid response to PWD command: '%s'\n"),
+                                 request->last_ftp_response);
+      gftp_disconnect (request);
+      return (-2);
+    }
+
+  dir = pos + 1;
+
+  if ((pos = strchr (dir, '"')) == NULL)
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+				 _("Received invalid response to PWD command: '%s'\n"),
+                                 request->last_ftp_response);
+      gftp_disconnect (request);
+      return (-2);
+    }
+
+  *pos = '\0';
+
+  if (request->directory)
+    g_free (request->directory);
+
+  request->directory = g_malloc (strlen (dir) + 1);
+  strcpy (request->directory, dir);
+  return (0);
+}
+
+
+static int
 rfc959_chdir (gftp_request * request, const char *directory)
 {
-  char ret, *tempstr, *dir;
+  char ret, *tempstr;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
@@ -228,32 +282,8 @@
 
   if (directory != request->directory)
     {
-      if (request->directory)
-        {
-          g_free (request->directory);
-          request->directory = NULL;
-        }
-
-      if (rfc959_send_command (request, "PWD\r\n") != '2')
-        return (-2);
-
-      tempstr = strchr (request->last_ftp_response, '"');
-      if (tempstr != NULL)
-        dir = tempstr + 1;
-      else
-        return (-2);
-
-      tempstr = strchr (dir, '"');
-      if (tempstr != NULL)
-        *tempstr = '\0';
-      else
-        {
-          gftp_disconnect (request);
-          return (-2);
-        }
-
-      request->directory = g_malloc (strlen (dir) + 1);
-      strcpy (request->directory, dir);
+      if (rfc959_getcwd (request) < 0)
+        return (-1);
     }
 
   return (0);
@@ -263,13 +293,16 @@
 static int
 rfc959_connect (gftp_request * request)
 {
-  char tempchar, *startpos, *endpos, *tempstr, *dir;
-  int sock, ret, resp;
+  char tempchar, *startpos, *endpos, *tempstr;
+  int ret, resp;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (request->hostname != NULL, -2);
 
+  if (request->sockfd > 0)
+    return (0);
+
   if (request->username == NULL || *request->username == '\0')
     {
       gftp_set_username (request, "anonymous");
@@ -278,30 +311,9 @@
   else if (strcasecmp (request->username, "anonymous") == 0)
     gftp_set_password (request, emailaddr);
     
-  if (request->sockfd != NULL)
-    return (0);
-
-  if ((sock = gftp_connect_server (request, "ftp")) < 0)
+  if ((request->sockfd = gftp_connect_server (request, "ftp")) < 0)
     return (-1);
 
-  if ((request->sockfd = fdopen (sock, "rb+")) == NULL)
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Cannot fdopen() socket: %s\n"),
-                                 g_strerror (errno));
-      close (sock);
-      return (-2);
-    }
-
-  if ((request->sockfd_write = fdopen (dup (sock), "wb+")) == NULL)
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Cannot fdopen() socket: %s\n"),
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (-2);
-    }
-
   /* Get the banner */
   if (rfc959_read_response (request) != '2')
     {
@@ -376,39 +388,17 @@
   if (request->directory != NULL && *request->directory != '\0')
     {
       ret = rfc959_chdir (request, request->directory);
-      if (request->sockfd == NULL)
+      if (request->sockfd < 0)
         return (-2);
     }
 
   if (ret != 0)
     {
-      if (rfc959_send_command (request, "PWD\r\n") != '2' || 
-          request->sockfd == NULL)
-        {
-          gftp_disconnect (request);
-  	  return (-2);
-        }
-
-      if ((tempstr = strchr (request->last_ftp_response, '"')) == NULL)
-        {
-          gftp_disconnect (request);
-	  return (-2);
-        }
-      dir = tempstr + 1;
-
-      if ((tempstr = strchr (dir, '"')) == NULL)
-	{
-          gftp_disconnect (request);
-          return (0);
-        }
-      if (tempstr != NULL)
-	*tempstr = '\0';
-
-      request->directory = g_malloc (strlen (dir) + 1);
-      strcpy (request->directory, dir);
+      if (rfc959_getcwd (request) < 0)
+        return (-1);
     }
 
-  if (request->sockfd == NULL)
+  if (request->sockfd < 0)
     return (-2);
 
   return (0);
@@ -421,18 +411,17 @@
   g_return_if_fail (request != NULL);
   g_return_if_fail (request->protonum == GFTP_FTP_NUM);
 
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     {
       request->logging_function (gftp_logging_misc, request->user_data,
 				 _("Disconnecting from site %s\n"),
 				 request->hostname);
-      fclose (request->sockfd);
-      fclose (request->sockfd_write);
-      request->sockfd = request->sockfd_write = NULL;
-      if (request->datafd)
+      close (request->sockfd);
+      request->sockfd = -1;
+      if (request->datafd > 0)
 	{
-	  fclose (request->datafd);
-	  request->datafd = NULL;
+	  close (request->datafd);
+	  request->datafd = -1;
 	}
     }
 }
@@ -446,13 +435,13 @@
   size_t data_addr_len;
   unsigned int temp[6];
   unsigned char ad[6];
-  int i, sock;
+  int i;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
-  if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+  if ((request->datafd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
     {
       request->logging_function (gftp_logging_error, request->user_data,
 				 _("Failed to create a socket: %s\n"),
@@ -469,69 +458,94 @@
     {
       if ((resp = rfc959_send_command (request, "PASV\r\n")) != '2')
 	{
-          if (request->sockfd == NULL)
+          if (request->sockfd < 0)
             return (-2);
 
 	  request->transfer_type = gftp_transfer_active;
 	  return (rfc959_data_connection_new (request));
 	}
+
       pos = request->last_ftp_response + 4;
       while (!isdigit ((int) *pos) && *pos != '\0')
         pos++;
+
       if (*pos == '\0')
         {
+          request->logging_function (gftp_logging_error, request->user_data,
+                      _("Cannot find an IP address in PASV response '%s'\n"),
+                      request->last_ftp_response);
           gftp_disconnect (request);
-          close (sock);
           return (-2);
         }
+
       if (sscanf (pos, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
                   &temp[3], &temp[4], &temp[5]) != 6)
         {
+          request->logging_function (gftp_logging_error, request->user_data,
+                      _("Cannot find an IP address in PASV response '%s'\n"),
+                      request->last_ftp_response);
           gftp_disconnect (request);
-          close (sock);
           return (-2);
         }
+
       for (i = 0; i < 6; i++)
         ad[i] = (unsigned char) (temp[i] & 0xff);
 
       memcpy (&data_addr.sin_addr, &ad[0], 4);
       memcpy (&data_addr.sin_port, &ad[4], 2);
-      if (connect (sock, (struct sockaddr *) &data_addr, data_addr_len) == -1)
+      if (connect (request->datafd, (struct sockaddr *) &data_addr, 
+                   data_addr_len) == -1)
         {
           request->logging_function (gftp_logging_error, request->user_data,
                                     _("Cannot create a data connection: %s\n"),
                                     g_strerror (errno));
           gftp_disconnect (request);
-          close (sock);
           return (-1);
 	}
     }
   else
     {
-      getsockname (fileno (request->sockfd), (struct sockaddr *) &data_addr,
-		   &data_addr_len);
+      if (getsockname (request->sockfd, (struct sockaddr *) &data_addr,
+                       &data_addr_len) == -1)
+        {
+	  request->logging_function (gftp_logging_error, request->user_data,
+				     _("Cannot get socket name: %s\n"),
+				     g_strerror (errno));
+          gftp_disconnect (request);
+	  return (-1);
+        }
+
       data_addr.sin_port = 0;
-      if (bind (sock, (struct sockaddr *) &data_addr, data_addr_len) == -1)
+      if (bind (request->datafd, (struct sockaddr *) &data_addr, 
+                data_addr_len) == -1)
 	{
 	  request->logging_function (gftp_logging_error, request->user_data,
 				     _("Cannot bind a port: %s\n"),
 				     g_strerror (errno));
           gftp_disconnect (request);
-	  close (sock);
 	  return (-1);
 	}
 
-      getsockname (sock, (struct sockaddr *) &data_addr, &data_addr_len);
-      if (listen (sock, 1) == -1)
+      if (getsockname (request->datafd, (struct sockaddr *) &data_addr, 
+                       &data_addr_len) == -1)
+        {
+	  request->logging_function (gftp_logging_error, request->user_data,
+				     _("Cannot get socket name: %s\n"),
+				     g_strerror (errno));
+          gftp_disconnect (request);
+	  return (-1);
+        }
+
+      if (listen (request->datafd, 1) == -1)
 	{
 	  request->logging_function (gftp_logging_error, request->user_data,
 				     _("Cannot listen on port %d: %s\n"),
 				     ntohs (data_addr.sin_port),
 				     g_strerror (errno));
           gftp_disconnect (request);
-	  close (sock);
 	  return (-1);
 	}
+
       pos = (char *) &data_addr.sin_addr;
       pos1 = (char *) &data_addr.sin_port;
       command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n",
@@ -543,20 +557,10 @@
       if (resp != '2')
 	{
           gftp_disconnect (request);
-	  close (sock);
 	  return (-2);
 	}
     }
 
-  if ((request->datafd = fdopen (sock, "rb+")) == NULL)
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Cannot fdopen() socket: %s\n"),
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (-2);
-    }
-
   return (0);
 }
 
@@ -570,11 +574,15 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
-  g_return_val_if_fail (request->datafd != NULL, -2);
+  g_return_val_if_fail (request->datafd > 0, -2);
   g_return_val_if_fail (request->transfer_type == gftp_transfer_active, -2);
 
   cli_addr_len = sizeof (cli_addr);
-  if ((infd = accept (fileno (request->datafd), (struct sockaddr *) &cli_addr,
+
+  if (gftp_set_sockblocking (request, request->datafd, 0) == -1)
+    return (-1);
+
+  if ((infd = accept (request->datafd, (struct sockaddr *) &cli_addr,
        &cli_addr_len)) == -1)
     {
       request->logging_function (gftp_logging_error, request->user_data,
@@ -584,46 +592,37 @@
       return (-1);
     }
 
-  fclose (request->datafd);
+  close (request->datafd);
 
-  if ((request->datafd = fdopen (infd, "rb+")) == NULL)
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Cannot fdopen() socket: %s\n"),
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (-2);
-    }
+  request->datafd = infd;
+  if (gftp_set_sockblocking (request, request->datafd, 1) == -1)
+    return (-1);
+
   return (0);
 }
 
 
-static long
-rfc959_get_file (gftp_request * request, const char *filename, FILE * fd,
+static off_t
+rfc959_get_file (gftp_request * request, const char *filename, int fd,
                  off_t startsize)
 {
   char *command, *tempstr, resp;
-  int ret, flags;
+  int ret;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (filename != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
-  if (fd != NULL)
+  if (fd > 0)
     request->datafd = fd;
 
-  if (request->datafd == NULL && 
+  if (request->datafd < 0 && 
       (ret = rfc959_data_connection_new (request)) < 0)
     return (ret);
 
-  flags = fcntl (fileno (request->datafd), F_GETFL, 0);
-  if (fcntl (fileno (request->datafd), F_SETFL, flags | O_NONBLOCK) < 0)
-    {
-      fclose (request->datafd);
-      request->datafd = NULL;
-      return (-1);
-    }
+  if (gftp_set_sockblocking (request, request->datafd, 1) == -1)
+    return (-1);
 
   if (startsize > 0)
     {
@@ -637,8 +636,8 @@
 
       if (resp != '3')
         {
-          fclose (request->datafd);
-          request->datafd = NULL;
+          close (request->datafd);
+          request->datafd = -1;
 	  return (-2);
         }
     }
@@ -648,7 +647,11 @@
   g_free (tempstr);
 
   if (ret != '1')
-    return (-2);
+    {
+      close (request->datafd);
+      request->datafd = -1;
+      return (-2);
+    }
 
   if (request->transfer_type == gftp_transfer_active &&
       (ret = rfc959_accept_active_connection (request)) < 0)
@@ -668,31 +671,26 @@
 
 
 static int
-rfc959_put_file (gftp_request * request, const char *filename, FILE * fd,
+rfc959_put_file (gftp_request * request, const char *filename, int fd,
                  off_t startsize, off_t totalsize)
 {
   char *command, *tempstr, resp;
-  int ret, flags;
+  int ret;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (filename != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
-  if (fd != NULL)
+  if (fd > 0)
     fd = request->datafd;
 
-  if (request->datafd == NULL && 
+  if (request->datafd < 0 && 
       (ret = rfc959_data_connection_new (request)) < 0)
     return (ret);
 
-  flags = fcntl (fileno (request->datafd), F_GETFL, 0);
-  if (fcntl (fileno (request->datafd), F_SETFL, flags | O_NONBLOCK) < 0)
-    {
-      fclose (request->datafd);
-      request->datafd = NULL;
-      return (-1);
-    }
+  if (gftp_set_sockblocking (request, request->datafd, 1) == -1)
+    return (-1);
 
   if (startsize > 0)
     {
@@ -705,8 +703,8 @@
       g_free (command);
       if (resp != '3')
         {
-          fclose (request->datafd);
-          request->datafd = NULL;
+          close (request->datafd);
+          request->datafd = -1;
 	  return (-2);
         }
     }
@@ -715,7 +713,11 @@
   ret = rfc959_send_command (request, tempstr);
   g_free (tempstr);
   if (ret != '1')
-    return (-2);
+    {
+      close (request->datafd);
+      request->datafd = -1;
+      return (-2);
+    }
 
   if (request->transfer_type == gftp_transfer_active && 
       (ret = rfc959_accept_active_connection (request)) < 0)
@@ -724,6 +726,7 @@
   return (0);
 }
 
+
 static long 
 rfc959_transfer_file (gftp_request *fromreq, const char *fromfile, 
                       off_t fromsize, gftp_request *toreq, 
@@ -735,14 +738,13 @@
   g_return_val_if_fail (fromfile != NULL, -2);
   g_return_val_if_fail (toreq != NULL, -2);
   g_return_val_if_fail (tofile != NULL, -2);
-  g_return_val_if_fail (fromreq->sockfd != NULL, -2);
-  g_return_val_if_fail (toreq->sockfd != NULL, -2);
+  g_return_val_if_fail (fromreq->sockfd > 0, -2);
+  g_return_val_if_fail (toreq->sockfd > 0, -2);
 
   fromreq->transfer_type = gftp_transfer_passive;
   toreq->transfer_type = gftp_transfer_active;
 
-  if (rfc959_send_command (fromreq, "PASV\r\n") != '2' ||
-      fromreq->sockfd == NULL)
+  if (rfc959_send_command (fromreq, "PASV\r\n") != '2')
     return (-2);
 
   pos = fromreq->last_ftp_response + 4;
@@ -766,20 +768,20 @@
   g_free (tempstr);
 
   tempstr = g_strconcat ("RETR ", fromfile, "\r\n", NULL);
-  if (gftp_fwrite (fromreq, tempstr, strlen (tempstr), 
-                   fromreq->sockfd_write) < 0)
-     {
-       g_free (tempstr);
-       return (-2);
-     }
+  if (gftp_write (fromreq, tempstr, strlen (tempstr), 
+                   fromreq->sockfd) < 0)
+    {
+      g_free (tempstr);
+      return (-2);
+    }
   g_free (tempstr);
 
   tempstr = g_strconcat ("STOR ", tofile, "\r\n", NULL);
-  if (gftp_fwrite (toreq, tempstr, strlen (tempstr), toreq->sockfd_write) < 0)
-     {
-       g_free (tempstr);
-       return (-2);
-     }
+  if (gftp_write (toreq, tempstr, strlen (tempstr), toreq->sockfd) < 0)
+    {
+      g_free (tempstr);
+      return (-2);
+    }
   g_free (tempstr);
 
   if (rfc959_read_response (fromreq) < 0)
@@ -796,12 +798,12 @@
 {
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
-  if (request->datafd)
+  if (request->datafd > 0)
     {
-      fclose (request->datafd);
-      request->datafd = NULL;
+      close (request->datafd);
+      request->datafd = -1;
     }
   return (rfc959_read_response (request) == '2' ? 0 : -2);
 }
@@ -814,23 +816,22 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
-  if (request->datafd)
+  if (request->datafd > 0)
     {
-      fclose (request->datafd);
-      request->datafd = NULL;
+      close (request->datafd);
+      request->datafd = -1;
     }
 
   /* We need to read two lines of output. The first one is acknowleging
      the transfer and the second line acknowleges the ABOR command */
-  rfc959_send_command (request, "ABOR\r\n");
+  if (rfc959_send_command (request, "ABOR\r\n") < 0)
+    return (-2);
 
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     {
-      ret = rfc959_read_response (request);
-
-      if (ret != '2')
+      if ((ret = rfc959_read_response (request)) < 0)
         gftp_disconnect (request);
     }
   
@@ -846,7 +847,7 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   if ((ret = rfc959_data_connection_new (request)) < 0)
     return (ret);
@@ -872,37 +873,39 @@
 
 
 int
-rfc959_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd)
+rfc959_get_next_file (gftp_request * request, gftp_file * fle, int fd)
 {
+  rfc959_parms * parms;
   char tempstr[255];
-  size_t len;
+  ssize_t len;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (fle != NULL, -2);
-  g_return_val_if_fail (fd != NULL, -2);
+  g_return_val_if_fail (fd > 0, -2);
 
   if (request->last_dir_entry)
     {
       g_free (request->last_dir_entry);
       request->last_dir_entry = NULL;
     }
+
+  parms = request->protocol_data;
+
   do
     {
-      if (!gftp_fgets (request, tempstr, sizeof (tempstr), fd))
+      if ((len = gftp_get_line (request, &parms->datafd_rbuf,
+                                tempstr, sizeof (tempstr) - 1, fd)) <= 0)
 	{
           gftp_file_destroy (fle);
-          if (ferror (fd))
-            gftp_disconnect (request);
-	  return (-2);
+	  return ((int) len);
 	} 
-      tempstr[sizeof (tempstr) - 1] = '\0';
 
       if (gftp_parse_ls (tempstr, fle) != 0)
 	{
-	  if (strncmp (tempstr, "total", strlen("total")) != 0 &&
-	      strncmp (tempstr, _("total"), strlen(_("total"))) != 0)
-	    request->logging_function (gftp_logging_misc, request->user_data,
+	  if (strncmp (tempstr, "total", strlen ("total")) != 0 &&
+	      strncmp (tempstr, _("total"), strlen (_("total"))) != 0)
+	    request->logging_function (gftp_logging_error, request->user_data,
 				       _("Warning: Cannot parse listing %s\n"),
 				       tempstr);
 	  gftp_file_destroy (fle);
@@ -932,7 +935,7 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
 
-  if (request->sockfd != NULL && request->data_type != data_type)
+  if (request->sockfd > 0 && request->data_type != data_type)
     {
       if (data_type == GFTP_TYPE_BINARY)
 	tempstr = "TYPE I\r\n";
@@ -956,7 +959,7 @@
   g_return_val_if_fail (request != NULL, 0);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (filename != NULL, 0);
-  g_return_val_if_fail (request->sockfd != NULL, 0);
+  g_return_val_if_fail (request->sockfd > 0, 0);
 
   tempstr = g_strconcat ("SIZE ", filename, "\r\n", NULL);
   ret = rfc959_send_command (request, tempstr);
@@ -978,7 +981,7 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (directory != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   tempstr = g_strconcat ("RMD ", directory, "\r\n", NULL);
   ret = rfc959_send_command (request, tempstr);
@@ -995,7 +998,7 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (file != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   tempstr = g_strconcat ("DELE ", file, "\r\n", NULL);
   ret = rfc959_send_command (request, tempstr);
@@ -1012,7 +1015,7 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (directory != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   tempstr = g_strconcat ("MKD ", directory, "\r\n", NULL);
   ret = rfc959_send_command (request, tempstr);
@@ -1031,7 +1034,7 @@
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (oldname != NULL, -2);
   g_return_val_if_fail (newname != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   tempstr = g_strconcat ("RNFR ", oldname, "\r\n", NULL);
   ret = rfc959_send_command (request, tempstr);
@@ -1054,7 +1057,7 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (file != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   tempstr = g_malloc (strlen (file) + (mode / 10) + 16);
   sprintf (tempstr, "SITE CHMOD %d %s\r\n", mode, file);
@@ -1072,12 +1075,43 @@
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2);
   g_return_val_if_fail (command != NULL, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   tempstr = g_strconcat ("SITE ", command, "\r\n", NULL);
   ret = rfc959_send_command (request, tempstr);
   g_free (tempstr);
-  return (request->sockfd != NULL ? ret : -2);
+  return (request->sockfd > 0 ? ret : -2);
+}
+
+
+static void
+rfc959_set_config_options (gftp_request * request)
+{
+  request->transfer_type = passive_transfer ? gftp_transfer_passive : gftp_transfer_active;
+
+  if (strcmp (proxy_config, "http") != 0)
+    {
+      gftp_set_proxy_hostname (request, firewall_host);
+      gftp_set_proxy_port (request, firewall_port);
+      gftp_set_proxy_username (request, firewall_username);
+      gftp_set_proxy_password (request, firewall_password);
+      gftp_set_proxy_account (request, firewall_account);
+      gftp_set_proxy_config (request, proxy_config);
+    }
+  else
+    {
+      gftp_set_proxy_hostname (request, http_proxy_host);
+      gftp_set_proxy_port (request, http_proxy_port);
+      gftp_set_proxy_username (request, http_proxy_username);
+      gftp_set_proxy_password (request, http_proxy_password);
+
+
+      if (request->proxy_config == NULL)
+        {
+          gftp_protocols[GFTP_HTTP_NUM].init (request);
+          request->proxy_config = g_strdup ("ftp");
+        }
+    }
 }
 
 
@@ -1111,6 +1145,7 @@
   request->set_file_time = NULL;
   request->site = rfc959_site;
   request->parse_url = NULL;
+  request->set_config_options = rfc959_set_config_options;
   request->url_prefix = "ftp";
   request->protocol_name = "FTP";
   request->need_hostport = 1;
@@ -1118,6 +1153,7 @@
   request->use_cache = 1;
   request->use_threads = 1;
   request->always_connected = 0;
+  request->protocol_data = g_malloc0 (sizeof (rfc959_parms));
   gftp_set_config_options (request);
 }
 
--- a/lib/ssh.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/ssh.c	Thu Nov 21 00:33:51 2002 +0000
@@ -176,7 +176,7 @@
     memcpy (&buf[6], command, len);
   ssh_log_command (request, params->channel, cmdnum, command, len, 1);
 
-  if (gftp_fwrite (request, buf, len + 6, request->sockfd_write) < 0)
+  if (gftp_write (request, buf, len + 6, request->sockfd) < 0)
     return (-2);
 
   return 0;
@@ -185,27 +185,20 @@
 
 
 static char *
-ssh_read_message (gftp_request * request, char *buf, size_t len, FILE * fd)
+ssh_read_message (gftp_request * request, char *buf, size_t len, int fd)
 {
-  if (fd == NULL)
+  if (fd <= 0)
     fd = request->sockfd;
 
-  fread (buf, len, 1, fd);
-  if (ferror (fd))
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Error: Could not read from socket: %s\n"),
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (NULL);
-    }
+  if (gftp_read (request, buf, len, fd) < 0)
+    return (NULL);
 
   return (buf);
 }
 
 
 static int
-ssh_read_response (gftp_request * request, ssh_message *message, FILE * fd)
+ssh_read_response (gftp_request * request, ssh_message *message, int fd)
 {
   char buf[6];
 
@@ -313,7 +306,7 @@
                             strlen (directory) + 1) < 0) 
         return (-1);
 
-      if ((ret = ssh_read_response (request, &message, NULL)) != SUCCESS)
+      if ((ret = ssh_read_response (request, &message, -1)) != SUCCESS)
         {
           request->logging_function (gftp_logging_error, request->user_data,
 			    _("Could not change remote directory to %s: %s\n"),
@@ -329,7 +322,7 @@
       if (ssh_send_command (request, GETDIR, NULL, 0) < 0)
         return (-1);
 
-      if (ssh_read_response (request, &message, NULL) != TELLDIR)
+      if (ssh_read_response (request, &message, -1) != TELLDIR)
         {
           request->logging_function (gftp_logging_error, request->user_data,
                             _("Could not get current working directory: %s\n"),
@@ -353,7 +346,6 @@
   char **args, *tempstr, pts_name[20], *p1, p2, *exepath, port[6];
   int version, fdm, fds, s[2];
   ssh_message message;
-  const gchar *errstr;
   ssh_parms *params;
   pid_t child;
 
@@ -362,7 +354,7 @@
   g_return_val_if_fail (request->hostname != NULL, -2);
   
   params = request->protocol_data;
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     return (0);
 
   request->logging_function (gftp_logging_misc, request->user_data,
@@ -435,11 +427,7 @@
       execvp (ssh_prog_name != NULL && *ssh_prog_name != '\0' ?
               ssh_prog_name : "ssh", args);  
 
-      tempstr = _("Error: Cannot execute ssh: ");
-      write (1, tempstr, strlen (tempstr));
-      errstr = g_strerror (errno);
-      write (1, errstr, strlen (errstr));
-      write (1, "\n", 1);
+      printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno));
       return (-1);
     }
   else if (child > 0)
@@ -465,29 +453,13 @@
       g_free (exepath);
       g_free (tempstr);
 
-      if ((request->sockfd = fdopen (fdm, "rb+")) == NULL)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Cannot fdopen() socket: %s\n"),
-                                     g_strerror (errno));
-          close (fdm);
-          return (-2);
-        }
-
-      if ((request->sockfd_write = fdopen (fdm, "wb+")) == NULL)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Cannot fdopen() socket: %s\n"),
-                                     g_strerror (errno));
-          gftp_disconnect (request);
-          return (-2);
-        }
+      request->sockfd = fdm;
 
       params->channel = 0;
       version = htonl (7 << 4);
       if (ssh_send_command (request, SSH_VERSION, (char *) &version, 4) < 0)
         return (-2);
-      if (ssh_read_response (request, &message, NULL) != SSH_VERSION)
+      if (ssh_read_response (request, &message, -1) != SSH_VERSION)
         return (-2);
       g_free (message.data);
 
@@ -509,7 +481,7 @@
   if (ssh_send_command (request, GETDIR, NULL, 0) < 0)
     return (-1);
 
-  if (ssh_read_response (request, &message, NULL) != TELLDIR)
+  if (ssh_read_response (request, &message, -1) != TELLDIR)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                             _("Could not get current working directory: %s\n"),
@@ -522,9 +494,6 @@
     g_free (request->directory);
   request->directory = message.data;
 
-  if (request->sockfd == NULL)
-    return (-2);
-
   return (0);
 }
 
@@ -535,19 +504,24 @@
   g_return_if_fail (request != NULL);
   g_return_if_fail (request->protonum == GFTP_SSH_NUM);
 
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     {
       request->logging_function (gftp_logging_misc, request->user_data,
 			         _("Disconnecting from site %s\n"),
                                  request->hostname);
-      fclose (request->sockfd);
-      request->sockfd = request->sockfd_write = NULL;
+
+      if (close (request->sockfd) < 0)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error closing file descriptor: %s\n"),
+                                   g_strerror (errno));
+
+      request->sockfd = -1;
     }
 }
 
 
-static long
-ssh_get_file (gftp_request * request, const char *filename, FILE * fd,
+static off_t 
+ssh_get_file (gftp_request * request, const char *filename, int fd,
               off_t startsize)
 {
   ssh_message message;
@@ -568,7 +542,7 @@
   retsize = 0;
   while (1)
     {
-      ret = ssh_read_response (request, &message, NULL);
+      ret = ssh_read_response (request, &message, -1);
       switch (ret)
         {
           case FILESIZE:
@@ -604,7 +578,7 @@
 
 
 static int
-ssh_put_file (gftp_request * request, const char *filename, FILE * fd,
+ssh_put_file (gftp_request * request, const char *filename, int fd,
               off_t startsize, off_t totalsize)
 {
   ssh_message message;
@@ -626,7 +600,7 @@
   if (ssh_send_command (request, FILENAME, filename, strlen (filename) + 1) < 0)
     return (-1);
 
-  if (ssh_read_response (request, &message, NULL) < 0)
+  if (ssh_read_response (request, &message, -1) < 0)
     {
       g_free (message.data);
       return (-1);
@@ -663,13 +637,13 @@
 }
 
 
-static size_t 
+static ssize_t 
 ssh_get_next_file_chunk (gftp_request * request, char *buf, size_t size)
 {
   ssh_message message;
   size_t len;
 
-  switch (ssh_read_response (request, &message, NULL))
+  switch (ssh_read_response (request, &message, -1))
     {
       case DATA:
         len = size > message.len ? message.len : size;
@@ -678,7 +652,7 @@
         return (len);
       case ENDDATA:
         g_free (message.data);
-        if (ssh_read_response (request, &message, NULL) < 0)
+        if (ssh_read_response (request, &message, -1) < 0)
           {
             g_free (message.data);
             return (-1);
@@ -698,7 +672,7 @@
 }
 
 
-static size_t 
+static ssize_t 
 ssh_put_next_file_chunk (gftp_request * request, char *buf, size_t size)
 {
   if (size == 0)
@@ -773,7 +747,7 @@
     }
   g_free (tempstr);
 
-  if (ssh_read_response (request, &message, NULL) != STREAM)
+  if (ssh_read_response (request, &message, -1) != STREAM)
     {
       g_free (message.data);
       request->logging_function (gftp_logging_misc, request->user_data,
@@ -788,7 +762,7 @@
 
 
 static int
-ssh_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd)
+ssh_get_next_file (gftp_request * request, gftp_file * fle, int fd)
 {
   char *tempstr, *pos;
   ssh_message message;
@@ -930,7 +904,7 @@
 
   while (1)
     {
-      ret = ssh_read_response (request, &message, NULL);
+      ret = ssh_read_response (request, &message, -1);
       switch (ret)
         {
           case -1: 
@@ -1138,6 +1112,26 @@
 }
 
 
+static void
+ssh_set_config_options (gftp_request * request)
+{
+  if (request->sftpserv_path != NULL)
+    {
+      if (ssh1_sftp_path != NULL &&
+          strcmp (ssh1_sftp_path, request->sftpserv_path) == 0)
+        return;
+
+      g_free (request->sftpserv_path);
+      request->sftpserv_path = NULL;
+    }
+
+  if (ssh1_sftp_path != NULL)
+    request->sftpserv_path = g_strdup (ssh1_sftp_path);
+
+  request->need_userpass = ssh_need_userpass;
+}
+
+
 void
 ssh_init (gftp_request * request)
 {
@@ -1168,6 +1162,7 @@
   request->set_file_time = NULL;
   request->site = NULL;
   request->parse_url = NULL;
+  request->set_config_options = ssh_set_config_options;
   request->url_prefix = "ssh";
   request->protocol_name = "SSH";
   request->need_hostport = 1;
--- a/lib/sshv2.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/lib/sshv2.c	Thu Nov 21 00:33:51 2002 +0000
@@ -305,7 +305,7 @@
 
   sshv2_log_command (request, gftp_logging_send, type, buf + 5, len);
 
-  if (gftp_fwrite (request, buf, len + 5, request->sockfd_write) < 0)
+  if (gftp_write (request, buf, len + 5, request->sockfd) < 0)
     return (-2);
 
   return 0;
@@ -314,30 +314,23 @@
 
 static int
 sshv2_read_response (gftp_request * request, sshv2_message * message,
-                     FILE * fd)
+                     int fd)
 {
   ssize_t numread;
   char buf[5];
 
-  if (fd == NULL)
+  if (fd <= 0)
     fd = request->sockfd;
 
-  numread = fread (buf, 5, 1, fd);
-  if (ferror (fd))
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Error: Could not read from socket: %s\n"),
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (-1);
-    }
+  if ((numread = gftp_read (request, buf, 5, fd)) < 0)
+    return (-2);
 
-#ifdef DEBUG
+/* #ifdef DEBUG*/
   printf ("\rReceived: ");
   for (numread=0; numread<5; numread++)
     printf ("%x ", buf[numread]);
   fflush (stdout);
-#endif
+/* #endif*/
 
   memcpy (&message->length, buf, 4);
   message->length = ntohl (message->length);
@@ -350,29 +343,24 @@
       gftp_disconnect (request);
       return (-1);
     }
+
   message->command = buf[4];
   message->buffer = g_malloc (message->length);
 
   message->pos = message->buffer;
   message->end = message->buffer + message->length - 1;
 
-  numread = fread (message->buffer, message->length - 1, 1, fd);
-  if (ferror (fd))
-    {
-      request->logging_function (gftp_logging_error, request->user_data,
-                                 _("Error: Could not read from socket: %s\n"),
-                                 g_strerror (errno));
-      gftp_disconnect (request);
-      return (-1);
-    }
+  if ((numread = gftp_read (request, message->buffer, message->length -1, fd)) < 0)
+
+    return (-2);
+
   message->buffer[message->length - 1] = '\0';
 
-#ifdef DEBUG
-  printf ("\rReceived: ");
+/* #ifdef DEBUG*/
   for (numread=0; numread<message->length - 1; numread++)
     printf ("%x ", message->buffer[numread]);
   printf ("\n");
-#endif
+/* #endif*/
 
   sshv2_log_command (request, gftp_logging_recv, message->command, 
                      message->buffer, message->length);
@@ -500,7 +488,7 @@
     }
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) != SSH_FXP_NAME)
+  if (sshv2_read_response (request, &message, -1) != SSH_FXP_NAME)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                      _("Received wrong response from server, disconnecting\n"));
@@ -526,14 +514,13 @@
   char **args, *tempstr, pts_name[20], *p1, p2, *exepath, port[6];
   int version, fdm, fds, s[2];
   sshv2_message message;
-  const gchar *errstr;
   pid_t child;
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2);
   g_return_val_if_fail (request->hostname != NULL, -2);
   
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     return (0);
 
   request->logging_function (gftp_logging_misc, request->user_data,
@@ -612,11 +599,7 @@
       execvp (ssh_prog_name != NULL && *ssh_prog_name != '\0' ?
               ssh_prog_name : "ssh", args);
 
-      tempstr = _("Error: Cannot execute ssh: ");
-      write (1, tempstr, strlen (tempstr));
-      errstr = g_strerror (errno);
-      write (1, errstr, strlen (errstr));
-      write (1, "\n", 1);
+      printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno));
       return (-1);
     }
   else if (child > 0)
@@ -645,30 +628,14 @@
       g_free (args);
       g_free (exepath);
 
-      if ((request->sockfd = fdopen (fdm, "rb+")) == NULL)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Cannot fdopen() socket: %s\n"),
-                                     g_strerror (errno));
-          close (fdm);
-          return (-2);
-        }
-
-      if ((request->sockfd_write = fdopen (fdm, "wb+")) == NULL)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                     _("Cannot fdopen() socket: %s\n"),
-                                     g_strerror (errno));
-          gftp_disconnect (request);
-          return (-2);
-        }
+      request->sockfd = fdm;
 
       version = htonl (SSH_MY_VERSION);
       if (sshv2_send_command (request, SSH_FXP_INIT, (char *) &version, 4) < 0)
         return (-2);
 
       memset (&message, 0, sizeof (message));
-      if (sshv2_read_response (request, &message, NULL) != SSH_FXP_VERSION)
+      if (sshv2_read_response (request, &message, -1) != SSH_FXP_VERSION)
         {
           request->logging_function (gftp_logging_error, request->user_data,
                    _("Received wrong response from server, disconnecting\n"));
@@ -692,7 +659,7 @@
     }
 
   sshv2_getcwd (request);
-  if (request->sockfd == NULL)
+  if (request->sockfd < 0)
     return (-2);
 
   return (0);
@@ -709,13 +676,18 @@
 
   params = request->protocol_data;
 
-  if (request->sockfd != NULL)
+  if (request->sockfd > 0)
     {
       request->logging_function (gftp_logging_misc, request->user_data,
 			         _("Disconnecting from site %s\n"),
                                  request->hostname);
-      fclose (request->sockfd);
-      request->sockfd = request->sockfd_write = NULL;
+
+      if (close (request->sockfd) < 0)
+        request->logging_function (gftp_logging_error, request->user_data,
+                                   _("Error closing file descriptor: %s\n"),
+                                   g_strerror (errno));
+
+      request->sockfd = -1;
     }
 
   if (params->message.buffer != NULL)
@@ -750,7 +722,7 @@
         return (-2);
 
       memset (&message, 0, sizeof (message));
-      if (sshv2_read_response (request, &message, NULL) != SSH_FXP_STATUS)
+      if (sshv2_read_response (request, &message, -1) != SSH_FXP_STATUS)
         {
           request->logging_function (gftp_logging_error, request->user_data,
                      _("Received wrong response from server, disconnecting\n"));
@@ -782,7 +754,7 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
 
   params = request->protocol_data;
 
@@ -806,7 +778,7 @@
   g_free (tempstr);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) != SSH_FXP_HANDLE)
+  if (sshv2_read_response (request, &message, -1) != SSH_FXP_HANDLE)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                      _("Received wrong response from server, disconnecting\n"));
@@ -836,7 +808,7 @@
 
 
 static int
-sshv2_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd)
+sshv2_get_next_file (gftp_request * request, gftp_file * fle, int fd)
 {
   gint32 len, attrs, longnamelen;
   int ret, i, count, retsize;
@@ -1070,7 +1042,7 @@
       g_free (tempstr);
 
       memset (&message, 0, sizeof (message));
-      if (sshv2_read_response (request, &message, NULL) != SSH_FXP_NAME)
+      if (sshv2_read_response (request, &message, -1) != SSH_FXP_NAME)
         {
           request->logging_function (gftp_logging_error, request->user_data,
                      _("Received wrong response from server, disconnecting\n"));
@@ -1140,7 +1112,7 @@
   g_free (tempstr);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) < 0)
+  if (sshv2_read_response (request, &message, -1) < 0)
     return (-2);
 
   message.pos += 4;
@@ -1197,7 +1169,7 @@
   g_free (tempstr);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) < 0)
+  if (sshv2_read_response (request, &message, -1) < 0)
     return (-2);
 
   message.pos += 4;
@@ -1261,7 +1233,7 @@
   g_free (tempstr);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) < 0)
+  if (sshv2_read_response (request, &message, -1) < 0)
     return (-2);
 
   message.pos += 4;
@@ -1319,7 +1291,7 @@
   g_free (tempstr);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) < 0)
+  if (sshv2_read_response (request, &message, -1) < 0)
     return (-2);
 
   message.pos += 4;
@@ -1390,7 +1362,7 @@
   g_free (tempstr);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) < 0)
+  if (sshv2_read_response (request, &message, -1) < 0)
     return (-2);
 
   message.pos += 4;
@@ -1456,7 +1428,7 @@
   g_free (tempstr);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) < 0)
+  if (sshv2_read_response (request, &message, -1) < 0)
     return (-2);
 
   message.pos += 4;
@@ -1514,7 +1486,7 @@
   g_free (tempstr);
 
   memset (&params->message, 0, sizeof (params->message));
-  if (sshv2_read_response (request, &params->message, NULL) != SSH_FXP_ATTRS)
+  if (sshv2_read_response (request, &params->message, -1) != SSH_FXP_ATTRS)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                      _("Received wrong response from server, disconnecting\n"));
@@ -1555,8 +1527,8 @@
 }
 
 
-static long 
-sshv2_get_file (gftp_request * request, const char *file, FILE * fd,
+static off_t
+sshv2_get_file (gftp_request * request, const char *file, int fd,
                 off_t startsize)
 {
   sshv2_params * params;
@@ -1567,7 +1539,7 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
   /* fd ignored for this protocol */
 
   params = request->protocol_data;
@@ -1607,7 +1579,7 @@
 
   g_free (tempstr);
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) != SSH_FXP_HANDLE)
+  if (sshv2_read_response (request, &message, -1) != SSH_FXP_HANDLE)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                      _("Received wrong response from server, disconnecting\n"));
@@ -1637,7 +1609,7 @@
 
 
 static int
-sshv2_put_file (gftp_request * request, const char *file, FILE * fd,
+sshv2_put_file (gftp_request * request, const char *file, int fd,
                 off_t startsize, off_t totalsize)
 {
   sshv2_params * params;
@@ -1648,7 +1620,7 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
   /* fd ignored for this protocol */
 
   params = request->protocol_data;
@@ -1691,7 +1663,7 @@
 
   g_free (tempstr);
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) != SSH_FXP_HANDLE)
+  if (sshv2_read_response (request, &message, -1) != SSH_FXP_HANDLE)
     {
       request->logging_function (gftp_logging_error, request->user_data,
                      _("Received wrong response from server, disconnecting\n"));
@@ -1720,7 +1692,7 @@
 }
 
 
-static size_t 
+static ssize_t 
 sshv2_get_next_file_chunk (gftp_request * request, char *buf, size_t size)
 {
   sshv2_params * params;
@@ -1735,7 +1707,7 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
   g_return_val_if_fail (buf != NULL, -2);
 
   params = request->protocol_data;
@@ -1766,7 +1738,7 @@
     return (-2);
 
   memset (&message, 0, sizeof (message));
-  if (sshv2_read_response (request, &message, NULL) != SSH_FXP_DATA)
+  if (sshv2_read_response (request, &message, -1) != SSH_FXP_DATA)
     {
       message.pos += 4;
       if ((num = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK)) < 0)
@@ -1802,7 +1774,7 @@
 }
 
 
-static size_t 
+static ssize_t 
 sshv2_put_next_file_chunk (gftp_request * request, char *buf, size_t size)
 {
   sshv2_params * params;
@@ -1819,7 +1791,7 @@
 
   g_return_val_if_fail (request != NULL, -2);
   g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2);
-  g_return_val_if_fail (request->sockfd != NULL, -2);
+  g_return_val_if_fail (request->sockfd > 0, -2);
   g_return_val_if_fail (buf != NULL, -2);
   g_return_val_if_fail (size <= 32500, -2);
 
@@ -1852,7 +1824,7 @@
 
   memset (&message, 0, sizeof (message));
   params->dont_log_status = 1;
-  ret = sshv2_read_response (request, &message, NULL);
+  ret = sshv2_read_response (request, &message, -1);
   params->dont_log_status = 0;
   if (ret != SSH_FXP_STATUS)
    {
@@ -1878,6 +1850,26 @@
 }
 
 
+static void
+sshv2_set_config_options (gftp_request * request)
+{
+  if (request->sftpserv_path != NULL)
+    {
+      if (ssh2_sftp_path != NULL && 
+          strcmp (ssh2_sftp_path, request->sftpserv_path) == 0)
+        return;
+
+      g_free (request->sftpserv_path);
+      request->sftpserv_path = NULL;
+    }
+
+  if (ssh2_sftp_path != NULL)
+    request->sftpserv_path = g_strdup (ssh2_sftp_path);
+
+  request->need_userpass = ssh_need_userpass;
+}
+
+
 void
 sshv2_init (gftp_request * request)
 {
@@ -1910,6 +1902,7 @@
   request->set_file_time = sshv2_set_file_time;
   request->site = NULL;
   request->parse_url = NULL;
+  request->set_config_options = sshv2_set_config_options;
   request->url_prefix = "ssh2";
   request->protocol_name = "SSH2";
   request->need_hostport = 1;
--- a/src/gtk/dnd.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/src/gtk/dnd.c	Thu Nov 21 00:33:51 2002 +0000
@@ -92,15 +92,8 @@
                      wdata, templist, 1);
   gftp_request_destroy (current_ftpdata);
 
-  if (newfle->isdir)
-    {
-/* FIXME - need to fix this 
-      add_entire_directory (tdata, newfle, 
-		            GFTP_GET_DIRECTORY (tdata->fromhdata->ftpdata), 
-			    GFTP_GET_DIRECTORY (tdata->tohdata->ftpdata), 
-			    tdata->fromhdata->ftpdata);
-*/
-    }
+  /* FIXME  resume files and download entire directories */
+
   return (1);
 }
 
--- a/src/gtk/gftp-gtk.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/src/gtk/gftp-gtk.c	Thu Nov 21 00:33:51 2002 +0000
@@ -352,7 +352,7 @@
 
   portedit = gtk_combo_new ();
   gtk_combo_set_case_sensitive (GTK_COMBO (portedit), 1);
-  gtk_widget_set_size_request (portedit, 40, -1);
+  gtk_widget_set_size_request (portedit, 45, -1);
 
   gtk_signal_connect (GTK_OBJECT (GTK_COMBO (portedit)->entry), "activate",
 		      GTK_SIGNAL_FUNC (toolbar_hostedit), NULL);
--- a/src/gtk/misc-gtk.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/src/gtk/misc-gtk.c	Thu Nov 21 00:33:51 2002 +0000
@@ -708,7 +708,7 @@
 int
 check_reconnect (gftp_window_data *wdata)
 {
-  return (wdata->request->cached && wdata->request->sockfd == NULL && 
+  return (wdata->request->cached && wdata->request->sockfd < 0 && 
 	  !ftp_connect (wdata, wdata->request, 0) ? -1 : 0);
 }
 
--- a/src/gtk/transfer.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/src/gtk/transfer.c	Thu Nov 21 00:33:51 2002 +0000
@@ -41,7 +41,6 @@
 
   if (socketpair (AF_UNIX, SOCK_STREAM, 0, request->wakeup_main_thread) == 0)
     {
-      /* FIXME - depreciated in GDK 2.0 */
       handler = gdk_input_add (request->wakeup_main_thread[0], 
                                GDK_INPUT_READ, wakeup_main_thread, request);
     }
@@ -60,7 +59,6 @@
 {
   if (request->wakeup_main_thread[0] > 0 && request->wakeup_main_thread[1] > 0)
     {
-      /* FIXME - depreciated in GDK 2.0 */
       gdk_input_remove (handler);
       close (request->wakeup_main_thread[0]);
       close (request->wakeup_main_thread[1]);
@@ -733,7 +731,7 @@
 {
   gftp_transfer * transfer;
   char *tempstr, buf[8192];
-  FILE * tofd, * fromfd;
+  int tofd, fromfd;
   off_t fromsize, total;
   gftp_file * curfle; 
   ssize_t num_read;
@@ -794,18 +792,18 @@
               if (transfer->transfer_direction == GFTP_DIRECTION_DOWNLOAD)
                 {
                   tofd = curfle->fd;
-                  fromfd = NULL;
+                  fromfd = -1;
                 }
               else
                 {
-                  tofd = NULL;
+                  tofd = -1;
                   fromfd = curfle->fd;
                 }
             }
           else
             {
-              tofd = NULL;
-              fromfd = NULL;
+              tofd = -1;
+              fromfd = -1;
             }
 
           if (curfle->size == 0)
@@ -840,9 +838,9 @@
           if (curfle->is_fd)
             {
               if (transfer->transfer_direction == GFTP_DIRECTION_DOWNLOAD)
-                transfer->toreq->datafd = NULL;
+                transfer->toreq->datafd = -1;
               else
-                transfer->fromreq->datafd = NULL;
+                transfer->fromreq->datafd = -1;
             }
 
           pthread_mutex_lock (transfer->structmutex);
@@ -917,9 +915,9 @@
           if (curfle->is_fd)
             {
               if (transfer->transfer_direction == GFTP_DIRECTION_DOWNLOAD)
-                transfer->toreq->datafd = NULL;
+                transfer->toreq->datafd = -1;
               else
-                transfer->fromreq->datafd = NULL;
+                transfer->fromreq->datafd = -1;
             }
 
           if (gftp_end_transfer (transfer->fromreq) != 0)
@@ -1239,7 +1237,7 @@
       tempfle = tdata->updfle->data;
 
       if (tempfle->is_fd)
-        fd = fileno (tempfle->fd);
+        fd = tempfle->fd;
       else
         fd = 0;
 
@@ -1251,8 +1249,8 @@
 
           if (tempfle->is_fd)
             {
-              fclose (tempfle->fd);
-              tempfle->fd = NULL;
+              close (tempfle->fd);
+              tempfle->fd = -1;
             }
         }
       else if (tempfle->done_edit)
@@ -1263,8 +1261,8 @@
 
           if (tempfle->is_fd)
             {
-              fclose (tempfle->fd);
-              tempfle->fd = NULL;
+              close (tempfle->fd);
+              tempfle->fd = -1;
             }
         }
       else if (tempfle->done_rm)
@@ -1409,8 +1407,8 @@
     {
       fromreq = tdata->fromwdata != NULL ? ((gftp_window_data *) tdata->fromwdata)->request : NULL;
       if (!tdata->fromreq->stopable && tdata->fromwdata &&
-          ((fromreq->sockfd == NULL && fromreq->cached) ||
-           fromreq->always_connected) && tdata->fromreq->sockfd != NULL &&
+          ((fromreq->sockfd < 0 && fromreq->cached) ||
+           fromreq->always_connected) && tdata->fromreq->sockfd > 0 &&
           compare_request (tdata->fromreq, fromreq, 0))
 	{
           swap_socks (((gftp_window_data *) tdata->towdata)->request, 
@@ -1464,7 +1462,7 @@
   if (!tdata->fromreq->stopable)
     {
       if (tdata->fromwdata && 
-          ((gftp_window_data *) tdata->fromwdata)->request->sockfd != NULL && 
+          ((gftp_window_data *) tdata->fromwdata)->request->sockfd > 0 && 
           !((gftp_window_data *) tdata->fromwdata)->request->stopable &&
           compare_request (tdata->fromreq, ((gftp_window_data *) tdata->fromwdata)->request, 0))
 	{
--- a/src/gtk/view_dialog.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/src/gtk/view_dialog.c	Thu Nov 21 00:33:51 2002 +0000
@@ -28,7 +28,7 @@
   GList * templist, * filelist, * newfile;
   gftp_window_data * fromwdata, * towdata;
   gftp_file * new_fle;
-  int num, fd;
+  int num;
 
   fromwdata = data;
   towdata = fromwdata == &window1 ? &window2 : &window1;
@@ -56,7 +56,7 @@
       if (new_fle->destfile)
         g_free (new_fle->destfile);
       new_fle->destfile = g_strconcat (g_get_tmp_dir (), "/gftp-view.XXXXXX", NULL);
-      if ((fd = mkstemp (new_fle->destfile)) < 0)
+      if ((new_fle->fd = mkstemp (new_fle->destfile)) < 0)
         {
           ftp_log (gftp_logging_misc, NULL, 
                    _("Error: Cannot open %s for writing: %s\n"),  
@@ -65,14 +65,7 @@
           return;
         }
 
-      chmod (new_fle->destfile, S_IRUSR | S_IWUSR);
-      if ((new_fle->fd = fdopen (fd, "rw+")) == NULL)
-        {
-          ftp_log (gftp_logging_error, NULL,
-                   _("Cannot fdopen() socket: %s\n"),
-                   g_strerror (errno));
-          return;
-        }
+      fchmod (new_fle->fd, S_IRUSR | S_IWUSR);
 
       new_fle->is_fd = 1;
       new_fle->done_view = 1;
@@ -90,7 +83,7 @@
   gftp_window_data * fromwdata, * towdata;
   GList * templist, * filelist, * newfile;
   gftp_file * new_fle;
-  int num, fd;
+  int num;
 
   fromwdata = data;
   towdata = fromwdata == &window1 ? &window2 : &window1;
@@ -126,7 +119,7 @@
         g_free (new_fle->destfile);
       new_fle->destfile = g_strconcat (g_get_tmp_dir (), "/gftp-view.XXXXXX",
                                        NULL);
-      if ((fd = mkstemp (new_fle->destfile)) < 0)
+      if ((new_fle->fd = mkstemp (new_fle->destfile)) < 0)
         {
           ftp_log (gftp_logging_misc, NULL, 
                    _("Error: Cannot open %s for writing: %s\n"),
@@ -135,14 +128,7 @@
           return;
         }
 
-      chmod (new_fle->destfile, S_IRUSR | S_IWUSR);
-      if ((new_fle->fd = fdopen (fd, "rw+")) == NULL)
-        {
-          ftp_log (gftp_logging_error, NULL,
-                   _("Cannot fdopen() socket: %s\n"),
-                   g_strerror (errno));
-          return;
-        }
+      fchmod (new_fle->fd, S_IRUSR | S_IWUSR);
 
       new_fle->is_fd = 1;
       new_fle->done_edit = 1;
--- a/src/text/gftp-text.c	Tue Nov 12 00:04:44 2002 +0000
+++ b/src/text/gftp-text.c	Thu Nov 21 00:33:51 2002 +0000
@@ -588,6 +588,9 @@
     }
   g_free (fle);
 
+  if (files == NULL)
+    return (1);
+
   if (request == gftp_text_locreq)
     {
       sortcol = local_sortcol;
@@ -863,9 +866,9 @@
         }
 
       transfer->curtrans = curfle->startsize;
-      fromsize = gftp_transfer_file (transfer->fromreq, curfle->file, NULL,
+      fromsize = gftp_transfer_file (transfer->fromreq, curfle->file, -1,
                                      curfle->startsize, transfer->toreq, curfle->destfile, 
-                                     NULL, curfle->startsize);
+                                     -1, curfle->startsize);
       if (fromsize < 0)
         return (1);