[PATCH 4/8] Restructure ..._ensure_data_connection and fall back on PASV when EPSV fails.
- From: Andreas Henriksson <andreas fatal se>
- To: gvfs-list gnome org
- Cc: Andreas Henriksson <andreas fatal se>, Oliver <oliver joos schweiz org>, Benjamin Otte <otte gnome org>
- Subject: [PATCH 4/8] Restructure ..._ensure_data_connection and fall back on PASV when EPSV fails.
- Date: Sat, 15 Nov 2008 18:03:45 +0100
- split up ..._ensure_data_connection in subroutines
- make a full attempt to connect instead of relying on response
code from EPSV command.
- when EPSV data connection fails, try PASV.
---
daemon/gvfsbackendftp.c | 119 ++++++++++++++++++++++++++++++-----------------
1 files changed, 76 insertions(+), 43 deletions(-)
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
index 109b776..b05e164 100644
--- a/daemon/gvfsbackendftp.c
+++ b/daemon/gvfsbackendftp.c
@@ -779,42 +779,78 @@ ftp_connection_use (FtpConnection *conn)
}
static gboolean
-ftp_connection_ensure_data_connection (FtpConnection *conn)
+_ftp_connection_ensure_data_connection (FtpConnection *conn, SoupAddress *addr)
{
- guint ip1, ip2, ip3, ip4, port1, port2;
- SoupAddress *addr;
- const char *s;
- char *ip;
guint status;
- if (conn->features & FTP_FEATURE_EPSV)
+ conn->data = soup_socket_new ("non-blocking", FALSE,
+ "remote-address", addr,
+ "timeout", TIMEOUT_IN_SECONDS,
+ NULL);
+ g_object_unref (addr);
+ status = soup_socket_connect_sync (conn->data, conn->job->cancellable);
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status))
{
- status = ftp_connection_send (conn, RESPONSE_PASS_500, "EPSV");
- if (STATUS_GROUP (status) == 2)
- {
- s = strrchr (conn->read_buffer, '(');
- if (s)
- {
- guint port;
- s += 4;
- port = strtoul (s, NULL, 10);
- if (port != 0)
- {
- addr = soup_address_new (
+ /* FIXME: better error messages depending on status please */
+ g_set_error_literal (&conn->error,
+ G_IO_ERROR,
+ G_IO_ERROR_HOST_NOT_FOUND,
+ _("Could not connect to host"));
+ g_object_unref (conn->data);
+ conn->data = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+ftp_connection_ensure_data_connection_epsv (FtpConnection *conn)
+{
+ const char *s;
+ guint port;
+ SoupAddress *addr;
+ guint status;
+
+ if ((conn->features & FTP_FEATURE_EPSV) == 0)
+ return FALSE;
+
+ status = ftp_connection_send (conn, RESPONSE_PASS_500, "EPSV");
+ if (STATUS_GROUP (status) != 2)
+ return FALSE;
+
+ s = strrchr (conn->read_buffer, '(');
+ if (!s)
+ return FALSE;
+
+ s += 4;
+ port = strtoul (s, NULL, 10);
+ if (port == 0)
+ return FALSE;
+
+ addr = soup_address_new (
soup_address_get_name (soup_socket_get_remote_address (conn->commands)),
port);
- goto have_address;
- }
- }
- }
- }
+
+ return _ftp_connection_ensure_data_connection (conn, addr);
+}
+
+static gboolean
+ftp_connection_ensure_data_connection_pasv (FtpConnection *conn)
+{
+ guint ip1, ip2, ip3, ip4, port1, port2;
+ char *ip;
+ const char *s;
+ SoupAddress *addr;
+ guint status;
+
/* only binary transfers please */
status = ftp_connection_send (conn, 0, "PASV");
if (status == 0)
return FALSE;
/* parse response and try to find the address to connect to.
- * This code does the sameas curl.
+ * This code does the same as curl.
*/
for (s = conn->read_buffer; *s; s++)
{
@@ -829,30 +865,27 @@ ftp_connection_ensure_data_connection (FtpConnection *conn)
_("Invalid reply"));
return FALSE;
}
+
ip = g_strdup_printf ("%u.%u.%u.%u", ip1, ip2, ip3, ip4);
addr = soup_address_new (ip, port1 << 8 | port2);
g_free (ip);
-have_address:
- conn->data = soup_socket_new ("non-blocking", FALSE,
- "remote-address", addr,
- "timeout", TIMEOUT_IN_SECONDS,
- NULL);
- g_object_unref (addr);
- status = soup_socket_connect_sync (conn->data, conn->job->cancellable);
- if (!SOUP_STATUS_IS_SUCCESSFUL (status))
- {
- /* FIXME: better error messages depending on status please */
- g_set_error_literal (&conn->error,
- G_IO_ERROR,
- G_IO_ERROR_HOST_NOT_FOUND,
- _("Could not connect to host"));
- g_object_unref (conn->data);
- conn->data = NULL;
- return FALSE;
- }
+ return _ftp_connection_ensure_data_connection (conn, addr);
+}
- return TRUE;
+static gboolean
+ftp_connection_ensure_data_connection (FtpConnection *conn)
+{
+ if (ftp_connection_ensure_data_connection_epsv (conn))
+ return TRUE;
+
+ if (ftp_connection_in_error (conn))
+ return FALSE;
+
+ if (ftp_connection_ensure_data_connection_pasv (conn))
+ return TRUE;
+
+ return FALSE;
}
static void
--
1.5.6.5
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]