changeset 146:782f84694489

2003-4-25 Brian Masney <masneyb@gftp.org> * lib/rfc959.c - added IPV6 support (RFC2428). The only part of the project that isn't IPV6 ready is the proxy comparsion functions. * lib/protocols.c - change the hints.ai_family paramater from AF_INET to PF_UNSPEC * lib/gftp.h lib/misc.c lib/pty.c - moved the functionality of pty[ms]_open() to pty.c. Combined these 2 functions into open_ptys(), and there is one defined for each system type (lots of #define's in this file!) * lib/Makefile.am po/POTFILES.in - added pty.c * lib/sshv2.c - when searching for the password prompt, omit the first character in case it is capitalized. Also, use the new function open_ptys() * configure.in - search for openpty in -lutil. Also, define HAVE_OPENPTY if this function is present on the system
author masneyb
date Sat, 26 Apr 2003 15:26:42 +0000
parents a57ba8acfde5
children 280115680288
files ChangeLog configure.in lib/Makefile.am lib/gftp.h lib/misc.c lib/protocols.c lib/pty.c lib/rfc959.c lib/sshv2.c po/POTFILES.in
diffstat 10 files changed, 409 insertions(+), 195 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Apr 25 12:53:23 2003 +0000
+++ b/ChangeLog	Sat Apr 26 15:26:42 2003 +0000
@@ -1,3 +1,25 @@
+2003-4-25 Brian Masney <masneyb@gftp.org>
+	* lib/rfc959.c - added IPV6 support (RFC2428). The only part of the
+	project that isn't IPV6 ready is the proxy comparsion functions.
+
+	* lib/protocols.c - change the hints.ai_family paramater from AF_INET
+	to PF_UNSPEC
+
+	* lib/gftp.h lib/misc.c lib/pty.c - moved the functionality of
+	pty[ms]_open() to pty.c. Combined these 2 functions into open_ptys(),
+	and there is one defined for each system type (lots of #define's in
+	this file!)
+
+	* lib/Makefile.am po/POTFILES.in - added pty.c 
+
+	* lib/sshv2.c - when searching for the password prompt, omit the first
+	character in case it is capitalized. Also, use the new function 
+	open_ptys()
+
+	* configure.in - search for openpty in -lutil. Also, define
+	HAVE_OPENPTY if this function is present on the system
+
+
 2003-4-23 Brian Masney <masneyb@gftp.org>
 	* Makefile.am - removed config.rpath from EXTRA_DIST
 
@@ -767,7 +789,7 @@
 
 	* cvsclean - added this script
 
-	* *.[ch] - added $Id: ChangeLog,v 1.73 2003/04/24 02:21:54 masneyb Exp $ tags
+	* *.[ch] - added $Id: ChangeLog,v 1.74 2003/04/26 15:26:40 masneyb Exp $ tags
 
 	* debian/* - updated files from Debian maintainer
 
--- a/configure.in	Fri Apr 25 12:53:23 2003 +0000
+++ b/configure.in	Sat Apr 26 15:26:42 2003 +0000
@@ -64,7 +64,7 @@
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
 AC_FUNC_UTIME_NULL
-AC_CHECK_FUNCS(gai_strerror getaddrinfo getcwd gettimeofday getwd mkdir mktime putenv rmdir select socket strdup strstr strtod strtol uname grantpt)
+AC_CHECK_FUNCS(gai_strerror getaddrinfo getcwd gettimeofday getwd mkdir mktime putenv rmdir select socket strdup strstr strtod strtol uname grantpt openpty)
 
 if test "x$enable_gtk20" = "xyes" ; then
   PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.0.0, found_glib20=1, found_glib20=0)
@@ -78,6 +78,9 @@
 
 EXTRA_LIBS=""
 
+# FreeBSD needs this
+AC_CHECK_LIB(util, openpty, EXTRA_LIBS="-lutil")
+
 AC_CHECK_LIB(socket, socket, EXTRA_LIBS="-lsocket")
   
 AC_CHECK_LIB(nsl, gethostbyname, EXTRA_LIBS="$EXTRA_LIBS -lnsl")
--- a/lib/Makefile.am	Fri Apr 25 12:53:23 2003 +0000
+++ b/lib/Makefile.am	Sat Apr 26 15:26:42 2003 +0000
@@ -2,6 +2,6 @@
 
 noinst_LIBRARIES = libgftp.a
 libgftp_a_SOURCES=bookmark.c cache.c config_file.c local.c misc.c protocols.c \
-                  rfc959.c rfc2068.c sshv2.c
+                  pty.c rfc959.c rfc2068.c sshv2.c
 INCLUDES=@GLIB_CFLAGS@ @PTHREAD_CFLAGS@ -I../intl -DSHARE_DIR=\"$(datadir)/gftp\" 
 noinst_HEADERS=gftp.h options.h
--- a/lib/gftp.h	Fri Apr 25 12:53:23 2003 +0000
+++ b/lib/gftp.h	Sat Apr 26 15:26:42 2003 +0000
@@ -80,6 +80,13 @@
 #define AF_LOCAL AF_UNIX
 #endif
 
+#ifdef HAVE_GETADDRINFO
+#define HAVE_IPV6
+#define GFTP_GET_AI_FAMILY(request)	(request->hostp->ai_family)
+#else
+#define GFTP_GET_AI_FAMILY(request)	AF_INET
+#endif
+
 /* We need the major() and minor() macros in the user interface. If they aren't
    defined by the system, we'll just define them here. */
 #ifndef major
