From 7f2ac23d150aa779310a37534fc8564bbfc93b86 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 15 Jun 2009 22:02:34 +0200 Subject: [PATCH 01/13] [FTP] prepare the code for active FTP support adds a bunch of new APIs necessary for supporting active FTP. These APIs don't do anything yet, as active FTP is still unsupported, it's just refactoring of code. --- daemon/gvfsbackendftp.c | 11 +++++++-- daemon/gvfsftpdircache.c | 4 +- daemon/gvfsftptask.c | 47 ++++++++++++++++++++++++++++++++------------- daemon/gvfsftptask.h | 1 + 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c index ba6acd4..913eb1c 100644 --- a/daemon/gvfsbackendftp.c +++ b/daemon/gvfsbackendftp.c @@ -642,7 +642,7 @@ do_open_for_read (GVfsBackend *backend, error_550_permission_or_not_found, NULL }; - g_vfs_ftp_task_open_data_connection (&task); + g_vfs_ftp_task_setup_data_connection (&task); file = g_vfs_ftp_file_new_from_gvfs (ftp, filename); g_vfs_ftp_task_send_and_check (&task, @@ -653,6 +653,8 @@ do_open_for_read (GVfsBackend *backend, "RETR %s", g_vfs_ftp_file_get_ftp_path (file)); g_vfs_ftp_file_free (file); + g_vfs_ftp_task_open_data_connection (&task); + if (!g_vfs_ftp_task_is_in_error (&task)) { /* don't push the connection back, it's our handle now */ @@ -722,7 +724,7 @@ do_start_write (GVfsFtpTask *task, /* FIXME: can we honour the flags? */ - g_vfs_ftp_task_open_data_connection (task); + g_vfs_ftp_task_setup_data_connection (task); va_start (varargs, format); g_vfs_ftp_task_sendv (task, @@ -732,6 +734,8 @@ do_start_write (GVfsFtpTask *task, varargs); va_end (varargs); + g_vfs_ftp_task_open_data_connection (task); + if (!g_vfs_ftp_task_is_in_error (task)) { /* don't push the connection back, it's our handle now */ @@ -1280,13 +1284,14 @@ do_pull (GVfsBackend * backend, } else total_size = 0; - g_vfs_ftp_task_open_data_connection (&task); + g_vfs_ftp_task_setup_data_connection (&task); g_vfs_ftp_task_send_and_check (&task, G_VFS_FTP_PASS_100 | G_VFS_FTP_FAIL_200, &open_read_handlers[0], src, NULL, "RETR %s", g_vfs_ftp_file_get_ftp_path (src)); + g_vfs_ftp_task_open_data_connection (&task); if (g_vfs_ftp_task_is_in_error (&task)) { g_vfs_ftp_file_free (src); diff --git a/daemon/gvfsftpdircache.c b/daemon/gvfsftpdircache.c index 26984f4..8e6de25 100644 --- a/daemon/gvfsftpdircache.c +++ b/daemon/gvfsftpdircache.c @@ -153,11 +153,11 @@ g_vfs_ftp_dir_cache_lookup_entry (GVfsFtpDirCache * cache, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, _("The file is not a directory")); } - g_vfs_ftp_task_open_data_connection (task); - + g_vfs_ftp_task_setup_data_connection (task); g_vfs_ftp_task_send (task, G_VFS_FTP_PASS_100 | G_VFS_FTP_FAIL_200, "%s", cache->funcs->command); + g_vfs_ftp_task_open_data_connection (task); if (g_vfs_ftp_task_is_in_error (task)) return NULL; diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c index 118f80d..37f2b59 100644 --- a/daemon/gvfsftptask.c +++ b/daemon/gvfsftptask.c @@ -747,7 +747,7 @@ g_vfs_ftp_task_create_remote_address (GVfsFtpTask *task, guint port) } static GVfsFtpMethod -g_vfs_ftp_task_open_data_connection_epsv (GVfsFtpTask *task, GVfsFtpMethod method) +g_vfs_ftp_task_setup_data_connection_epsv (GVfsFtpTask *task, GVfsFtpMethod method) { const char *s; char **reply; @@ -790,7 +790,7 @@ fail: } static GVfsFtpMethod -g_vfs_ftp_task_open_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod method) +g_vfs_ftp_task_setup_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod method) { guint ip1, ip2, ip3, ip4, port1, port2; char **reply; @@ -875,14 +875,14 @@ g_vfs_ftp_task_open_data_connection_pasv (GVfsFtpTask *task, GVfsFtpMethod metho typedef GVfsFtpMethod (* GVfsFtpOpenDataConnectionFunc) (GVfsFtpTask *task, GVfsFtpMethod method); static GVfsFtpMethod -g_vfs_ftp_task_open_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unused) +g_vfs_ftp_task_setup_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unused) { static const struct { GVfsFtpFeature required_feature; GVfsFtpOpenDataConnectionFunc func; } funcs_ordered[] = { - { G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_open_data_connection_epsv }, - { 0, g_vfs_ftp_task_open_data_connection_pasv } + { G_VFS_FTP_FEATURE_EPSV, g_vfs_ftp_task_setup_data_connection_epsv }, + { 0, g_vfs_ftp_task_setup_data_connection_pasv } }; GVfsFtpMethod method; guint i; @@ -918,20 +918,23 @@ g_vfs_ftp_task_open_data_connection_any (GVfsFtpTask *task, GVfsFtpMethod unused } /** - * g_vfs_ftp_task_open_data_connection: + * g_vfs_ftp_task_setup_data_connection: * @task: a task not having an open data connection * - * Tries to open a data connection to the ftp server. If the operation fails, - * @task will be set into an error state. + * Sets up a data connection to the ftp server with using the best method for + * this task. If the operation fails, @task will be set into an error state. + * You must call g_vfs_ftp_task_open_data_connection() to finish setup and + * ensure the data connection actually gets opened. Usually, this requires + * sending an FTP command down the stream. **/ void -g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task) +g_vfs_ftp_task_setup_data_connection (GVfsFtpTask *task) { static const GVfsFtpOpenDataConnectionFunc connect_funcs[] = { - [G_VFS_FTP_METHOD_ANY] = g_vfs_ftp_task_open_data_connection_any, - [G_VFS_FTP_METHOD_EPSV] = g_vfs_ftp_task_open_data_connection_epsv, - [G_VFS_FTP_METHOD_PASV] = g_vfs_ftp_task_open_data_connection_pasv, - [G_VFS_FTP_METHOD_PASV_ADDR] = g_vfs_ftp_task_open_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] = NULL }; @@ -953,7 +956,7 @@ g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task) if (result == G_VFS_FTP_METHOD_ANY && method != G_VFS_FTP_METHOD_ANY && !g_vfs_ftp_task_is_in_error (task)) - result = g_vfs_ftp_task_open_data_connection_any (task, G_VFS_FTP_METHOD_ANY); + result = g_vfs_ftp_task_setup_data_connection_any (task, G_VFS_FTP_METHOD_ANY); g_assert (result < G_N_ELEMENTS (connect_funcs) && connect_funcs[result]); if (result != method) @@ -972,3 +975,19 @@ g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task) } } +/** + * g_vfs_ftp_task_open_data_connection: + * @task: a task + * + * Tries to open a data connection to the ftp server. If the operation fails, + * @task will be set into an error state. + **/ +void +g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task) +{ + g_return_if_fail (task != NULL); + + if (g_vfs_ftp_task_is_in_error (task)) + return; +} + diff --git a/daemon/gvfsftptask.h b/daemon/gvfsftptask.h index 6453f41..8345535 100644 --- a/daemon/gvfsftptask.h +++ b/daemon/gvfsftptask.h @@ -82,6 +82,7 @@ guint g_vfs_ftp_task_sendv (GVfsFtpTask * guint g_vfs_ftp_task_receive (GVfsFtpTask * task, GVfsFtpResponseFlags flags, char *** reply); +void g_vfs_ftp_task_setup_data_connection (GVfsFtpTask * task); void g_vfs_ftp_task_open_data_connection (GVfsFtpTask * task); void g_vfs_ftp_task_close_data_connection (GVfsFtpTask * task); -- 1.6.3.2