32d84ada85
- Backport FTP and Computer backend patches from master
102 lines
4.0 KiB
Diff
102 lines
4.0 KiB
Diff
From 19a6bf345fdb8d445e4c3683e4ca0af0a0031f0b Mon Sep 17 00:00:00 2001
|
|
From: Benjamin Otte <otte@gnome.org>
|
|
Date: Tue, 16 Jun 2009 11:16:27 +0200
|
|
Subject: [PATCH 05/13] [FTP] add EPRT support
|
|
|
|
The code does not support some corner cases that are listed in the RFC
|
|
(see inline comments), but I suspect those will never be hit. We can add
|
|
those when they are hit.
|
|
---
|
|
daemon/gvfsftptask.c | 60 ++++++++++++++++++++++++++++++++++++++++++++-----
|
|
1 files changed, 53 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
|
|
index 318dde4..9cab5a8 100644
|
|
--- a/daemon/gvfsftptask.c
|
|
+++ b/daemon/gvfsftptask.c
|
|
@@ -876,7 +876,52 @@ g_vfs_ftp_task_setup_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod meth
|
|
}
|
|
|
|
static GVfsFtpMethod
|
|
-g_vfs_ftp_task_open_data_connection_port (GVfsFtpTask *task, GVfsFtpMethod unused)
|
|
+g_vfs_ftp_task_setup_data_connection_eprt (GVfsFtpTask *task, GVfsFtpMethod unused)
|
|
+{
|
|
+ GSocketAddress *addr;
|
|
+ guint status, port, family;
|
|
+ char *ip_string;
|
|
+
|
|
+ /* workaround for the task not having a connection yet */
|
|
+ if (task->conn == NULL &&
|
|
+ g_vfs_ftp_task_send (task, 0, "NOOP") == 0)
|
|
+ return G_VFS_FTP_METHOD_ANY;
|
|
+
|
|
+ addr = g_vfs_ftp_connection_listen_data_connection (task->conn, &task->error);
|
|
+ if (addr == NULL)
|
|
+ return G_VFS_FTP_METHOD_ANY;
|
|
+ switch (g_socket_address_get_family (addr))
|
|
+ {
|
|
+ case G_SOCKET_FAMILY_IPV4:
|
|
+ family = 1;
|
|
+ break;
|
|
+ case G_SOCKET_FAMILY_IPV6:
|
|
+ family = 2;
|
|
+ break;
|
|
+ default:
|
|
+ g_object_unref (addr);
|
|
+ return G_VFS_FTP_METHOD_ANY;
|
|
+ }
|
|
+
|
|
+ ip_string = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr)));
|
|
+ /* if this ever happens (and it must not for IP4 and IP6 addresses),
|
|
+ * we need to add support for using a different separator */
|
|
+ g_assert (strchr (ip_string, '|') == NULL);
|
|
+ port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
|
|
+
|
|
+ /* we could handle the 522 response here, (unsupported network family),
|
|
+ * but I don't think that will buy us anything */
|
|
+ status = g_vfs_ftp_task_send (task, 0, "EPRT |%u|%s|%u|", family, ip_string, port);
|
|
+ g_free (ip_string);
|
|
+ g_object_unref (addr);
|
|
+ if (status == 0)
|
|
+ return G_VFS_FTP_METHOD_ANY;
|
|
+
|
|
+ return G_VFS_FTP_METHOD_EPRT;
|
|
+}
|
|
+
|
|
+static GVfsFtpMethod
|
|
+g_vfs_ftp_task_setup_data_connection_port (GVfsFtpTask *task, GVfsFtpMethod unused)
|
|
{
|
|
GSocketAddress *addr;
|
|
guint status, i, port;
|
|
@@ -925,7 +970,8 @@ g_vfs_ftp_task_setup_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unuse
|
|
} funcs_ordered[] = {
|
|
{ G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_epsv },
|
|
{ 0, g_vfs_ftp_task_setup_data_connection_pasv },
|
|
- { 0, g_vfs_ftp_task_open_data_connection_port }
|
|
+ { G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_eprt },
|
|
+ { 0, g_vfs_ftp_task_setup_data_connection_port }
|
|
};
|
|
GVfsFtpMethod method;
|
|
guint i;
|
|
@@ -974,12 +1020,12 @@ void
|
|
g_vfs_ftp_task_setup_data_connection (GVfsFtpTask *task)
|
|
{
|
|
static const GVfsFtpOpenDataConnectionFunc connect_funcs[] = {
|
|
- [G_VFS_FTP_METHOD_ANY] = g_vfs_ftp_task_setup_data_connection_any,
|
|
- [G_VFS_FTP_METHOD_EPSV] = g_vfs_ftp_task_setup_data_connection_epsv,
|
|
- [G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_setup_data_connection_pasv,
|
|
+ [G_VFS_FTP_METHOD_ANY] = g_vfs_ftp_task_setup_data_connection_any,
|
|
+ [G_VFS_FTP_METHOD_EPSV] = g_vfs_ftp_task_setup_data_connection_epsv,
|
|
+ [G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_setup_data_connection_pasv,
|
|
[G_VFS_FTP_METHOD_PASV_ADDR] = g_vfs_ftp_task_setup_data_connection_pasv,
|
|
- [G_VFS_FTP_METHOD_EPRT] = NULL,
|
|
- [G_VFS_FTP_METHOD_PORT] = g_vfs_ftp_task_open_data_connection_port
|
|
+ [G_VFS_FTP_METHOD_EPRT] = g_vfs_ftp_task_setup_data_connection_eprt,
|
|
+ [G_VFS_FTP_METHOD_PORT] = g_vfs_ftp_task_setup_data_connection_port
|
|
};
|
|
GVfsFtpMethod method, result;
|
|
|
|
--
|
|
1.6.3.2
|
|
|