@@ -610,14 +617,6 @@
 
 gftp_request * copy_request 		( gftp_request * req );
 
-int ptym_open 				( char *pts_name,
-					  size_t len );
-
-int ptys_open 				( int fdm, 
-					  char *pts_name );
-
-int tty_raw 				( int fd );
-
 GList * gftp_sort_filelist 		( GList * filelist, 
 					  int column, 
 					  int asds );
@@ -835,5 +834,12 @@
 int gftp_get_transfer_status 		( gftp_transfer * tdata, 
 					  ssize_t num_read );
 
+/* pty.c */
+int open_ptys 				( gftp_request * request, 
+					  int *fdm, 
+					  int *fds );
+
+int tty_raw 				( int fd );
+
 #endif
 
--- a/lib/misc.c	Fri Apr 25 12:53:23 2003 +0000
+++ b/lib/misc.c	Sat Apr 26 15:26:42 2003 +0000
@@ -608,141 +608,6 @@
 }
 
 
-int
-ptym_open (char *pts_name, size_t len)
-{
-  int fd;
-
-#ifdef __sgi
-  char *tempstr;
-
-  if ((tempstr = _getpty (&fd, O_RDWR, 0600, 0)) == NULL)
-    return (-1);
-
-  strncpy (pts_name, tempstr, len);
-  return (fd);
-
-#else /* !__sgi */
-
-#ifdef HAVE_GRANTPT
-
-  char *tempstr;
-
-  strncpy (pts_name, "/dev/ptmx", len);
-  if ((fd = open (pts_name, O_RDWR)) < 0)
-    return (-1);
-
-  if (grantpt (fd) < 0)
-    {
-      close (fd);
-      return (-1);
-    }
-
-  if (unlockpt (fd) < 0)
-    {
-      close (fd);
-      return (-1);
-    }
-
-  if ((tempstr = ptsname (fd)) == NULL)
-    {
-      close (fd);
-      return (-1);
-    }
-
-  strncpy (pts_name, tempstr, len);
-  return (fd);
-
-#else /* !GRANTPT */
-
-  char *pos1, *pos2;
-
-  strncpy (pts_name, "/dev/ptyXY", len);
-  for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++) 
-    {
-      pts_name[8] = *pos1;
-      for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++)
-        {
-          pts_name[9] = *pos2;
-          if ((fd = open (pts_name, O_RDWR)) < 0)
-            continue;
-          pts_name[5] = 't';
-          return (fd);
-        }
-    }
-  return (-1);
-
-#endif /* GRANTPT */
-
-#endif /* __sgi */
-
-}
-
-
-int
-ptys_open (int fdm, char *pts_name)
-{
-  int fds;
-
-#if !defined (HAVE_GRANTPT) && !defined (__sgi)
-
-  chmod (pts_name, S_IRUSR | S_IWUSR);
-  chown (pts_name, getuid (), -1);
-
-#endif
-
-  if ((fds = open (pts_name, O_RDWR)) < 0)
-    {
-      close (fdm);
-      return (-1);
-    }
-
-#ifdef HAVE_GRANTPT
-  /* I intentionally ignore these errors */
-  ioctl (fds, I_PUSH, "ptem");
-  ioctl (fds, I_PUSH, "ldterm");
-  ioctl (fds, I_PUSH, "ttcompat");
-#endif
-
-#if !defined(HAVE_GRANTPT) && !defined (__sgi) && defined(TIOCSCTTY) && !defined(CIBAUD)
-
-  if (ioctl (fds, TIOCSCTTY, (char *) 0) < 0)
-    {
-      close (fdm);
-      return (-1);
-    }
-
-#endif
-
-  return (fds);
-}
-
-
-int
-tty_raw (int fd)
-{
-  struct termios buf;
-
-  if (tcgetattr (fd, &buf) < 0)
-    return (-1);
-
-  buf.c_iflag |= IGNPAR;
-  buf.c_iflag &= ~(ICRNL | ISTRIP | IXON | IGNCR | IXANY | IXOFF | INLCR);
-  buf.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL);
-#ifdef IEXTEN
-  buf.c_lflag &= ~(IEXTEN);
-#endif
-
-  buf.c_oflag &= ~(OPOST);
-  buf.c_cc[VMIN] = 1;
-  buf.c_cc[VTIME] = 0;
-
-  if (tcsetattr (fd, TCSADRAIN, &buf) < 0)
-    return (-1);
-  return (0);
-}
-
-
 static gint
 gftp_file_sort_function_as (gconstpointer a, gconstpointer b)
 {
--- a/lib/protocols.c	Fri Apr 25 12:53:23 2003 +0000
+++ b/lib/protocols.c	Sat Apr 26 15:26:42 2003 +0000
@@ -775,7 +775,7 @@
 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
   memset (&hints, 0, sizeof (hints));
   hints.ai_flags = AI_CANONNAME;
-  hints.ai_family = AF_INET;
+  hints.ai_family = PF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
 
   port = request->use_proxy ? proxy_port : request->port;
@@ -1575,7 +1575,7 @@
 
   memset (&hints, 0, sizeof (hints));
   hints.ai_flags = AI_CANONNAME;
-  hints.ai_family = AF_INET;
+  hints.ai_family = PF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
 
   if (request->use_proxy)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/pty.c	Sat Apr 26 15:26:42 2003 +0000
@@ -0,0 +1,176 @@
+/*****************************************************************************/
+/*  pty.c - general purpose routines                                         */
+/*  Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>                  */
+/*                                                                           */
+/*  This program is free software; you can redistribute it and/or modify     */
+/*  it under the terms of the GNU General Public License as published by     */
+/*  the Free Software Foundation; either version 2 of the License, or        */
+/*  (at your option) any later version.                                      */
+/*                                                                           */
+/*  This program is distributed in the hope that it will be useful,          */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
+/*  GNU General Public License for more details.                             */
+/*                                                                           */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program; if not, write to the Free Software              */
+/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
+/*****************************************************************************/
+
+static const char cvsid[] = "$Id$";
+
+#include "gftp.h"
+
+
+#ifdef __sgi
+
+int
+open_ptys (gftp_request * request, int *fdm, int *fds)
+{
+  char *pts_name;
+
+  if ((pts_name = _getpty (fdm, O_RDWR, 0600, 0)) == NULL)
+    return (GFTP_ERETRYABLE);
+
+  if ((*fds = open (pts_name, O_RDWR)) < 0)
+    {
+      close (*fdm);
+      return (GFTP_ERETRYABLE);
+    }
+
+  return (0);
+}
+
+#else /* !__sgi */
+
+#ifdef HAVE_GRANTPT
+
+int
+open_ptys (gftp_request * request, int *fdm, int *fds)
+{
+  char *pts_name;
+
+  if ((*fdm = open ("/dev/ptmx", O_RDWR)) < 0)
+    return (GFTP_ERETRYABLE);
+
+  if (grantpt (*fdm) < 0)
+    {
+      close (*fdm);
+      return (GFTP_ERETRYABLE);
+    }
+
+  if (unlockpt (*fdm) < 0)
+    {
+      close (*fdm);
+      return (GFTP_ERETRYABLE);
+    }
+
+  if ((pts_name = ptsname (*fdm)) == NULL)
+    {
+      close (*fdm);
+      return (GFTP_ERETRYABLE);
+    }
+
+  if ((*fds = open (pts_name, O_RDWR)) < 0)
+    {
+      close (*fdm);
+      return (GFTP_ERETRYABLE);
+    }
+
+  /* I intentionally ignore these errors */
+  ioctl (*fds, I_PUSH, "ptem");
+  ioctl (*fds, I_PUSH, "ldterm");
+  ioctl (*fds, I_PUSH, "ttcompat");
+
+  return (0);
+}
+
+#else /* !HAVE_GRANTPT */
+
+#ifdef HAVE_OPENPTY
+
+int
+open_ptys (gftp_request * request, int *fdm, int *fds)
+{
+  char *pts_name;
+
+  if (openpty (fdm, fds, &pts_name, NULL, NULL ) < 0)
+    return (GFTP_ERETRYABLE);
+
+  ioctl (*fds, TIOCSCTTY, NULL);
+
+  return (0);
+}
+
+#else /* !HAVE_OPENPTY */
+
+/* Fall back to *BSD... */
+
+int
+open_ptys (gftp_request * request, int *fdm, int *fds)
+{
+  char pts_name[20], *pos1, *pos2;
+
+  strncpy (pts_name, "/dev/ptyXY", sizeof (pts_name));
+  for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++) 
+    {
+      pts_name[8] = *pos1;
+      for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++)
+        {
+          pts_name[9] = *pos2;
+          if ((*fdm = open (pts_name, O_RDWR)) < 0)
+            continue;
+
+          pts_name[5] = 't';
+          chmod (pts_name, S_IRUSR | S_IWUSR);
+          chown (pts_name, getuid (), -1);
+
+          if ((*fds = open (pts_name, O_RDWR)) < 0)
+            {
+              pts_name[5] = 'p';
+              continue;
+            }
+
+#if defined(TIOCSCTTY) && !defined(CIBAUD)
+          ioctl (*fds, TIOCSCTTY, NULL);
+#endif
+
+          return (0);
+        }
+    }
+
+  return (GFTP_ERETRYABLE);
+}
+
+#endif /* HAVE_OPENPTY */
+
+#endif /* HAVE_GRANTPT */
+
+#endif /* __sgi */
+
+
+int
+tty_raw (int fd)
+{
+  struct termios buf;
+
+  if (tcgetattr (fd, &buf) < 0)
+    return (-1);
+
+  buf.c_iflag |= IGNPAR;
+  buf.c_iflag &= ~(ICRNL | ISTRIP | IXON | IGNCR | IXANY | IXOFF | INLCR);
+  buf.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL);
+#ifdef IEXTEN
+  buf.c_lflag &= ~(IEXTEN);
+#endif
+
+  buf.c_oflag &= ~(OPOST);
+  buf.c_cc[VMIN] = 1;
+  buf.c_cc[VTIME] = 0;
+
+  if (tcsetattr (fd, TCSADRAIN, &buf) < 0)
+    return (-1);
+  return (0);
+}
+
+
--- a/lib/rfc959.c	Fri Apr 25 12:53:23 2003 +0000
+++ b/lib/rfc959.c	Sat Apr 26 15:26:42 2003 +0000
@@ -562,7 +562,7 @@
 
 
 static int
-rfc959_data_connection_new (gftp_request * request)
+rfc959_ipv4_data_connection_new (gftp_request * request)
 {
   char *pos, *pos1, resp, *command;
   struct sockaddr_in data_addr;
@@ -571,10 +571,6 @@
   unsigned int temp[6];
   unsigned char ad[6];
 
-  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
-  g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL);
-  g_return_val_if_fail (request->sockfd > 0, GFTP_EFATAL);
-
   if ((request->datafd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
     {
       request->logging_function (gftp_logging_error, request->user_data,
@@ -597,7 +593,7 @@
             return (resp);
 
           gftp_set_request_option (request, "passive_transfer", GINT_TO_POINTER(0));
-	  return (rfc959_data_connection_new (request));
+	  return (rfc959_ipv4_data_connection_new (request));
 	}
 
       pos = request->last_ftp_response + 4;
@@ -700,11 +696,182 @@
 }
 
 
+#ifdef HAVE_IPV6
+
+static int
+rfc959_ipv6_data_connection_new (gftp_request * request)
+{
+  char *pos, resp, buf[64], *command;
+  struct sockaddr_in6 data_addr;
+  int passive_transfer;
+  size_t data_addr_len;
+  unsigned int port;
+
+  if ((request->datafd = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0)
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+				 _("Failed to create a socket: %s\n"),
+				 g_strerror (errno));
+      gftp_disconnect (request);
+      return (GFTP_ERETRYABLE);
+    }
+
+  data_addr_len = sizeof (data_addr);
+  /* This condition shouldn't happen. We better check anyway... */
+  if (data_addr_len != request->hostp->ai_addrlen) 
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+				 _("Error: It doesn't look like we are connected via IPv6. Aborting connection.\n"));
+      gftp_disconnect (request);
+      return (GFTP_EFATAL);
+    }
+
+  memset (&data_addr, 0, data_addr_len);
+  data_addr.sin6_family = AF_INET6;
+
+  gftp_lookup_request_option (request, "passive_transfer", &passive_transfer);
+  if (passive_transfer)
+    {
+      if ((resp = rfc959_send_command (request, "EPSV\r\n")) != '2')
+	{
+          if (request->sockfd < 0)
+            return (resp);
+
+          gftp_set_request_option (request, "passive_transfer", 
+                                   GINT_TO_POINTER(0));
+	  return (rfc959_ipv6_data_connection_new (request));
+	}
+
+      pos = request->last_ftp_response + 4;
+      while (*pos != '(' && *pos != '\0')
+        pos++;
+      pos++;
+
+      if (*pos == '\0')
+        {
+          request->logging_function (gftp_logging_error, request->user_data,
+                      _("Invalid EPSV response '%s'\n"),
+                      request->last_ftp_response);
+          gftp_disconnect (request);
+          return (GFTP_EFATAL);
+        }
+
+      if (sscanf (pos, "|||%d|", &port) != 1)
+        {
+          request->logging_function (gftp_logging_error, request->user_data,
+                      _("Invalid EPSV response '%s'\n"),
+                      request->last_ftp_response);
+          gftp_disconnect (request);
+          return (GFTP_EFATAL);
+        }
+
+      memcpy (&data_addr, request->hostp->ai_addr, data_addr_len);
+      data_addr.sin6_port = htons (port);
+
+      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);
+          return (GFTP_ERETRYABLE);
+	}
+    }
+  else
+    {
+      memcpy (&data_addr, request->hostp->ai_addr, data_addr_len);
+      data_addr.sin6_port = 0;
+
+      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);
+	  return (GFTP_ERETRYABLE);
+	}
+
+      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 (GFTP_ERETRYABLE);
+        }
+
+      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.sin6_port),
+				     g_strerror (errno));
+          gftp_disconnect (request);
+	  return (GFTP_ERETRYABLE);
+	}
+
+      if (inet_ntop (AF_INET6, &data_addr.sin6_addr, buf, sizeof (buf)) == NULL)
+        {
+          request->logging_function (gftp_logging_error, request->user_data,
+				     _("Cannot get address of local socket: %s\n"),
+				     g_strerror (errno));
+          gftp_disconnect (request);
+	  return (GFTP_ERETRYABLE);
+        }
+
+      command = g_strdup_printf ("EPRT |2|%s|%d|\n", buf,
+                                 ntohs (data_addr.sin6_port));
+
+      resp = rfc959_send_command (request, command);
+      g_free (command);
+      if (resp != '2')
+	{
+          gftp_disconnect (request);
+	  return (GFTP_ERETRYABLE);
+	}
+    }
+
+  return (0);
+}
+
+#endif /* HAVE_IPV6 */
+
+
+static int
+rfc959_data_connection_new (gftp_request * request)
+{
+  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
+  g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL);
+  g_return_val_if_fail (request->sockfd > 0, GFTP_EFATAL);
+
+  if (GFTP_GET_AI_FAMILY(request) == AF_INET)
+    return (rfc959_ipv4_data_connection_new (request));
+#ifdef HAVE_IPV6
+  else
+    return (rfc959_ipv6_data_connection_new (request));
+#else /* Shouldn't happen */
+  else
+    {
+      request->logging_function (gftp_logging_error, request->user_data,
+				 _("Error: IPV6 support was not completely compiled in\n"));
+      return (GFTP_EFATAL);
+    }
+#endif
+}
+
+
 static int
 rfc959_accept_active_connection (gftp_request * request)
 {
   int infd, ret, passive_transfer;
+#ifdef HAVE_IPV6
   struct sockaddr_in cli_addr;
+#else
+  struct sockaddr_in6 cli_addr;
+#endif
   size_t cli_addr_len;
 
   g_return_val_if_fail (request != NULL, GFTP_EFATAL);
--- a/lib/sshv2.c	Fri Apr 25 12:53:23 2003 +0000
+++ b/lib/sshv2.c	Sat Apr 26 15:26:42 2003 +0000
@@ -286,7 +286,7 @@
       diff += rd;
       tempstr[diff] = '\0'; 
 
-      if (diff > 11 && strcmp (tempstr + diff - 10, "password: ") == 0)
+      if (diff >= 10 && strcmp (tempstr + diff - 9, "assword: ") == 0)
         {
           if (wrotepw)
             {
@@ -813,8 +813,8 @@
 static int
 sshv2_connect (gftp_request * request)
 {
-  int version, fdm, fds, s[2], ret, ssh_use_askpass, sshv2_use_sftp_subsys;
-  char **args, *tempstr, pts_name[20], *p1, p2, *exepath, *ssh2_sftp_path;
+  int version, s[2], ret, ssh_use_askpass, sshv2_use_sftp_subsys;
+  char **args, *tempstr, *p1, p2, *exepath, *ssh2_sftp_path;
   struct servent serv_struct;
   sshv2_message message;
   pid_t child;
@@ -868,7 +868,6 @@
 
   if (ssh_use_askpass || sshv2_use_sftp_subsys)
     {
-      fdm = fds = 0;
       if (socketpair (AF_LOCAL, SOCK_STREAM, 0, s) < 0)
         {
           request->logging_function (gftp_logging_error, request->user_data,
@@ -879,41 +878,19 @@
     }
   else
     {
-      s[0] = s[1] = 0;
-      if ((fdm = ptym_open (pts_name, sizeof (pts_name))) < 0)
-        {
-          request->logging_function (gftp_logging_error, request->user_data,
-                                _("Cannot open master pty %s: %s\n"), pts_name,
-                                g_strerror (errno));
-          return (GFTP_ERETRYABLE);
-        }
+      if ((ret = open_ptys (request, &s[0], &s[1])) < 0)
+        return (ret);
     }
  
   if ((child = fork ()) == 0)
     {
       setsid ();
-      if (ssh_use_askpass || sshv2_use_sftp_subsys)
-        {
-          close (s[0]);
-          fds = s[1];
-        }
-      else
-        {
-          if ((fds = ptys_open (fdm, pts_name)) < 0)
-            {
-              printf ("Cannot open slave pts %s: %s\n", pts_name, 
-                      g_strerror (errno));
-              return (GFTP_ERETRYABLE);
-            }
-          close (fdm);
-        }
+      close (s[0]);
 
-      tty_raw (fds);
-      dup2 (fds, 0);
-      dup2 (fds, 1);
-      dup2 (fds, 2);
-      if (!ssh_use_askpass && fds > 2)
-        close (fds);
+      tty_raw (s[1]);
+      dup2 (s[1], 0);
+      dup2 (s[1], 1);
+      dup2 (s[1], 2);
       execvp (args[0], args);
 
       printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno));
@@ -921,15 +898,12 @@
     }
   else if (child > 0)
     {
-      if (ssh_use_askpass || sshv2_use_sftp_subsys)
-        {
-          close (s[1]);
-          fdm = s[0];
-        }
-      tty_raw (fdm);
+      close (s[1]);
+      tty_raw (s[0]);
+
       if (!sshv2_use_sftp_subsys)
         {
-          tempstr = sshv2_start_login_sequence (request, fdm);
+          tempstr = sshv2_start_login_sequence (request, s[0]);
           if (!tempstr ||
               !(strlen (tempstr) > 4 && strcmp (tempstr + strlen (tempstr) - 5,
                                                 "xsftp") == 0))
@@ -943,7 +917,7 @@
       sshv2_free_args (args);
       g_free (exepath);
 
-      request->sockfd = fdm;
+      request->sockfd = s[0];
 
       version = htonl (SSH_MY_VERSION);
       if ((ret = sshv2_send_command (request, SSH_FXP_INIT, (char *) 
--- a/po/POTFILES.in	Fri Apr 25 12:53:23 2003 +0000
+++ b/po/POTFILES.in	Sat Apr 26 15:26:42 2003 +0000
@@ -6,6 +6,7 @@
 lib/misc.c
 lib/options.h
 lib/protocols.c
+lib/pty.c
 lib/rfc2068.c
 lib/rfc959.c
 lib/sshv2.c