diff --git a/.gitignore b/.gitignore index 7d60f6d..7f7e500 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/gvfs-1.36.2.tar.xz +gvfs-1.54.4.tar.xz diff --git a/.gvfs.metadata b/.gvfs.metadata deleted file mode 100644 index 1ed6813..0000000 --- a/.gvfs.metadata +++ /dev/null @@ -1 +0,0 @@ -fb5fe05f0661da8c88f5fa41014bcd526ad39993 SOURCES/gvfs-1.36.2.tar.xz diff --git a/SOURCES/admin-Add-query_info_on_read-write-functionality.patch b/SOURCES/admin-Add-query_info_on_read-write-functionality.patch deleted file mode 100644 index b0a27e7..0000000 --- a/SOURCES/admin-Add-query_info_on_read-write-functionality.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 5cd76d627f4d1982b6e77a0e271ef9301732d09e Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Thu, 23 May 2019 10:24:36 +0200 -Subject: [PATCH] admin: Add query_info_on_read/write functionality - -Admin backend doesn't implement query_info_on_read/write which might -potentially lead to some race conditions which aren't really wanted -especially in case of admin backend. Let's add this missing functionality. ---- - daemon/gvfsbackendadmin.c | 79 +++++++++++++++++++++++++++++++++------ - 1 file changed, 67 insertions(+), 12 deletions(-) - -diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c -index 65a979e7..23d16f16 100644 ---- a/daemon/gvfsbackendadmin.c -+++ b/daemon/gvfsbackendadmin.c -@@ -42,6 +42,8 @@ - #include "gvfsjobopenforwrite.h" - #include "gvfsjobqueryattributes.h" - #include "gvfsjobqueryinfo.h" -+#include "gvfsjobqueryinforead.h" -+#include "gvfsjobqueryinfowrite.h" - #include "gvfsjobread.h" - #include "gvfsjobseekread.h" - #include "gvfsjobseekwrite.h" -@@ -155,6 +157,19 @@ complete_job (GVfsJob *job, - g_vfs_job_succeeded (job); - } - -+static void -+fix_file_info (GFileInfo *info) -+{ -+ /* Override read/write flags, since the above call will use access() -+ * to determine permissions, which does not honor our privileged -+ * capabilities. -+ */ -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE); -+} -+ - static void - do_query_info (GVfsBackend *backend, - GVfsJobQueryInfo *query_info_job, -@@ -180,19 +195,57 @@ do_query_info (GVfsBackend *backend, - if (error != NULL) - goto out; - -- /* Override read/write flags, since the above call will use access() -- * to determine permissions, which does not honor our privileged -- * capabilities. -- */ -- g_file_info_set_attribute_boolean (real_info, -- G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE); -- g_file_info_set_attribute_boolean (real_info, -- G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE); -- g_file_info_set_attribute_boolean (real_info, -- G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE); -- g_file_info_set_attribute_boolean (real_info, -- G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE); -+ fix_file_info (real_info); -+ g_file_info_copy_into (real_info, info); -+ g_object_unref (real_info); -+ -+ out: -+ complete_job (job, error); -+} -+ -+static void -+do_query_info_on_read (GVfsBackend *backend, -+ GVfsJobQueryInfoRead *query_info_job, -+ GVfsBackendHandle handle, -+ GFileInfo *info, -+ GFileAttributeMatcher *matcher) -+{ -+ GVfsJob *job = G_VFS_JOB (query_info_job); -+ GFileInputStream *stream = handle; -+ GError *error = NULL; -+ GFileInfo *real_info; -+ -+ real_info = g_file_input_stream_query_info (stream, query_info_job->attributes, -+ job->cancellable, &error); -+ if (error != NULL) -+ goto out; -+ -+ fix_file_info (real_info); -+ g_file_info_copy_into (real_info, info); -+ g_object_unref (real_info); -+ -+ out: -+ complete_job (job, error); -+} -+ -+static void -+do_query_info_on_write (GVfsBackend *backend, -+ GVfsJobQueryInfoWrite *query_info_job, -+ GVfsBackendHandle handle, -+ GFileInfo *info, -+ GFileAttributeMatcher *matcher) -+{ -+ GVfsJob *job = G_VFS_JOB (query_info_job); -+ GFileOutputStream *stream = handle; -+ GError *error = NULL; -+ GFileInfo *real_info; -+ -+ real_info = g_file_output_stream_query_info (stream, query_info_job->attributes, -+ job->cancellable, &error); -+ if (error != NULL) -+ goto out; - -+ fix_file_info (real_info); - g_file_info_copy_into (real_info, info); - g_object_unref (real_info); - -@@ -868,6 +921,8 @@ g_vfs_backend_admin_class_init (GVfsBackendAdminClass * klass) - backend_class->mount = do_mount; - backend_class->open_for_read = do_open_for_read; - backend_class->query_info = do_query_info; -+ backend_class->query_info_on_read = do_query_info_on_read; -+ backend_class->query_info_on_write = do_query_info_on_write; - backend_class->read = do_read; - backend_class->create = do_create; - backend_class->append_to = do_append_to; --- -2.23.0 - diff --git a/SOURCES/admin-Ensure-correct-ownership-when-moving-to-file-u.patch b/SOURCES/admin-Ensure-correct-ownership-when-moving-to-file-u.patch deleted file mode 100644 index f5e483a..0000000 --- a/SOURCES/admin-Ensure-correct-ownership-when-moving-to-file-u.patch +++ /dev/null @@ -1,80 +0,0 @@ -From d5dfd823c94045488aef8727c553f1e0f7666b90 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Fri, 24 May 2019 09:43:43 +0200 -Subject: [PATCH] admin: Ensure correct ownership when moving to file:// uri - -User and group is not restored properly when moving (or copying with -G_FILE_COPY_ALL_METADATA) from admin:// to file://, because it is handled -by GIO fallback code, which doesn't run with root permissions. Let's -handle this case with pull method to ensure correct ownership. ---- - daemon/gvfsbackendadmin.c | 46 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 46 insertions(+) - -diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c -index 32b51b1a..9a7e8295 100644 ---- a/daemon/gvfsbackendadmin.c -+++ b/daemon/gvfsbackendadmin.c -@@ -807,6 +807,51 @@ do_move (GVfsBackend *backend, - complete_job (job, error); - } - -+static void -+do_pull (GVfsBackend *backend, -+ GVfsJobPull *pull_job, -+ const char *source, -+ const char *local_path, -+ GFileCopyFlags flags, -+ gboolean remove_source, -+ GFileProgressCallback progress_callback, -+ gpointer progress_callback_data) -+{ -+ GVfsBackendAdmin *self = G_VFS_BACKEND_ADMIN (backend); -+ GVfsJob *job = G_VFS_JOB (pull_job); -+ GError *error = NULL; -+ GFile *src_file, *dst_file; -+ -+ /* Pull method is necessary when user/group needs to be restored, return -+ * G_IO_ERROR_NOT_SUPPORTED in other cases to proceed with the fallback code. -+ */ -+ if (!(flags & G_FILE_COPY_ALL_METADATA)) -+ { -+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, -+ G_IO_ERROR_NOT_SUPPORTED, -+ _("Operation not supported")); -+ return; -+ } -+ -+ if (!check_permission (self, job)) -+ return; -+ -+ src_file = g_file_new_for_path (source); -+ dst_file = g_file_new_for_path (local_path); -+ -+ if (remove_source) -+ g_file_move (src_file, dst_file, flags, job->cancellable, -+ progress_callback, progress_callback_data, &error); -+ else -+ g_file_copy (src_file, dst_file, flags, job->cancellable, -+ progress_callback, progress_callback_data, &error); -+ -+ g_object_unref (src_file); -+ g_object_unref (dst_file); -+ -+ complete_job (job, error); -+} -+ - static void - do_query_settable_attributes (GVfsBackend *backend, - GVfsJobQueryAttributes *query_job, -@@ -927,6 +972,7 @@ g_vfs_backend_admin_class_init (GVfsBackendAdminClass * klass) - backend_class->set_attribute = do_set_attribute; - backend_class->delete = do_delete; - backend_class->move = do_move; -+ backend_class->pull = do_pull; - backend_class->query_settable_attributes = do_query_settable_attributes; - backend_class->query_writable_namespaces = do_query_writable_namespaces; - } --- -2.23.0 - diff --git a/SOURCES/admin-Prevent-access-if-any-authentication-agent-isn.patch b/SOURCES/admin-Prevent-access-if-any-authentication-agent-isn.patch deleted file mode 100644 index 63b0c74..0000000 --- a/SOURCES/admin-Prevent-access-if-any-authentication-agent-isn.patch +++ /dev/null @@ -1,42 +0,0 @@ -From d8d0c8c40049cfd824b2b90d0cd47914052b9811 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 2 Jan 2019 17:13:27 +0100 -Subject: [PATCH] admin: Prevent access if any authentication agent isn't - available - -The backend currently allows to access and modify files without prompting -for password if any polkit authentication agent isn't available. This seems -isn't usually problem, because polkit agents are integral parts of -graphical environments / linux distributions. The agents can't be simply -disabled without root permissions and are automatically respawned. However, -this might be a problem in some non-standard cases. - -This affects only users which belong to wheel group (i.e. those who are -already allowed to use sudo). It doesn't allow privilege escalation for -users, who don't belong to that group. - -Let's return permission denied error also when the subject can't be -authorized by any polkit agent to prevent this behavior. - -Closes: https://gitlab.gnome.org/GNOME/gvfs/issues/355 ---- - daemon/gvfsbackendadmin.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c -index ec0f2392..0f849008 100644 ---- a/daemon/gvfsbackendadmin.c -+++ b/daemon/gvfsbackendadmin.c -@@ -130,8 +130,7 @@ check_permission (GVfsBackendAdmin *self, - return FALSE; - } - -- is_authorized = polkit_authorization_result_get_is_authorized (result) || -- polkit_authorization_result_get_is_challenge (result); -+ is_authorized = polkit_authorization_result_get_is_authorized (result); - - g_object_unref (result); - --- -2.20.1 - diff --git a/SOURCES/admin-Use-fsuid-to-ensure-correct-file-ownership.patch b/SOURCES/admin-Use-fsuid-to-ensure-correct-file-ownership.patch deleted file mode 100644 index a911d1d..0000000 --- a/SOURCES/admin-Use-fsuid-to-ensure-correct-file-ownership.patch +++ /dev/null @@ -1,87 +0,0 @@ -From d7d362995aa0cb8905c8d5c2a2a4c305d2ffff80 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Thu, 23 May 2019 10:33:30 +0200 -Subject: [PATCH] admin: Use fsuid to ensure correct file ownership - -Files created over admin backend should be owned by root, but they are -owned by the user itself. This is because the daemon drops the uid to -make dbus connection work. Use fsuid and euid to fix this issue. - -Closes: https://gitlab.gnome.org/GNOME/gvfs/issues/21 ---- - daemon/gvfsbackendadmin.c | 29 +++++++---------------------- - 1 file changed, 7 insertions(+), 22 deletions(-) - -diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c -index a74d09cf..32b51b1a 100644 ---- a/daemon/gvfsbackendadmin.c -+++ b/daemon/gvfsbackendadmin.c -@@ -157,19 +157,6 @@ complete_job (GVfsJob *job, - g_vfs_job_succeeded (job); - } - --static void --fix_file_info (GFileInfo *info) --{ -- /* Override read/write flags, since the above call will use access() -- * to determine permissions, which does not honor our privileged -- * capabilities. -- */ -- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE); -- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE); -- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE); -- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE); --} -- - static void - do_query_info (GVfsBackend *backend, - GVfsJobQueryInfo *query_info_job, -@@ -195,7 +182,6 @@ do_query_info (GVfsBackend *backend, - if (error != NULL) - goto out; - -- fix_file_info (real_info); - g_file_info_copy_into (real_info, info); - g_object_unref (real_info); - -@@ -220,7 +206,6 @@ do_query_info_on_read (GVfsBackend *backend, - if (error != NULL) - goto out; - -- fix_file_info (real_info); - g_file_info_copy_into (real_info, info); - g_object_unref (real_info); - -@@ -245,7 +230,6 @@ do_query_info_on_write (GVfsBackend *backend, - if (error != NULL) - goto out; - -- fix_file_info (real_info); - g_file_info_copy_into (real_info, info); - g_object_unref (real_info); - -@@ -977,14 +961,15 @@ acquire_caps (uid_t uid) - struct __user_cap_header_struct hdr; - struct __user_cap_data_struct data; - -- /* Tell kernel not clear capabilities when dropping root */ -- if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) -- g_error ("prctl(PR_SET_KEEPCAPS) failed"); -- -- /* Drop root uid, but retain the required permitted caps */ -- if (setuid (uid) < 0) -+ /* Set euid to user to make dbus work */ -+ if (seteuid (uid) < 0) - g_error ("unable to drop privs"); - -+ /* Set fsuid to still behave like root when working with files */ -+ setfsuid (0); -+ if (setfsuid (-1) != 0) -+ g_error ("setfsuid failed"); -+ - memset (&hdr, 0, sizeof(hdr)); - hdr.version = _LINUX_CAPABILITY_VERSION; - --- -2.23.0 - diff --git a/SOURCES/daemon-Handle-lockdown-option-to-disable-writing.patch b/SOURCES/daemon-Handle-lockdown-option-to-disable-writing.patch deleted file mode 100644 index 211c3ba..0000000 --- a/SOURCES/daemon-Handle-lockdown-option-to-disable-writing.patch +++ /dev/null @@ -1,385 +0,0 @@ -From af4d0d88604af7c196e461a743f2d1e81239d76a Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 14 May 2019 09:31:37 +0200 -Subject: [PATCH 2/3] daemon: Handle lockdown option to disable writing - -Handle the new mount-removable-storage-devices-as-read-only option of -org.gnome.desktop.lockdown schema and present AFC, MTP, GPhoto2 devices -as read-only if enabled. ---- - daemon/gvfsbackend.c | 62 ++++++++++++++++++++++++++++++++-- - daemon/gvfsbackend.h | 6 ++++ - daemon/gvfsbackendafc.c | 2 ++ - daemon/gvfsbackendgphoto2.c | 1 + - daemon/gvfsbackendmtp.c | 1 + - daemon/gvfsjobcopy.c | 7 ++++ - daemon/gvfsjobdelete.c | 7 ++++ - daemon/gvfsjobmakedirectory.c | 7 ++++ - daemon/gvfsjobmakesymlink.c | 7 ++++ - daemon/gvfsjobmove.c | 7 ++++ - daemon/gvfsjobopenforwrite.c | 7 ++++ - daemon/gvfsjobpush.c | 7 ++++ - daemon/gvfsjobqueryfsinfo.c | 11 ++---- - daemon/gvfsjobsetattribute.c | 7 ++++ - daemon/gvfsjobsetdisplayname.c | 7 ++++ - daemon/gvfsjobtrash.c | 7 ++++ - 16 files changed, 143 insertions(+), 10 deletions(-) - -diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c -index 4fd3455c..599733ef 100644 ---- a/daemon/gvfsbackend.c -+++ b/daemon/gvfsbackend.c -@@ -80,6 +80,9 @@ struct _GVfsBackendPrivate - char *default_location; - GMountSpec *mount_spec; - gboolean block_requests; -+ -+ GSettings *lockdown_settings; -+ gboolean readonly_lockdown; - }; - - -@@ -155,7 +158,9 @@ g_vfs_backend_finalize (GObject *object) - g_free (backend->priv->default_location); - if (backend->priv->mount_spec) - g_mount_spec_unref (backend->priv->mount_spec); -- -+ -+ g_clear_object (&backend->priv->lockdown_settings); -+ - if (G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize) - (*G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize) (object); - } -@@ -587,7 +592,29 @@ g_vfs_backend_add_auto_info (GVfsBackend *backend, - g_file_attribute_matcher_matches (matcher, - G_FILE_ATTRIBUTE_THUMBNAILING_FAILED))) - get_thumbnail_attributes (uri, info); -- -+ -+ if (backend->priv->readonly_lockdown) -+ { -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, FALSE); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE); -+ } -+} -+ -+void -+g_vfs_backend_add_auto_fs_info (GVfsBackend *backend, -+ GFileAttributeMatcher *matcher, -+ GFileInfo *info) -+{ -+ const char *type; -+ -+ type = g_vfs_backend_get_backend_type (backend); -+ if (type) -+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_GVFS_BACKEND, type); -+ -+ if (backend->priv->readonly_lockdown) -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE); - } - - void -@@ -1047,3 +1074,34 @@ g_vfs_backend_force_unmount (GVfsBackend *backend) - (GAsyncReadyCallback) forced_unregister_mount_callback, - NULL); - } -+ -+static void -+lockdown_settings_changed (GSettings *settings, -+ gchar *key, -+ gpointer user_data) -+{ -+ GVfsBackend *backend = G_VFS_BACKEND (user_data); -+ -+ backend->priv->readonly_lockdown = g_settings_get_boolean (settings, -+ "mount-removable-storage-devices-as-read-only"); -+} -+ -+ -+void -+g_vfs_backend_handle_readonly_lockdown (GVfsBackend *backend) -+{ -+ backend->priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown"); -+ backend->priv->readonly_lockdown = g_settings_get_boolean (backend->priv->lockdown_settings, -+ "mount-removable-storage-devices-as-read-only"); -+ g_signal_connect_object (backend->priv->lockdown_settings, -+ "changed", -+ G_CALLBACK (lockdown_settings_changed), -+ backend, -+ 0); -+} -+ -+gboolean -+g_vfs_backend_get_readonly_lockdown (GVfsBackend *backend) -+{ -+ return backend->priv->readonly_lockdown; -+} -diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h -index 9c7476cf..431dd290 100644 ---- a/daemon/gvfsbackend.h -+++ b/daemon/gvfsbackend.h -@@ -516,6 +516,9 @@ void g_vfs_backend_add_auto_info (GVfsBackend - GFileAttributeMatcher *matcher, - GFileInfo *info, - const char *uri); -+void g_vfs_backend_add_auto_fs_info (GVfsBackend *backend, -+ GFileAttributeMatcher *matcher, -+ GFileInfo *info); - - void g_vfs_backend_set_block_requests (GVfsBackend *backend, - gboolean value); -@@ -534,6 +537,9 @@ gboolean g_vfs_backend_invocation_first_handler (GVfsDBusMount *object, - GDBusMethodInvocation *invocation, - GVfsBackend *backend); - -+void g_vfs_backend_handle_readonly_lockdown (GVfsBackend *backend); -+gboolean g_vfs_backend_get_readonly_lockdown (GVfsBackend *backend); -+ - G_END_DECLS - - #endif /* __G_VFS_BACKEND_H__ */ -diff --git a/daemon/gvfsbackendafc.c b/daemon/gvfsbackendafc.c -index b6e6a106..ce68aa45 100644 ---- a/daemon/gvfsbackendafc.c -+++ b/daemon/gvfsbackendafc.c -@@ -2760,6 +2760,8 @@ g_vfs_backend_afc_init (GVfsBackendAfc *self) - } - - g_mutex_init (&self->apps_lock); -+ -+ g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (self)); - } - - static void -diff --git a/daemon/gvfsbackendgphoto2.c b/daemon/gvfsbackendgphoto2.c -index 51e9a3bd..7e50194a 100644 ---- a/daemon/gvfsbackendgphoto2.c -+++ b/daemon/gvfsbackendgphoto2.c -@@ -614,6 +614,7 @@ g_vfs_backend_gphoto2_init (GVfsBackendGphoto2 *gphoto2_backend) - g_mutex_init (&gphoto2_backend->lock); - - g_vfs_backend_set_display_name (backend, "gphoto2"); -+ g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (backend)); - - mount_spec = g_mount_spec_new ("gphoto2"); - g_vfs_backend_set_mount_spec (backend, mount_spec); -diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c -index e3a25ef2..c4f1e855 100644 ---- a/daemon/gvfsbackendmtp.c -+++ b/daemon/gvfsbackendmtp.c -@@ -379,6 +379,7 @@ g_vfs_backend_mtp_init (GVfsBackendMtp *backend) - g_mutex_init (&backend->mutex); - g_vfs_backend_set_display_name (G_VFS_BACKEND (backend), "mtp"); - g_vfs_backend_set_icon_name (G_VFS_BACKEND (backend), "multimedia-player"); -+ g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (backend)); - - mount_spec = g_mount_spec_new ("mtp"); - g_vfs_backend_set_mount_spec (G_VFS_BACKEND (backend), mount_spec); -diff --git a/daemon/gvfsjobcopy.c b/daemon/gvfsjobcopy.c -index 785d7480..cf33da56 100644 ---- a/daemon/gvfsjobcopy.c -+++ b/daemon/gvfsjobcopy.c -@@ -141,6 +141,13 @@ try (GVfsJob *job) - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - gboolean res; - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_copy == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobdelete.c b/daemon/gvfsjobdelete.c -index 92892f15..8d5e5b8e 100644 ---- a/daemon/gvfsjobdelete.c -+++ b/daemon/gvfsjobdelete.c -@@ -120,6 +120,13 @@ try (GVfsJob *job) - GVfsJobDelete *op_job = G_VFS_JOB_DELETE (job); - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_delete == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobmakedirectory.c b/daemon/gvfsjobmakedirectory.c -index 98bb28d5..56a9c42a 100644 ---- a/daemon/gvfsjobmakedirectory.c -+++ b/daemon/gvfsjobmakedirectory.c -@@ -120,6 +120,13 @@ try (GVfsJob *job) - GVfsJobMakeDirectory *op_job = G_VFS_JOB_MAKE_DIRECTORY (job); - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_make_directory == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobmakesymlink.c b/daemon/gvfsjobmakesymlink.c -index 2c55e26b..2684b6fd 100644 ---- a/daemon/gvfsjobmakesymlink.c -+++ b/daemon/gvfsjobmakesymlink.c -@@ -124,6 +124,13 @@ try (GVfsJob *job) - GVfsJobMakeSymlink *op_job = G_VFS_JOB_MAKE_SYMLINK (job); - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_make_symlink == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobmove.c b/daemon/gvfsjobmove.c -index cc4ad220..5903d17a 100644 ---- a/daemon/gvfsjobmove.c -+++ b/daemon/gvfsjobmove.c -@@ -141,6 +141,13 @@ try (GVfsJob *job) - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - gboolean res; - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_move == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobopenforwrite.c b/daemon/gvfsjobopenforwrite.c -index 68eae532..60ce64f9 100644 ---- a/daemon/gvfsjobopenforwrite.c -+++ b/daemon/gvfsjobopenforwrite.c -@@ -230,6 +230,13 @@ try (GVfsJob *job) - GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job); - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (op_job->mode == OPEN_FOR_WRITE_CREATE) - { - if (class->try_create == NULL) -diff --git a/daemon/gvfsjobpush.c b/daemon/gvfsjobpush.c -index d7e48d86..a8df73a8 100644 ---- a/daemon/gvfsjobpush.c -+++ b/daemon/gvfsjobpush.c -@@ -146,6 +146,13 @@ try (GVfsJob *job) - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - gboolean res; - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_push == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobqueryfsinfo.c b/daemon/gvfsjobqueryfsinfo.c -index 898052ea..3363311a 100644 ---- a/daemon/gvfsjobqueryfsinfo.c -+++ b/daemon/gvfsjobqueryfsinfo.c -@@ -147,15 +147,10 @@ create_reply (GVfsJob *job, - GDBusMethodInvocation *invocation) - { - GVfsJobQueryFsInfo *op_job = G_VFS_JOB_QUERY_FS_INFO (job); -- const char *type; -- -- type = g_vfs_backend_get_backend_type (op_job->backend); -- -- if (type) -- g_file_info_set_attribute_string (op_job->file_info, -- G_FILE_ATTRIBUTE_GVFS_BACKEND, -- type); - -+ g_vfs_backend_add_auto_fs_info (op_job->backend, -+ op_job->attribute_matcher, -+ op_job->file_info); - g_file_info_set_attribute_mask (op_job->file_info, - op_job->attribute_matcher); - -diff --git a/daemon/gvfsjobsetattribute.c b/daemon/gvfsjobsetattribute.c -index 1efe7c94..ac7618a4 100644 ---- a/daemon/gvfsjobsetattribute.c -+++ b/daemon/gvfsjobsetattribute.c -@@ -146,6 +146,13 @@ try (GVfsJob *job) - GVfsJobSetAttribute *op_job = G_VFS_JOB_SET_ATTRIBUTE (job); - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_set_attribute == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobsetdisplayname.c b/daemon/gvfsjobsetdisplayname.c -index badb10dd..e12ae879 100644 ---- a/daemon/gvfsjobsetdisplayname.c -+++ b/daemon/gvfsjobsetdisplayname.c -@@ -124,6 +124,13 @@ try (GVfsJob *job) - GVfsJobSetDisplayName *op_job = G_VFS_JOB_SET_DISPLAY_NAME (job); - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_set_display_name == NULL) - return FALSE; - -diff --git a/daemon/gvfsjobtrash.c b/daemon/gvfsjobtrash.c -index 1738f8a2..5234ebf8 100644 ---- a/daemon/gvfsjobtrash.c -+++ b/daemon/gvfsjobtrash.c -@@ -119,6 +119,13 @@ try (GVfsJob *job) - GVfsJobTrash *op_job = G_VFS_JOB_TRASH (job); - GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); - -+ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) -+ { -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, -+ _("Filesystem is read-only")); -+ return TRUE; -+ } -+ - if (class->try_trash == NULL) - return FALSE; - --- -2.21.0 - diff --git a/SOURCES/daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch b/SOURCES/daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch deleted file mode 100644 index 305c7e5..0000000 --- a/SOURCES/daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 396216f71abf6907efd1383ca0d1a597918cd83d Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Thu, 11 Oct 2018 17:47:59 +0200 -Subject: [PATCH] daemon: Prevent spawning new daemons if outgoing operation - exists - -A new daemon is always spawned if MountLocation method (or LookupMount for -automounted) is called and the respective mount isn't registered yet. This -is not usually an issue, because the redundant daemons are consequently -terminated. However, this is a problem if mount operations hang for some reason. -This may happen e.g. with trash backend due to stale NFS mounts. Consequently, -new and new daemons are spawned which may lead to system failures due to lack -of system resources. See the following downstream bug report: -https://bugzilla.redhat.com/show_bug.cgi?id=1632960 - -Let's fix that behavior simply by preventing spawning of new daemons if -respective outgoing mount operations exist. - -https://gitlab.gnome.org/GNOME/gvfs/merge_requests/19 ---- - daemon/mount.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/daemon/mount.c b/daemon/mount.c -index e242666d..33cae597 100644 ---- a/daemon/mount.c -+++ b/daemon/mount.c -@@ -73,6 +73,7 @@ typedef void (*MountCallback) (VfsMountable *mountable, - - static GList *mountables = NULL; - static GList *mounts = NULL; -+static GList *ongoing = NULL; - - static gboolean fuse_available; - -@@ -253,6 +254,7 @@ typedef struct { - char *obj_path; - gboolean spawned; - GVfsDBusSpawner *spawner; -+ GList *pending; /* MountData */ - } MountData; - - static void spawn_mount (MountData *data); -@@ -264,6 +266,7 @@ mount_data_free (MountData *data) - g_mount_spec_unref (data->mount_spec); - g_free (data->obj_path); - g_clear_object (&data->spawner); -+ g_list_free_full (data->pending, (GDestroyNotify) mount_data_free); - - g_free (data); - } -@@ -271,7 +274,17 @@ mount_data_free (MountData *data) - static void - mount_finish (MountData *data, GError *error) - { -+ GList *l; -+ -+ ongoing = g_list_remove (ongoing, data); -+ - data->callback (data->mountable, error, data->user_data); -+ for (l = data->pending; l != NULL; l = l->next) -+ { -+ MountData *pending_data = l->data; -+ pending_data->callback (pending_data->mountable, error, pending_data->user_data); -+ } -+ - mount_data_free (data); - } - -@@ -493,6 +506,7 @@ mountable_mount (VfsMountable *mountable, - gpointer user_data) - { - MountData *data; -+ GList *l; - - data = g_new0 (MountData, 1); - data->automount = automount; -@@ -502,6 +516,18 @@ mountable_mount (VfsMountable *mountable, - data->callback = callback; - data->user_data = user_data; - -+ for (l = ongoing; l != NULL; l = l->next) -+ { -+ MountData *ongoing_data = l->data; -+ if (g_mount_spec_equal (ongoing_data->mount_spec, mount_spec)) -+ { -+ ongoing_data->pending = g_list_append (ongoing_data->pending, data); -+ return; -+ } -+ } -+ -+ ongoing = g_list_append (ongoing, data); -+ - if (mountable->dbus_name == NULL) - spawn_mount (data); - else --- -2.20.1 - diff --git a/SOURCES/goa-Add-support-for-certificate-prompts.patch b/SOURCES/goa-Add-support-for-certificate-prompts.patch deleted file mode 100644 index fef2e61..0000000 --- a/SOURCES/goa-Add-support-for-certificate-prompts.patch +++ /dev/null @@ -1,164 +0,0 @@ -From bbc95d6716ac491489f059c68a6dd258e38aee79 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Mon, 25 Nov 2019 16:53:31 +0100 -Subject: [PATCH] goa: Add support for certificate prompts - -Since commit f5ee590e, it is not possible to access Nextcloud/ownCloud -shares with self-signed (or invalid) certificates. This is because -the mount operation is handled by GOA volume monitor and the prompt -to accept certificate is not shown. Let's update the volume monitor -to handle just passwords and show the prompt to the client. - -Fixes: https://gitlab.gnome.org/GNOME/gvfs/issues/251 ---- - monitor/goa/goavolume.c | 98 ++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 96 insertions(+), 2 deletions(-) - -diff --git a/monitor/goa/goavolume.c b/monitor/goa/goavolume.c -index c077dd94..5e9097c6 100644 ---- a/monitor/goa/goavolume.c -+++ b/monitor/goa/goavolume.c -@@ -64,6 +64,7 @@ G_DEFINE_TYPE_EXTENDED (GVfsGoaVolume, g_vfs_goa_volume, G_TYPE_OBJECT, 0, - typedef struct - { - GMountOperation *mount_operation; -+ GMountOperation *mount_operation_orig; - gchar *passwd; - } MountOp; - -@@ -72,6 +73,13 @@ mount_op_free (MountOp *data) - { - g_clear_object (&data->mount_operation); - g_free (data->passwd); -+ -+ if (data->mount_operation_orig != NULL) -+ { -+ g_signal_handlers_disconnect_by_data (data->mount_operation_orig, data); -+ g_object_unref (data->mount_operation_orig); -+ } -+ - g_slice_free (MountOp, data); - } - -@@ -97,6 +105,88 @@ account_attention_needed_cb (GObject *_object, GParamSpec *pspec, gpointer user_ - - /* ---------------------------------------------------------------------------------------------------- */ - -+GType g_vfs_goa_mount_operation_get_type (void) G_GNUC_CONST; -+ -+typedef struct -+{ -+ GMountOperation parent_instance; -+} GVfsGoaMountOperation; -+ -+typedef struct -+{ -+ GMountOperationClass parent_class; -+} GVfsGoaMountOperationClass; -+ -+static GMountOperation * -+g_vfs_goa_mount_operation_new (void) -+{ -+ return G_MOUNT_OPERATION (g_object_new (g_vfs_goa_mount_operation_get_type (), NULL)); -+} -+ -+G_DEFINE_TYPE (GVfsGoaMountOperation, g_vfs_goa_mount_operation, G_TYPE_MOUNT_OPERATION) -+ -+static void -+g_vfs_goa_mount_operation_init (GVfsGoaMountOperation *mount_operation) -+{ -+} -+ -+static void -+g_vfs_goa_mount_operation_ask_question (GMountOperation *op, -+ const char *message, -+ const char *choices[]) -+{ -+ /* This is needed to prevent G_MOUNT_OPERATION_UNHANDLED reply in idle. */ -+} -+ -+static void -+g_vfs_goa_mount_operation_class_init (GVfsGoaMountOperationClass *klass) -+{ -+ GMountOperationClass *mount_op_class; -+ -+ mount_op_class = G_MOUNT_OPERATION_CLASS (klass); -+ mount_op_class->ask_question = g_vfs_goa_mount_operation_ask_question; -+} -+ -+/* ---------------------------------------------------------------------------------------------------- */ -+ -+static void -+ask_question_reply_cb (GMountOperation *op, -+ GMountOperationResult result, -+ gpointer user_data) -+{ -+ MountOp *data = g_task_get_task_data (user_data); -+ -+ g_mount_operation_set_choice (data->mount_operation, -+ g_mount_operation_get_choice (op)); -+ g_mount_operation_reply (data->mount_operation, result); -+} -+ -+static void -+mount_operation_ask_question_cb (GMountOperation *op, -+ gchar *message, -+ GStrv choices, -+ gpointer user_data) -+{ -+ MountOp *data = g_task_get_task_data (user_data); -+ -+ if (data->mount_operation_orig != NULL) -+ { -+ g_signal_connect (data->mount_operation_orig, -+ "reply", -+ G_CALLBACK (ask_question_reply_cb), -+ user_data); -+ g_signal_emit_by_name (data->mount_operation_orig, -+ "ask-question", -+ message, -+ choices); -+ } -+ else -+ { -+ g_mount_operation_reply (data->mount_operation, -+ G_MOUNT_OPERATION_UNHANDLED); -+ } -+} -+ - static void - mount_operation_ask_password_cb (GMountOperation *op, - gchar *message, -@@ -412,7 +502,7 @@ g_vfs_goa_volume_get_uuid (GVolume *_self) - static void - g_vfs_goa_volume_mount (GVolume *_self, - GMountMountFlags flags, -- GMountOperation *mount_operation, -+ GMountOperation *mount_operation_orig, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -@@ -423,6 +513,9 @@ g_vfs_goa_volume_mount (GVolume *_self, - GoaAccount *account; - - data = g_slice_new0 (MountOp); -+ if (mount_operation_orig != NULL) -+ data->mount_operation_orig = g_object_ref (mount_operation_orig); -+ - task = g_task_new (self, cancellable, callback, user_data); - g_task_set_source_tag (task, g_vfs_goa_volume_mount); - g_task_set_task_data (task, data, (GDestroyNotify) mount_op_free); -@@ -431,8 +524,9 @@ g_vfs_goa_volume_mount (GVolume *_self, - * monitor because it is set up to emit MountOpAskPassword on - * ask-password. - */ -- data->mount_operation = g_mount_operation_new (); -+ data->mount_operation = g_vfs_goa_mount_operation_new (); - g_signal_connect (data->mount_operation, "ask-password", G_CALLBACK (mount_operation_ask_password_cb), task); -+ g_signal_connect (data->mount_operation, "ask-question", G_CALLBACK (mount_operation_ask_question_cb), task); - - account = goa_object_peek_account (self->object); - goa_account_call_ensure_credentials (account, cancellable, ensure_credentials_cb, task); --- -2.28.0 - diff --git a/SOURCES/google-performance-fixes.patch b/SOURCES/google-performance-fixes.patch deleted file mode 100644 index 3225c59..0000000 --- a/SOURCES/google-performance-fixes.patch +++ /dev/null @@ -1,2724 +0,0 @@ -From ea26e6ddefca9b5f75f3d7485e420729bc038852 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 5 Jun 2018 13:04:15 +0200 -Subject: [PATCH 01/14] google: Do not create .desktop files for native files - -Currently, .desktop file with a link to the original location is provided, -when a native file is opened because Google doesn't provide its proprietary -formats and GLocalFile doesn't know G_FILE_TYPE_SHORTCUT. It is a bit -tricky and confusing, among other because the .desktop files aren't -automatically converted back to native files when writing. - -What is worse, Nautilus has dropped support for .desktop files recently, -so you see "There was an error launching the application." instead of the -requested file. It doesn't make more sense to provide this .desktop files, -so let's remove this fallback and return error instead. - -https://gitlab.gnome.org/GNOME/nautilus/issues/448 ---- - daemon/gvfsbackendgoogle.c | 68 ++++++++------------------------------ - 1 file changed, 13 insertions(+), 55 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 23bd8f58..7bea4bff 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -907,7 +907,6 @@ build_file_info (GVfsBackendGoogle *self, - gchar *escaped_name = NULL; - gchar *content_type = NULL; - gchar *copy_name = NULL; -- gchar *generated_copy_name = NULL; - gint64 atime; - gint64 ctime; - gint64 mtime; -@@ -1025,21 +1024,7 @@ build_file_info (GVfsBackendGoogle *self, - g_file_info_set_display_name (info, title); - g_file_info_set_edit_name (info, title); - -- generated_copy_name = generate_copy_name (self, entry); -- -- /* While copying remote Drive content to local storage, we want to -- * create Link-type desktop files because GLocalFile doesn't know -- * about shortcuts. That might change in future. -- */ -- if (file_type == G_FILE_TYPE_SHORTCUT) -- { -- copy_name = g_strconcat (generated_copy_name, ".desktop", NULL); -- } -- else -- { -- copy_name = generated_copy_name; -- generated_copy_name = NULL; -- } -+ copy_name = generate_copy_name (self, entry); - - /* Sanitize copy-name by replacing slashes with dashes. This is - * what nautilus does (for desktop files). -@@ -1097,7 +1082,6 @@ build_file_info (GVfsBackendGoogle *self, - - out: - g_free (copy_name); -- g_free (generated_copy_name); - g_free (escaped_name); - g_free (content_type); - g_list_free (links); -@@ -2249,6 +2233,8 @@ g_vfs_backend_google_open_for_read (GVfsBackend *_self, - GError *error; - gchar *content_type = NULL; - gchar *entry_path = NULL; -+ GDataAuthorizationDomain *auth_domain; -+ const gchar *uri; - - g_rec_mutex_lock (&self->mutex); - g_debug ("+ open_for_read: %s\n", filename); -@@ -2278,47 +2264,19 @@ g_vfs_backend_google_open_for_read (GVfsBackend *_self, - goto out; - } - -- /* While copying remote Drive content to local storage, we want to -- * create Link-type desktop files because GLocalFile doesn't know -- * about shortcuts. That might change in future. -- */ -- if (g_str_has_prefix (content_type, CONTENT_TYPE_PREFIX_GOOGLE)) -+ if (is_native_file (entry)) - { -- GDataLink *alternate; -- GKeyFile *file; -- const gchar *title; -- const gchar *uri; -- gchar *data; -- gsize length; -- -- file = g_key_file_new (); -- -- title = gdata_entry_get_title (entry); -- g_key_file_set_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, title); -- g_key_file_set_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TYPE, "Link"); -- -- alternate = gdata_entry_look_up_link (entry, GDATA_LINK_ALTERNATE); -- uri = gdata_link_get_uri (alternate); -- g_key_file_set_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_URL, uri); -- -- data = g_key_file_to_data (file, &length, NULL); -- stream = g_memory_input_stream_new_from_data (data, (gssize) length, g_free); -- -- g_key_file_free (file); -+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE, _("File is not a regular file")); -+ goto out; - } -- else -- { -- GDataAuthorizationDomain *auth_domain; -- const gchar *uri; - -- auth_domain = gdata_documents_service_get_primary_authorization_domain (); -- uri = gdata_entry_get_content_uri (entry); -- stream = gdata_download_stream_new (GDATA_SERVICE (self->service), auth_domain, uri, cancellable); -- if (stream == NULL) -- { -- g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED, _("Error getting data from file")); -- goto out; -- } -+ auth_domain = gdata_documents_service_get_primary_authorization_domain (); -+ uri = gdata_entry_get_content_uri (entry); -+ stream = gdata_download_stream_new (GDATA_SERVICE (self->service), auth_domain, uri, cancellable); -+ if (stream == NULL) -+ { -+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED, _("Error getting data from file")); -+ goto out; - } - - g_object_set_data_full (G_OBJECT (stream), "g-vfs-backend-google-entry", g_object_ref (entry), g_object_unref); --- -2.36.1 - - -From fec7d2162966c3574226564b62c6dd252bf4706f Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Mon, 23 Jul 2018 13:39:33 +0200 -Subject: [PATCH 02/14] google: Drop the (GDestroyNotify) cast - -"warning: function called through a non-compatible type" is printed -by GCC 8 because of (GDestroyNotfiy) cast in g_clear_pointer, see for -more info: https://gitlab.gnome.org/GNOME/glib/issues/1425. Let's -drop the (GDestroyNotify) cast in order to prevent those warnings. -The cast was not needed anyway. ---- - daemon/gvfsbackendgoogle.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 7bea4bff..2e96cca4 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -2866,8 +2866,8 @@ g_vfs_backend_google_dispose (GObject *_self) - g_clear_object (&self->service); - g_clear_object (&self->root); - g_clear_object (&self->client); -- g_clear_pointer (&self->entries, (GDestroyNotify) g_hash_table_unref); -- g_clear_pointer (&self->dir_entries, (GDestroyNotify) g_hash_table_unref); -+ g_clear_pointer (&self->entries, g_hash_table_unref); -+ g_clear_pointer (&self->dir_entries, g_hash_table_unref); - - G_OBJECT_CLASS (g_vfs_backend_google_parent_class)->dispose (_self); - } --- -2.36.1 - - -From 2d5fc426acb1bff385258d860ec97ff30242285d Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 1 Aug 2018 13:43:16 +0200 -Subject: [PATCH 03/14] google: Move debug prints before releasing entry - -Debug output contains mess because id and title are const gchar * -and are released together with GDataEntry on previous line. Let's -just swap the lines. ---- - daemon/gvfsbackendgoogle.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 2e96cca4..e157458b 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -510,13 +510,13 @@ remove_entry (GVfsBackendGoogle *self, - parent_id = get_parent_id (self, entry); - - k = dir_entries_key_new (id, parent_id); -- g_hash_table_remove (self->dir_entries, k); - g_debug (" remove_entry: Removed (%s, %s) -> %p\n", id, parent_id, entry); -+ g_hash_table_remove (self->dir_entries, k); - dir_entries_key_free (k); - - k = dir_entries_key_new (title, parent_id); -- g_hash_table_remove (self->dir_entries, k); - g_debug (" remove_entry: Removed (%s, %s) -> %p\n", title, parent_id, entry); -+ g_hash_table_remove (self->dir_entries, k); - dir_entries_key_free (k); - - for (l = self->dir_collisions; l != NULL; l = l->next) --- -2.36.1 - - -From b3f8db69522fdbdc965219e403da6e8e60997907 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 1 Aug 2018 13:44:59 +0200 -Subject: [PATCH 04/14] google: Remove also dir_collisions entries - -dir_collisions are not properly invalidated if removed entry is on this list. -Let's remove the entry also from this list. ---- - daemon/gvfsbackendgoogle.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index e157458b..e9eaec1f 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -519,6 +519,13 @@ remove_entry (GVfsBackendGoogle *self, - g_hash_table_remove (self->dir_entries, k); - dir_entries_key_free (k); - -+ l = g_list_find (self->dir_collisions, entry); -+ if (l != NULL) -+ { -+ self->dir_collisions = g_list_remove_link (self->dir_collisions, l); -+ g_object_unref (entry); -+ } -+ - for (l = self->dir_collisions; l != NULL; l = l->next) - { - GDataEntry *colliding_entry = GDATA_ENTRY (l->data); --- -2.36.1 - - -From ab007b1f3215a30c3ef49492cf22e6ef1383b0fd Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 31 Jul 2018 18:43:44 +0200 -Subject: [PATCH 05/14] google: Ignore entries without parents - -Entries without parents are not shown on the web and there isn't any -reason to list them here. Such entries belongs to some web services -and we have no control over them. ---- - daemon/gvfsbackendgoogle.c | 18 +----------------- - 1 file changed, 1 insertion(+), 17 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index e9eaec1f..897df61f 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -347,14 +347,6 @@ get_parent_id (GVfsBackendGoogle *self, - } - } - -- if (ret_val == NULL) -- { -- const gchar *root_id; -- -- root_id = gdata_entry_get_id (self->root); -- ret_val = g_strdup (root_id); -- } -- - g_list_free (links); - return ret_val; - } -@@ -903,10 +895,8 @@ build_file_info (GVfsBackendGoogle *self, - { - GFileType file_type; - GList *authors; -- GList *links; - gboolean is_folder = FALSE; - gboolean is_root = FALSE; -- gboolean has_parent = FALSE; - const gchar *etag; - const gchar *id; - const gchar *name; -@@ -925,9 +915,6 @@ build_file_info (GVfsBackendGoogle *self, - if (entry == self->root) - is_root = TRUE; - -- links = gdata_entry_look_up_links (entry, GDATA_LINK_PARENT); -- has_parent = (links != NULL); -- - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, !is_root); - - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, is_folder); -@@ -936,9 +923,7 @@ build_file_info (GVfsBackendGoogle *self, - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE, is_symlink); - - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE); -- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, !is_root && has_parent); -- -- g_file_info_set_is_hidden (info, !has_parent); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, !is_root); - - if (is_folder) - { -@@ -1091,7 +1076,6 @@ build_file_info (GVfsBackendGoogle *self, - g_free (copy_name); - g_free (escaped_name); - g_free (content_type); -- g_list_free (links); - } - - /* ---------------------------------------------------------------------------------------------------- */ --- -2.36.1 - - -From 631f794a4a660f49be9d30744e5c66a1f60da4de Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 31 Jul 2018 19:08:39 +0200 -Subject: [PATCH 06/14] google: Add support for files with multiple parents - -One entry can have multiple parents. You can create such entry on -the web in a pretty simple way, e.g. Ctrl + Drag&Drop. Such entries -are currently shown only on one place in the backend. Also the backend -rely on get_parent_id() and get_entry_path() functions which are tottaly -wrong. Let's introduce get_parent_ids() and resolve entry_path only -from given filename. ---- - daemon/gvfsbackendgoogle.c | 388 ++++++++++++++++--------------------- - 1 file changed, 168 insertions(+), 220 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 897df61f..7f812448 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -99,11 +99,13 @@ typedef struct - GDataEntry *document; - GDataUploadStream *stream; - gchar *filename; -+ gchar *entry_path; - } WriteHandle; - - static GDataEntry *resolve_dir (GVfsBackendGoogle *self, - const gchar *filename, - gchar **out_basename, -+ gchar **out_path, - GError **error); - - /* ---------------------------------------------------------------------------------------------------- */ -@@ -160,7 +162,7 @@ entries_in_folder_equal (gconstpointer a, gconstpointer b) - /* ---------------------------------------------------------------------------------------------------- */ - - static WriteHandle * --write_handle_new (GDataEntry *document, GDataUploadStream *stream, const gchar *filename) -+write_handle_new (GDataEntry *document, GDataUploadStream *stream, const gchar *filename, const gchar *entry_path) - { - WriteHandle *handle; - -@@ -177,6 +179,7 @@ write_handle_new (GDataEntry *document, GDataUploadStream *stream, const gchar * - } - - handle->filename = g_strdup (filename); -+ handle->entry_path = g_strdup (entry_path); - - return handle; - } -@@ -192,6 +195,7 @@ write_handle_free (gpointer data) - g_clear_object (&handle->document); - g_clear_object (&handle->stream); - g_free (handle->filename); -+ g_free (handle->entry_path); - g_slice_free (WriteHandle, handle); - } - -@@ -313,13 +317,13 @@ get_content_type_from_entry (GDataEntry *entry) - - /* ---------------------------------------------------------------------------------------------------- */ - --static gchar * --get_parent_id (GVfsBackendGoogle *self, -- GDataEntry *entry) -+static GList * -+get_parent_ids (GVfsBackendGoogle *self, -+ GDataEntry *entry) - { - GList *l; - GList *links = NULL; -- gchar *ret_val = NULL; -+ GList *ids = NULL; - - links = gdata_entry_look_up_links (entry, GDATA_LINK_PARENT); - for (l = links; l != NULL; l = l->next) -@@ -341,68 +345,13 @@ get_parent_id (GVfsBackendGoogle *self, - id = uri + uri_prefix_len; - if (id[0] != '\0') - { -- ret_val = g_strdup (uri + uri_prefix_len); -- break; -+ ids = g_list_prepend (ids, g_strdup (id)); - } - } - } - - g_list_free (links); -- return ret_val; --} -- --static gchar * --get_entry_path (GVfsBackendGoogle *self, GDataEntry *entry) --{ -- GString *path = NULL; -- const gchar *base_id; -- const gchar *root_id; -- gchar *id = NULL; -- gchar *ret_val = NULL; -- -- if (entry == self->root) -- { -- ret_val = g_strdup ("/"); -- goto out; -- } -- -- base_id = gdata_entry_get_id (entry); -- path = g_string_new (base_id); -- g_string_prepend_c (path, '/'); -- -- id = get_parent_id (self, entry); -- root_id = gdata_entry_get_id (self->root); -- -- while (id != NULL) -- { -- GDataEntry *parent_entry; -- -- /* The root folder itself has an ID, so path can become -- * /root/folder1/folder2/file. Instead, we want it to be -- * /folder1/folder2/file. -- */ -- -- if (g_strcmp0 (id, root_id) == 0) -- break; -- -- parent_entry = g_hash_table_lookup (self->entries, id); -- if (parent_entry == NULL) -- goto out; -- -- g_string_prepend (path, id); -- g_string_prepend_c (path, '/'); -- -- g_free (id); -- id = get_parent_id (self, parent_entry); -- } -- -- ret_val = g_strdup (path->str); -- -- out: -- g_free (id); -- if (path != NULL) -- g_string_free (path, TRUE); -- return ret_val; -+ return ids; - } - - /* ---------------------------------------------------------------------------------------------------- */ -@@ -418,62 +367,66 @@ insert_entry_full (GVfsBackendGoogle *self, - const gchar *id; - const gchar *old_id; - const gchar *title; -- gchar *parent_id; -+ GList *parent_ids, *l; - - id = gdata_entry_get_id (entry); - title = gdata_entry_get_title (entry); - - g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (entry)); - -- parent_id = get_parent_id (self, entry); -+ parent_ids = get_parent_ids (self, entry); -+ for (l = parent_ids; l != NULL; l = l->next) -+ { -+ gchar *parent_id = l->data; - -- k = dir_entries_key_new (id, parent_id); -- g_hash_table_insert (self->dir_entries, k, g_object_ref (entry)); -- g_debug (" insert_entry: Inserted (%s, %s) -> %p\n", id, parent_id, entry); -+ k = dir_entries_key_new (id, parent_id); -+ g_hash_table_insert (self->dir_entries, k, g_object_ref (entry)); -+ g_debug (" insert_entry: Inserted (%s, %s) -> %p\n", id, parent_id, entry); - -- k = dir_entries_key_new (title, parent_id); -- old_entry = g_hash_table_lookup (self->dir_entries, k); -- if (old_entry != NULL) -- { -- old_id = gdata_entry_get_id (old_entry); -- if (g_strcmp0 (old_id, title) == 0) -- { -- insert_title = FALSE; -- } -- else -+ k = dir_entries_key_new (title, parent_id); -+ old_entry = g_hash_table_lookup (self->dir_entries, k); -+ if (old_entry != NULL) - { -- /* If the collision is not due to the title matching the ID -- * of an earlier GDataEntry, then it is due to duplicate -- * titles. -- */ -- if (g_strcmp0 (old_id, id) < 0) -- insert_title = FALSE; -+ old_id = gdata_entry_get_id (old_entry); -+ if (g_strcmp0 (old_id, title) == 0) -+ { -+ insert_title = FALSE; -+ } -+ else -+ { -+ /* If the collision is not due to the title matching the ID -+ * of an earlier GDataEntry, then it is due to duplicate -+ * titles. -+ */ -+ if (g_strcmp0 (old_id, id) < 0) -+ insert_title = FALSE; -+ } - } -- } - -- if (insert_title) -- { -- if (old_entry != NULL && track_dir_collisions) -+ if (insert_title) - { -- self->dir_collisions = g_list_prepend (self->dir_collisions, g_object_ref (old_entry)); -- g_debug (" insert_entry: Ejected (%s, %s, %s) -> %p\n", old_id, title, parent_id, old_entry); -- } -+ if (old_entry != NULL && track_dir_collisions) -+ { -+ self->dir_collisions = g_list_prepend (self->dir_collisions, g_object_ref (old_entry)); -+ g_debug (" insert_entry: Ejected (%s, %s, %s) -> %p\n", old_id, title, parent_id, old_entry); -+ } - -- g_hash_table_insert (self->dir_entries, k, g_object_ref (entry)); -- g_debug (" insert_entry: Inserted (%s, %s) -> %p\n", title, parent_id, entry); -- } -- else -- { -- if (track_dir_collisions) -- { -- self->dir_collisions = g_list_prepend (self->dir_collisions, g_object_ref (entry)); -- g_debug (" insert_entry: Skipped (%s, %s, %s) -> %p\n", id, title, parent_id, entry); -+ g_hash_table_insert (self->dir_entries, k, g_object_ref (entry)); -+ g_debug (" insert_entry: Inserted (%s, %s) -> %p\n", title, parent_id, entry); - } -+ else -+ { -+ if (track_dir_collisions) -+ { -+ self->dir_collisions = g_list_prepend (self->dir_collisions, g_object_ref (entry)); -+ g_debug (" insert_entry: Skipped (%s, %s, %s) -> %p\n", id, title, parent_id, entry); -+ } - -- dir_entries_key_free (k); -+ dir_entries_key_free (k); -+ } - } -+ g_list_free_full (parent_ids, g_free); - -- g_free (parent_id); - return insert_title; - } - -@@ -492,47 +445,50 @@ remove_entry (GVfsBackendGoogle *self, - GList *l; - const gchar *id; - const gchar *title; -- gchar *parent_id; -+ GList *parent_ids, *ll; - - id = gdata_entry_get_id (entry); - title = gdata_entry_get_title (entry); - - g_hash_table_remove (self->entries, id); - -- parent_id = get_parent_id (self, entry); -- -- k = dir_entries_key_new (id, parent_id); -- g_debug (" remove_entry: Removed (%s, %s) -> %p\n", id, parent_id, entry); -- g_hash_table_remove (self->dir_entries, k); -- dir_entries_key_free (k); -- -- k = dir_entries_key_new (title, parent_id); -- g_debug (" remove_entry: Removed (%s, %s) -> %p\n", title, parent_id, entry); -- g_hash_table_remove (self->dir_entries, k); -- dir_entries_key_free (k); -- -- l = g_list_find (self->dir_collisions, entry); -- if (l != NULL) -+ parent_ids = get_parent_ids (self, entry); -+ for (ll = parent_ids; ll != NULL; ll = ll->next) - { -- self->dir_collisions = g_list_remove_link (self->dir_collisions, l); -- g_object_unref (entry); -- } -+ gchar *parent_id = ll->data; - -- for (l = self->dir_collisions; l != NULL; l = l->next) -- { -- GDataEntry *colliding_entry = GDATA_ENTRY (l->data); -+ k = dir_entries_key_new (id, parent_id); -+ g_debug (" remove_entry: Removed (%s, %s) -> %p\n", id, parent_id, entry); -+ g_hash_table_remove (self->dir_entries, k); -+ dir_entries_key_free (k); -+ -+ k = dir_entries_key_new (title, parent_id); -+ g_debug (" remove_entry: Removed (%s, %s) -> %p\n", title, parent_id, entry); -+ g_hash_table_remove (self->dir_entries, k); -+ dir_entries_key_free (k); - -- if (insert_entry_full (self, colliding_entry, FALSE)) -+ l = g_list_find (self->dir_collisions, entry); -+ if (l != NULL) - { - self->dir_collisions = g_list_remove_link (self->dir_collisions, l); -- g_debug (" remove_entry: Restored %p\n", colliding_entry); -- g_list_free (l); -- g_object_unref (colliding_entry); -- break; -+ g_object_unref (entry); - } -- } - -- g_free (parent_id); -+ for (l = self->dir_collisions; l != NULL; l = l->next) -+ { -+ GDataEntry *colliding_entry = GDATA_ENTRY (l->data); -+ -+ if (insert_entry_full (self, colliding_entry, FALSE)) -+ { -+ self->dir_collisions = g_list_remove_link (self->dir_collisions, l); -+ g_debug (" remove_entry: Restored %p\n", colliding_entry); -+ g_list_free (l); -+ g_object_unref (colliding_entry); -+ break; -+ } -+ } -+ } -+ g_list_free_full (parent_ids, g_free); - } - - static void -@@ -617,6 +573,7 @@ resolve_child (GVfsBackendGoogle *self, - static GDataEntry * - resolve (GVfsBackendGoogle *self, - const gchar *filename, -+ gchar **out_path, - GError **error) - { - GDataEntry *parent; -@@ -627,11 +584,15 @@ resolve (GVfsBackendGoogle *self, - if (g_strcmp0 (filename, "/") == 0) - { - ret_val = self->root; -+ -+ if (out_path != NULL) -+ *out_path = g_strdup ("/"); -+ - goto out; - } - - local_error = NULL; -- parent = resolve_dir (self, filename, &basename, &local_error); -+ parent = resolve_dir (self, filename, &basename, out_path, &local_error); - if (local_error != NULL) - { - g_propagate_error (error, local_error); -@@ -645,6 +606,14 @@ resolve (GVfsBackendGoogle *self, - goto out; - } - -+ if (out_path != NULL) -+ { -+ gchar *tmp; -+ tmp = g_build_path ("/", *out_path, gdata_entry_get_id (ret_val), NULL); -+ g_free (*out_path); -+ *out_path = tmp; -+ } -+ - out: - g_free (basename); - return ret_val; -@@ -654,6 +623,7 @@ static GDataEntry * - resolve_dir (GVfsBackendGoogle *self, - const gchar *filename, - gchar **out_basename, -+ gchar **out_path, - GError **error) - { - GDataEntry *parent; -@@ -666,7 +636,7 @@ resolve_dir (GVfsBackendGoogle *self, - parent_path = g_path_get_dirname (filename); - - local_error = NULL; -- parent = resolve (self, parent_path, &local_error); -+ parent = resolve (self, parent_path, out_path, &local_error); - if (local_error != NULL) - { - g_propagate_error (error, local_error); -@@ -699,12 +669,13 @@ static GDataEntry * - resolve_and_rebuild (GVfsBackendGoogle *self, - const gchar *filename, - GCancellable *cancellable, -+ gchar **out_path, - GError **error) - { - GDataEntry *entry; - GDataEntry *ret_val = NULL; - -- entry = resolve (self, filename, NULL); -+ entry = resolve (self, filename, out_path, NULL); - if (entry == NULL) - { - GError *local_error; -@@ -718,7 +689,7 @@ resolve_and_rebuild (GVfsBackendGoogle *self, - } - - local_error = NULL; -- entry = resolve (self, filename, &local_error); -+ entry = resolve (self, filename, out_path, &local_error); - if (local_error != NULL) - { - g_propagate_error (error, local_error); -@@ -737,6 +708,7 @@ resolve_dir_and_rebuild (GVfsBackendGoogle *self, - const gchar *filename, - GCancellable *cancellable, - gchar **out_basename, -+ gchar **out_path, - GError **error) - { - GDataEntry *parent; -@@ -745,7 +717,7 @@ resolve_dir_and_rebuild (GVfsBackendGoogle *self, - gchar *basename = NULL; - - local_error = NULL; -- parent = resolve_dir (self, filename, &basename, &local_error); -+ parent = resolve_dir (self, filename, &basename, out_path, &local_error); - if (local_error != NULL) - { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY)) -@@ -767,7 +739,7 @@ resolve_dir_and_rebuild (GVfsBackendGoogle *self, - } - - local_error = NULL; -- parent = resolve_dir (self, filename, &basename, &local_error); -+ parent = resolve_dir (self, filename, &basename, out_path, &local_error); - if (local_error != NULL) - { - g_propagate_error (error, local_error); -@@ -819,13 +791,12 @@ get_extension_offset (const char *title) - } - - static gchar * --generate_copy_name (GVfsBackendGoogle *self, GDataEntry *entry) -+generate_copy_name (GVfsBackendGoogle *self, GDataEntry *entry, const gchar *entry_path) - { - GDataEntry *existing_entry; - GDataEntry *parent; - const gchar *id; - const gchar *title; -- gchar *entry_path = NULL; - gchar *extension = NULL; - gchar *extension_offset; - gchar *ret_val = NULL; -@@ -833,11 +804,7 @@ generate_copy_name (GVfsBackendGoogle *self, GDataEntry *entry) - - title = gdata_entry_get_title (entry); - -- entry_path = get_entry_path (self, entry); -- if (entry_path == NULL) -- goto out; -- -- parent = resolve_dir (self, entry_path, NULL, NULL); -+ parent = resolve_dir (self, entry_path, NULL, NULL, NULL); - if (parent == NULL) - goto out; - -@@ -859,7 +826,6 @@ generate_copy_name (GVfsBackendGoogle *self, GDataEntry *entry) - out: - if (ret_val == NULL) - ret_val = g_strdup (title); -- g_free (entry_path); - g_free (extension); - g_free (title_without_extension); - return ret_val; -@@ -890,7 +856,7 @@ build_file_info (GVfsBackendGoogle *self, - GFileAttributeMatcher *matcher, - gboolean is_symlink, - const gchar *symlink_name, -- const gchar *symlink_target, -+ const gchar *entry_path, - GError **error) - { - GFileType file_type; -@@ -968,7 +934,7 @@ build_file_info (GVfsBackendGoogle *self, - file_type = G_FILE_TYPE_SYMBOLIC_LINK; - } - -- g_file_info_set_symlink_target (info, symlink_target); -+ g_file_info_set_symlink_target (info, entry_path); - } - - if (content_type != NULL) -@@ -1016,7 +982,7 @@ build_file_info (GVfsBackendGoogle *self, - g_file_info_set_display_name (info, title); - g_file_info_set_edit_name (info, title); - -- copy_name = generate_copy_name (self, entry); -+ copy_name = generate_copy_name (self, entry, entry_path); - - /* Sanitize copy-name by replacing slashes with dashes. This is - * what nautilus does (for desktop files). -@@ -1116,6 +1082,7 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - gchar *destination_basename = NULL; - gchar *entry_path = NULL; - goffset size; -+ gchar *parent_path = NULL; - - g_rec_mutex_lock (&self->mutex); - g_debug ("+ copy: %s -> %s, %d\n", source, destination, flags); -@@ -1130,12 +1097,12 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - goto out; - } - -- source_entry = resolve (self, source, NULL); -+ source_entry = resolve (self, source, NULL, NULL); - if (source_entry == NULL) - needs_rebuild = TRUE; - - error = NULL; -- destination_parent = resolve_dir (self, destination, &destination_basename, &error); -+ destination_parent = resolve_dir (self, destination, &destination_basename, &parent_path, &error); - if (error != NULL) - { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY)) -@@ -1158,7 +1125,7 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - } - - error = NULL; -- source_entry = resolve (self, source, &error); -+ source_entry = resolve (self, source, NULL, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1172,7 +1139,7 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - destination_basename = NULL; - - error = NULL; -- destination_parent = resolve_dir (self, destination, &destination_basename, &error); -+ destination_parent = resolve_dir (self, destination, &destination_basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1258,7 +1225,7 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, GDATA_ENTRY (new_entry)); -+ entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (new_entry)), NULL); - g_debug (" new entry path: %s\n", entry_path); - - insert_entry (self, GDATA_ENTRY (new_entry)); -@@ -1277,6 +1244,7 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - g_clear_object (&new_entry); - g_free (destination_basename); - g_free (entry_path); -+ g_free (parent_path); - g_debug ("- copy\n"); - g_rec_mutex_unlock (&self->mutex); - } -@@ -1306,7 +1274,7 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend *_self, - } - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &error); -+ entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1314,7 +1282,6 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, entry); - g_debug (" entry path: %s\n", entry_path); - - if (!GDATA_IS_DOCUMENTS_FOLDER (entry)) -@@ -1356,7 +1323,7 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - g_debug ("+ delete: %s\n", filename); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &error); -+ entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1364,7 +1331,6 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, entry); - g_debug (" entry path: %s\n", entry_path); - - if (entry == self->root) -@@ -1420,7 +1386,8 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - GDataEntry *entry; - GError *error; - GHashTableIter iter; -- gchar *entry_path = NULL; -+ char *parent_path; -+ char *id; - - g_rec_mutex_lock (&self->mutex); - g_debug ("+ enumerate: %s\n", filename); -@@ -1447,7 +1414,7 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - } - - error = NULL; -- entry = resolve (self, filename, &error); -+ entry = resolve (self, filename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1455,9 +1422,6 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, entry); -- g_debug (" entry path: %s\n", entry_path); -- - if (!GDATA_IS_DOCUMENTS_FOLDER (entry)) - { - g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,_("The file is not a directory")); -@@ -1466,39 +1430,37 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - - g_vfs_job_succeeded (G_VFS_JOB (job)); - -+ /* g_strdup() is necessary to prevent segfault because gdata_entry_get_id() calls g_free() */ -+ id = g_strdup (gdata_entry_get_id (entry)); -+ - g_hash_table_iter_init (&iter, self->entries); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) - { -- gchar *path; -+ DirEntriesKey *k; - -- path = get_entry_path (self, entry); -- g_debug (" found entry: %s\n", path); -- if (path != NULL) -+ k = dir_entries_key_new (gdata_entry_get_id (entry), id); -+ if (g_hash_table_contains (self->dir_entries, k)) - { -- gchar *parent_path; -- -- parent_path = g_path_get_dirname (path); -- if (g_strcmp0 (entry_path, parent_path) == 0) -- { -- GFileInfo *info; -- -- info = g_file_info_new (); -- build_file_info (self, entry, flags, info, matcher, FALSE, NULL, NULL, NULL); -- g_vfs_job_enumerate_add_info (job, info); -- g_object_unref (info); -- } -- -- g_free (parent_path); -+ GFileInfo *info; -+ gchar *entry_path; -+ -+ info = g_file_info_new (); -+ entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (entry)), NULL); -+ build_file_info (self, entry, flags, info, matcher, FALSE, NULL, entry_path, NULL); -+ g_vfs_job_enumerate_add_info (job, info); -+ g_object_unref (info); -+ g_free (entry_path); - } - -- g_free (path); -+ dir_entries_key_free (k); - } - - g_vfs_job_enumerate_done (job); - - out: -- g_free (entry_path); - g_debug ("- enumerate\n"); -+ g_free (parent_path); -+ g_free (id); - g_rec_mutex_unlock (&self->mutex); - } - -@@ -1532,7 +1494,7 @@ g_vfs_backend_google_make_directory (GVfsBackend *_self, - } - - error = NULL; -- parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &error); -+ parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1540,7 +1502,6 @@ g_vfs_backend_google_make_directory (GVfsBackend *_self, - goto out; - } - -- parent_path = get_entry_path (self, parent); - g_debug (" parent path: %s\n", parent_path); - - summary_entry = g_hash_table_lookup (self->entries, basename); -@@ -1574,7 +1535,7 @@ g_vfs_backend_google_make_directory (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, GDATA_ENTRY (new_folder)); -+ entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (new_folder)), NULL); - g_debug (" new entry path: %s\n", entry_path); - - insert_entry (self, GDATA_ENTRY (new_folder)); -@@ -1744,6 +1705,7 @@ g_vfs_backend_google_push (GVfsBackend *_self, - const gchar *title; - gchar *destination_basename = NULL; - gchar *entry_path = NULL; -+ gchar *parent_path = NULL; - goffset size; - - g_rec_mutex_lock (&self->mutex); -@@ -1777,7 +1739,7 @@ g_vfs_backend_google_push (GVfsBackend *_self, - } - - error = NULL; -- destination_parent = resolve_dir_and_rebuild (self, destination, cancellable, &destination_basename, &error); -+ destination_parent = resolve_dir_and_rebuild (self, destination, cancellable, &destination_basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1922,7 +1884,7 @@ g_vfs_backend_google_push (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, GDATA_ENTRY (new_document)); -+ entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (new_document)), NULL); - g_debug (" new entry path: %s\n", entry_path); - - if (needs_overwrite) -@@ -1960,6 +1922,7 @@ g_vfs_backend_google_push (GVfsBackend *_self, - g_clear_object (&ostream); - g_free (destination_basename); - g_free (entry_path); -+ g_free (parent_path); - g_debug ("- push\n"); - g_rec_mutex_unlock (&self->mutex); - } -@@ -2065,7 +2028,7 @@ g_vfs_backend_google_query_info (GVfsBackend *_self, - g_debug ("+ query_info: %s, %d\n", filename, flags); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &error); -+ entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2073,7 +2036,6 @@ g_vfs_backend_google_query_info (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, entry); - if (g_strcmp0 (entry_path, filename) != 0) /* volatile */ - { - is_symlink = TRUE; -@@ -2122,8 +2084,8 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self, - - entry = g_object_get_data (G_OBJECT (stream), "g-vfs-backend-google-entry"); - filename = g_object_get_data (G_OBJECT (stream), "g-vfs-backend-google-filename"); -+ entry_path = g_object_get_data (G_OBJECT (stream), "g-vfs-backend-google-entry-path"); - -- entry_path = get_entry_path (self, entry); - if (g_strcmp0 (entry_path, filename) != 0) /* volatile */ - { - is_symlink = TRUE; -@@ -2152,7 +2114,6 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self, - g_vfs_job_succeeded (G_VFS_JOB (job)); - - out: -- g_free (entry_path); - g_free (symlink_name); - g_debug ("- query_info_on_read\n"); - } -@@ -2170,19 +2131,17 @@ g_vfs_backend_google_query_info_on_write (GVfsBackend *_self, - GError *error; - WriteHandle *wh = (WriteHandle *) handle; - gboolean is_symlink = FALSE; -- gchar *entry_path = NULL; - gchar *symlink_name = NULL; - - g_debug ("+ query_info_on_write: %p\n", handle); - -- entry_path = get_entry_path (self, wh->document); -- if (g_strcmp0 (entry_path, wh->filename) != 0) /* volatile */ -+ if (g_strcmp0 (wh->entry_path, wh->filename) != 0) /* volatile */ - { - is_symlink = TRUE; - symlink_name = g_path_get_basename (wh->filename); - } - -- g_debug (" entry path: %s (%d)\n", entry_path, is_symlink); -+ g_debug (" entry path: %s (%d)\n", wh->entry_path, is_symlink); - - error = NULL; - build_file_info (self, -@@ -2192,7 +2151,7 @@ g_vfs_backend_google_query_info_on_write (GVfsBackend *_self, - matcher, - is_symlink, - symlink_name, -- entry_path, -+ wh->entry_path, - &error); - if (error != NULL) - { -@@ -2204,7 +2163,6 @@ g_vfs_backend_google_query_info_on_write (GVfsBackend *_self, - g_vfs_job_succeeded (G_VFS_JOB (job)); - - out: -- g_free (entry_path); - g_free (symlink_name); - g_debug ("- query_info_on_write\n"); - return TRUE; -@@ -2231,7 +2189,7 @@ g_vfs_backend_google_open_for_read (GVfsBackend *_self, - g_debug ("+ open_for_read: %s\n", filename); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &error); -+ entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2239,7 +2197,6 @@ g_vfs_backend_google_open_for_read (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, entry); - g_debug (" entry path: %s\n", entry_path); - - if (GDATA_IS_DOCUMENTS_FOLDER (entry)) -@@ -2272,6 +2229,7 @@ g_vfs_backend_google_open_for_read (GVfsBackend *_self, - - g_object_set_data_full (G_OBJECT (stream), "g-vfs-backend-google-entry", g_object_ref (entry), g_object_unref); - g_object_set_data_full (G_OBJECT (stream), "g-vfs-backend-google-filename", g_strdup (filename), g_free); -+ g_object_set_data_full (G_OBJECT (stream), "g-vfs-backend-google-entry-path", g_strdup (entry_path), g_free); - g_vfs_job_open_for_read_set_handle (job, stream); - g_vfs_job_open_for_read_set_can_seek (job, TRUE); - g_vfs_job_succeeded (G_VFS_JOB (job)); -@@ -2419,7 +2377,7 @@ g_vfs_backend_google_set_display_name (GVfsBackend *_self, - g_debug ("+ set_display_name: %s, %s\n", filename, display_name); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &error); -+ entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2427,7 +2385,6 @@ g_vfs_backend_google_set_display_name (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, entry); - g_debug (" entry path: %s\n", entry_path); - - if (entry == self->root) -@@ -2492,7 +2449,7 @@ g_vfs_backend_google_create (GVfsBackend *_self, - } - - error = NULL; -- parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &error); -+ parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2500,7 +2457,6 @@ g_vfs_backend_google_create (GVfsBackend *_self, - goto out; - } - -- parent_path = get_entry_path (self, parent); - g_debug (" parent path: %s\n", parent_path); - - existing_entry = resolve_child (self, parent, basename); -@@ -2538,13 +2494,13 @@ g_vfs_backend_google_create (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, GDATA_ENTRY (new_document)); -+ entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (new_document)), NULL); - g_debug (" new entry path: %s\n", entry_path); - - insert_entry (self, GDATA_ENTRY (new_document)); - g_hash_table_foreach (self->monitors, emit_create_event, entry_path); - -- handle = write_handle_new (GDATA_ENTRY (new_document), NULL, filename); -+ handle = write_handle_new (GDATA_ENTRY (new_document), NULL, filename, entry_path); - g_vfs_job_open_for_write_set_handle (job, handle); - g_vfs_job_succeeded (G_VFS_JOB (job)); - -@@ -2602,7 +2558,7 @@ g_vfs_backend_google_replace (GVfsBackend *_self, - } - - error = NULL; -- parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &error); -+ parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2610,7 +2566,6 @@ g_vfs_backend_google_replace (GVfsBackend *_self, - goto out; - } - -- parent_path = get_entry_path (self, parent); - g_debug (" parent path: %s\n", parent_path); - - existing_entry = resolve_child (self, parent, basename); -@@ -2639,7 +2594,7 @@ g_vfs_backend_google_replace (GVfsBackend *_self, - { - const gchar *title; - -- entry_path = get_entry_path (self, existing_entry); -+ entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (existing_entry), NULL); - g_debug (" existing entry path: %s\n", entry_path); - - title = gdata_entry_get_title (existing_entry); -@@ -2660,7 +2615,7 @@ g_vfs_backend_google_replace (GVfsBackend *_self, - goto out; - } - -- handle = write_handle_new (NULL, stream, filename); -+ handle = write_handle_new (NULL, stream, filename, entry_path); - } - else - { -@@ -2681,13 +2636,13 @@ g_vfs_backend_google_replace (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, GDATA_ENTRY (new_document)); -+ entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (new_document)), NULL); - g_debug (" new entry path: %s\n", entry_path); - - insert_entry (self, GDATA_ENTRY (new_document)); - g_hash_table_foreach (self->monitors, emit_create_event, entry_path); - -- handle = write_handle_new (GDATA_ENTRY (new_document), NULL, filename); -+ handle = write_handle_new (GDATA_ENTRY (new_document), NULL, filename, entry_path); - } - - g_vfs_job_open_for_write_set_handle (job, handle); -@@ -2718,7 +2673,6 @@ g_vfs_backend_google_write (GVfsBackend *_self, - GCancellable *cancellable = G_VFS_JOB (job)->cancellable; - GError *error; - WriteHandle *wh = (WriteHandle *) handle; -- gchar *entry_path = NULL; - gssize nwrite; - - g_debug ("+ write: %p\n", handle); -@@ -2751,9 +2705,7 @@ g_vfs_backend_google_write (GVfsBackend *_self, - } - - g_debug (" writing to stream: %p\n", wh->stream); -- -- entry_path = get_entry_path (self, wh->document); -- g_debug (" entry path: %s\n", entry_path); -+ g_debug (" entry path: %s\n", wh->entry_path); - - error = NULL; - nwrite = g_output_stream_write (G_OUTPUT_STREAM (wh->stream), -@@ -2768,12 +2720,11 @@ g_vfs_backend_google_write (GVfsBackend *_self, - goto out; - } - -- g_hash_table_foreach (self->monitors, emit_changed_event, entry_path); -+ g_hash_table_foreach (self->monitors, emit_changed_event, wh->entry_path); - g_vfs_job_write_set_written_size (job, (gsize) nwrite); - g_vfs_job_succeeded (G_VFS_JOB (job)); - - out: -- g_free (entry_path); - g_debug ("- write\n"); - } - -@@ -2789,7 +2740,6 @@ g_vfs_backend_google_close_write (GVfsBackend *_self, - GDataDocumentsDocument *new_document = NULL; - GError *error; - WriteHandle *wh = (WriteHandle *) handle; -- gchar *entry_path = NULL; - - g_debug ("+ close_write: %p\n", handle); - -@@ -2820,18 +2770,16 @@ g_vfs_backend_google_close_write (GVfsBackend *_self, - goto out; - } - -- entry_path = get_entry_path (self, GDATA_ENTRY (new_document)); -- g_debug (" new entry path: %s\n", entry_path); -+ g_debug (" new entry path: %s\n", wh->entry_path); - - remove_entry (self, wh->document); - insert_entry (self, GDATA_ENTRY (new_document)); -- g_hash_table_foreach (self->monitors, emit_changes_done_event, entry_path); -+ g_hash_table_foreach (self->monitors, emit_changes_done_event, wh->entry_path); - g_vfs_job_succeeded (G_VFS_JOB (job)); - - out: - g_clear_object (&new_document); - write_handle_free (wh); -- g_free (entry_path); - g_debug ("- close_write\n"); - } - --- -2.36.1 - - -From 77610a76ae671ec340d100791043f7b3de4bbaf4 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 1 Aug 2018 11:21:45 +0200 -Subject: [PATCH 07/14] google: Remove file just from concrete parent - -Files with multiple parents are currently removed from all parents. -This is unexpected and may cause data loss, because it is not obvious -that it is one file. Let's remove the file just from requested folder. ---- - daemon/gvfsbackendgoogle.c | 37 +++++++++++++++++++++++++++++++++---- - 1 file changed, 33 insertions(+), 4 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 7f812448..45a48079 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -1314,10 +1314,12 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - { - GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self); - GCancellable *cancellable = G_VFS_JOB (job)->cancellable; -- GDataAuthorizationDomain *auth_domain; - GDataEntry *entry; -+ GDataEntry *parent; -+ GDataDocumentsEntry *new_entry = NULL; - GError *error; - gchar *entry_path = NULL; -+ GList *parent_ids; - - g_rec_mutex_lock (&self->mutex); - g_debug ("+ delete: %s\n", filename); -@@ -1331,6 +1333,14 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - goto out; - } - -+ parent = resolve_dir (self, filename, cancellable, NULL, NULL, &error); -+ if (error != NULL) -+ { -+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -+ g_error_free (error); -+ goto out; -+ } -+ - g_debug (" entry path: %s\n", entry_path); - - if (entry == self->root) -@@ -1339,10 +1349,26 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - goto out; - } - -- auth_domain = gdata_documents_service_get_primary_authorization_domain (); -+ /* It has to be removed before the actual call to properly invalidate dir entries. */ -+ g_object_ref (entry); -+ remove_entry (self, entry); - - error = NULL; -- gdata_service_delete_entry (GDATA_SERVICE (self->service), auth_domain, entry, cancellable, &error); -+ -+ /* gdata_documents_service_remove_entry_from_folder seems doesn't work for one parent. */ -+ parent_ids = get_parent_ids (self, entry); -+ if (g_list_length (parent_ids) > 1) -+ { -+ new_entry = gdata_documents_service_remove_entry_from_folder (self->service, GDATA_DOCUMENTS_ENTRY (entry), GDATA_DOCUMENTS_FOLDER (parent), cancellable, &error); -+ } -+ else -+ { -+ GDataAuthorizationDomain *auth_domain; -+ -+ auth_domain = gdata_documents_service_get_primary_authorization_domain (); -+ gdata_service_delete_entry (GDATA_SERVICE (self->service), auth_domain, entry, cancellable, &error); -+ } -+ - if (error != NULL) - { - sanitize_error (&error); -@@ -1351,11 +1377,14 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - goto out; - } - -- remove_entry (self, entry); -+ if (new_entry) -+ insert_entry (self, GDATA_ENTRY (new_entry)); - g_hash_table_foreach (self->monitors, emit_delete_event, entry_path); - g_vfs_job_succeeded (G_VFS_JOB (job)); - - out: -+ g_object_unref (entry); -+ g_clear_object (&new_entry); - g_free (entry_path); - g_debug ("- delete\n"); - g_rec_mutex_unlock (&self->mutex); --- -2.36.1 - - -From 454e38f9a96505ea5ecaa6a95a8658d58caf24a1 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Mon, 30 Jul 2018 16:42:31 +0200 -Subject: [PATCH 08/14] google: Rework cache for better performance - -The backend is totally unusable if you have too many files on your -Drive. This happens because the backend preloads the whole Drive's -metadata. Let's build the cache incrementaly per folders. - -As a result, the backend works smoothly regardless of the total -number of Drive files, because the total number of transmitted data -is significantly reduced. On the other hand, more requests is done -to Drive, but the Drive quotas seem big enough. ---- - daemon/gvfsbackendgoogle.c | 404 +++++++++++++++---------------------- - 1 file changed, 166 insertions(+), 238 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 45a48079..bf50fef6 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -55,15 +55,13 @@ struct _GVfsBackendGoogle - GVfsBackend parent; - GDataDocumentsService *service; - GDataEntry *root; -- GHashTable *entries; -- GHashTable *dir_entries; -+ GHashTable *entries; /* gchar *entry_id -> GDataEntry */ -+ GHashTable *dir_entries; /* DirEntriesKey -> GDataEntry */ - GHashTable *monitors; - GList *dir_collisions; - GRecMutex mutex; /* guards cache */ - GoaClient *client; -- gboolean entries_stale; - gchar *account_identity; -- guint entries_stale_timeout; - }; - - struct _GVfsBackendGoogleClass -@@ -104,6 +102,7 @@ typedef struct - - static GDataEntry *resolve_dir (GVfsBackendGoogle *self, - const gchar *filename, -+ GCancellable *cancellable, - gchar **out_basename, - gchar **out_path, - GError **error); -@@ -434,12 +433,19 @@ static void - insert_entry (GVfsBackendGoogle *self, - GDataEntry *entry) - { -+ gint64 *timestamp; -+ -+ timestamp = g_new (gint64, 1); -+ *timestamp = g_get_real_time (); -+ g_object_set_data_full (G_OBJECT (entry), "timestamp", timestamp, g_free); -+ - insert_entry_full (self, entry, TRUE); - } - - static void --remove_entry (GVfsBackendGoogle *self, -- GDataEntry *entry) -+remove_entry_full (GVfsBackendGoogle *self, -+ GDataEntry *entry, -+ gboolean restore_dir_collisions) - { - DirEntriesKey *k; - GList *l; -@@ -474,17 +480,20 @@ remove_entry (GVfsBackendGoogle *self, - g_object_unref (entry); - } - -- for (l = self->dir_collisions; l != NULL; l = l->next) -+ if (restore_dir_collisions) - { -- GDataEntry *colliding_entry = GDATA_ENTRY (l->data); -- -- if (insert_entry_full (self, colliding_entry, FALSE)) -+ for (l = self->dir_collisions; l != NULL; l = l->next) - { -- self->dir_collisions = g_list_remove_link (self->dir_collisions, l); -- g_debug (" remove_entry: Restored %p\n", colliding_entry); -- g_list_free (l); -- g_object_unref (colliding_entry); -- break; -+ GDataEntry *colliding_entry = GDATA_ENTRY (l->data); -+ -+ if (insert_entry_full (self, colliding_entry, FALSE)) -+ { -+ self->dir_collisions = g_list_remove_link (self->dir_collisions, l); -+ g_debug (" remove_entry: Restored %p\n", colliding_entry); -+ g_list_free (l); -+ g_object_unref (colliding_entry); -+ break; -+ } - } - } - } -@@ -492,16 +501,85 @@ remove_entry (GVfsBackendGoogle *self, - } - - static void --rebuild_entries (GVfsBackendGoogle *self, -- GCancellable *cancellable, -- GError **error) -+remove_entry (GVfsBackendGoogle *self, -+ GDataEntry *entry) -+{ -+ remove_entry_full (self, entry, TRUE); -+} -+ -+static void -+remove_dir (GVfsBackendGoogle *self, -+ GDataEntry *parent) -+{ -+ GHashTableIter iter; -+ GDataEntry *entry; -+ gchar *parent_id; -+ GList *l; -+ -+ /* g_strdup() is necessary to prevent segfault because gdata_entry_get_id() calls g_free() */ -+ parent_id = g_strdup (gdata_entry_get_id (parent)); -+ -+ g_hash_table_iter_init (&iter, self->entries); -+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) -+ { -+ DirEntriesKey *k; -+ -+ k = dir_entries_key_new (gdata_entry_get_id (entry), parent_id); -+ if (g_hash_table_contains (self->dir_entries, k)) -+ { -+ g_object_ref (entry); -+ g_hash_table_iter_remove (&iter); -+ remove_entry_full (self, entry, FALSE); -+ g_object_unref (entry); -+ } -+ -+ dir_entries_key_free (k); -+ } -+ -+ for (l = self->dir_collisions; l != NULL; l = l->next) -+ { -+ GDataEntry *colliding_entry = GDATA_ENTRY (l->data); -+ -+ if (insert_entry_full (self, colliding_entry, FALSE)) -+ { -+ self->dir_collisions = g_list_remove_link (self->dir_collisions, l); -+ g_debug (" remove_entry: Restored %p\n", colliding_entry); -+ g_list_free (l); -+ g_object_unref (colliding_entry); -+ break; -+ } -+ } -+ -+ g_free (parent_id); -+} -+ -+static gboolean -+is_entry_valid (GDataEntry *entry) -+{ -+ gint64 *timestamp; -+ -+ timestamp = g_object_get_data (G_OBJECT (entry), "timestamp"); -+ return (g_get_real_time () - *timestamp < REBUILD_ENTRIES_TIMEOUT * G_USEC_PER_SEC); -+} -+ -+static void -+rebuild_dir (GVfsBackendGoogle *self, -+ GDataEntry *parent, -+ GCancellable *cancellable, -+ GError **error) - { - GDataDocumentsFeed *feed = NULL; - GDataDocumentsQuery *query = NULL; - gboolean succeeded_once = FALSE; -+ gchar *search; -+ const gchar *parent_id; -+ -+ parent_id = gdata_entry_get_id (parent); - -- query = gdata_documents_query_new_with_limits (NULL, 1, MAX_RESULTS); -+ search = g_strdup_printf ("'%s' in parents", parent_id); -+ query = gdata_documents_query_new_with_limits (search, 1, MAX_RESULTS); - gdata_documents_query_set_show_folders (query, TRUE); -+ g_free (search); - - while (TRUE) - { -@@ -515,18 +593,13 @@ rebuild_entries (GVfsBackendGoogle *self, - { - sanitize_error (&local_error); - g_propagate_error (error, local_error); -- self->entries_stale = TRUE; - - goto out; - } - - if (!succeeded_once) - { -- g_hash_table_remove_all (self->entries); -- g_hash_table_remove_all (self->dir_entries); -- -- g_list_free_full (self->dir_collisions, g_object_unref); -- self->dir_collisions = NULL; -+ remove_dir (self, parent); - - succeeded_once = TRUE; - } -@@ -545,8 +618,6 @@ rebuild_entries (GVfsBackendGoogle *self, - g_clear_object (&feed); - } - -- self->entries_stale = FALSE; -- - out: - g_clear_object (&feed); - g_clear_object (&query); -@@ -555,24 +626,48 @@ rebuild_entries (GVfsBackendGoogle *self, - /* ---------------------------------------------------------------------------------------------------- */ - - static GDataEntry * --resolve_child (GVfsBackendGoogle *self, -- GDataEntry *parent, -- const gchar *basename) -+resolve_child (GVfsBackendGoogle *self, -+ GDataEntry *parent, -+ const gchar *basename, -+ GCancellable *cancellable, -+ GError **error) - { - DirEntriesKey *k; - GDataEntry *entry; - const gchar *parent_id; -+ GError *local_error = NULL; - - parent_id = gdata_entry_get_id (parent); - k = dir_entries_key_new (basename, parent_id); - entry = g_hash_table_lookup (self->dir_entries, k); -+ // TODO: Rebuild only if dir listing is not valid -+ if (entry == NULL || !is_entry_valid (entry)) -+ { -+ rebuild_dir (self, parent, cancellable, &local_error); -+ if (local_error != NULL) -+ { -+ g_propagate_error (error, local_error); -+ goto out; -+ } -+ -+ entry = g_hash_table_lookup (self->dir_entries, k); -+ if (entry == NULL) -+ { -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory")); -+ goto out; -+ } -+ } -+ -+ out: - dir_entries_key_free (k); -+ - return entry; - } - - static GDataEntry * - resolve (GVfsBackendGoogle *self, - const gchar *filename, -+ GCancellable *cancellable, - gchar **out_path, - GError **error) - { -@@ -581,6 +676,8 @@ resolve (GVfsBackendGoogle *self, - GError *local_error; - gchar *basename = NULL; - -+ g_assert (filename && filename[0] == '/'); -+ - if (g_strcmp0 (filename, "/") == 0) - { - ret_val = self->root; -@@ -592,17 +689,17 @@ resolve (GVfsBackendGoogle *self, - } - - local_error = NULL; -- parent = resolve_dir (self, filename, &basename, out_path, &local_error); -+ parent = resolve_dir (self, filename, cancellable, &basename, out_path, &local_error); - if (local_error != NULL) - { - g_propagate_error (error, local_error); - goto out; - } - -- ret_val = resolve_child (self, parent, basename); -+ ret_val = resolve_child (self, parent, basename, cancellable, &local_error); - if (ret_val == NULL) - { -- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory")); -+ g_propagate_error (error, local_error); - goto out; - } - -@@ -622,6 +719,7 @@ resolve (GVfsBackendGoogle *self, - static GDataEntry * - resolve_dir (GVfsBackendGoogle *self, - const gchar *filename, -+ GCancellable *cancellable, - gchar **out_basename, - gchar **out_path, - GError **error) -@@ -636,7 +734,7 @@ resolve_dir (GVfsBackendGoogle *self, - parent_path = g_path_get_dirname (filename); - - local_error = NULL; -- parent = resolve (self, parent_path, out_path, &local_error); -+ parent = resolve (self, parent_path, cancellable, out_path, &local_error); - if (local_error != NULL) - { - g_propagate_error (error, local_error); -@@ -665,103 +763,6 @@ resolve_dir (GVfsBackendGoogle *self, - - /* ---------------------------------------------------------------------------------------------------- */ - --static GDataEntry * --resolve_and_rebuild (GVfsBackendGoogle *self, -- const gchar *filename, -- GCancellable *cancellable, -- gchar **out_path, -- GError **error) --{ -- GDataEntry *entry; -- GDataEntry *ret_val = NULL; -- -- entry = resolve (self, filename, out_path, NULL); -- if (entry == NULL) -- { -- GError *local_error; -- -- local_error = NULL; -- rebuild_entries (self, cancellable, &local_error); -- if (local_error != NULL) -- { -- g_propagate_error (error, local_error); -- goto out; -- } -- -- local_error = NULL; -- entry = resolve (self, filename, out_path, &local_error); -- if (local_error != NULL) -- { -- g_propagate_error (error, local_error); -- goto out; -- } -- } -- -- ret_val = entry; -- -- out: -- return ret_val; --} -- --static GDataEntry * --resolve_dir_and_rebuild (GVfsBackendGoogle *self, -- const gchar *filename, -- GCancellable *cancellable, -- gchar **out_basename, -- gchar **out_path, -- GError **error) --{ -- GDataEntry *parent; -- GDataEntry *ret_val = NULL; -- GError *local_error; -- gchar *basename = NULL; -- -- local_error = NULL; -- parent = resolve_dir (self, filename, &basename, out_path, &local_error); -- if (local_error != NULL) -- { -- if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY)) -- { -- g_propagate_error (error, local_error); -- goto out; -- } -- else -- { -- g_error_free (local_error); -- } -- -- local_error = NULL; -- rebuild_entries (self, cancellable, &local_error); -- if (local_error != NULL) -- { -- g_propagate_error (error, local_error); -- goto out; -- } -- -- local_error = NULL; -- parent = resolve_dir (self, filename, &basename, out_path, &local_error); -- if (local_error != NULL) -- { -- g_propagate_error (error, local_error); -- goto out; -- } -- } -- -- if (out_basename != NULL) -- { -- *out_basename = basename; -- basename = NULL; -- } -- -- ret_val = parent; -- -- out: -- g_free (basename); -- return ret_val; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static char * - get_extension_offset (const char *title) - { -@@ -804,11 +805,11 @@ generate_copy_name (GVfsBackendGoogle *self, GDataEntry *entry, const gchar *ent - - title = gdata_entry_get_title (entry); - -- parent = resolve_dir (self, entry_path, NULL, NULL, NULL); -+ parent = resolve_dir (self, entry_path, NULL, NULL, NULL, NULL); - if (parent == NULL) - goto out; - -- existing_entry = resolve_child (self, parent, title); -+ existing_entry = resolve_child (self, parent, title, NULL, NULL); - if (existing_entry == entry) - goto out; - -@@ -1074,8 +1075,6 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - GDataEntry *source_entry; - GError *error; - GType source_entry_type; -- gboolean needs_rebuild = FALSE; -- gboolean destination_not_directory = FALSE; - const gchar *etag; - const gchar *id; - const gchar *summary; -@@ -1097,56 +1096,21 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - goto out; - } - -- source_entry = resolve (self, source, NULL, NULL); -- if (source_entry == NULL) -- needs_rebuild = TRUE; -- - error = NULL; -- destination_parent = resolve_dir (self, destination, &destination_basename, &parent_path, &error); -+ source_entry = resolve (self, source, cancellable, NULL, &error); - if (error != NULL) - { -- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY)) -- destination_not_directory = TRUE; -- else -- needs_rebuild = TRUE; -- -+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error); - g_error_free (error); -+ goto out; - } - -- if (needs_rebuild) -+ destination_parent = resolve_dir (self, destination, cancellable, &destination_basename, &parent_path, &error); -+ if (error != NULL) - { -- error = NULL; -- rebuild_entries (self, cancellable, &error); -- if (error != NULL) -- { -- g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -- g_error_free (error); -- goto out; -- } -- -- error = NULL; -- source_entry = resolve (self, source, NULL, &error); -- if (error != NULL) -- { -- g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -- g_error_free (error); -- goto out; -- } -- -- if (!destination_not_directory) -- { -- g_free (destination_basename); -- destination_basename = NULL; -- -- error = NULL; -- destination_parent = resolve_dir (self, destination, &destination_basename, &parent_path, &error); -- if (error != NULL) -- { -- g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -- g_error_free (error); -- goto out; -- } -- } -+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -+ g_error_free (error); -+ goto out; - } - - etag = gdata_entry_get_etag (source_entry); -@@ -1165,13 +1129,7 @@ g_vfs_backend_google_copy (GVfsBackend *_self, - goto out; - } - -- if (destination_not_directory) -- { -- g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, _("The file is not a directory")); -- goto out; -- } -- -- existing_entry = resolve_child (self, destination_parent, destination_basename); -+ existing_entry = resolve_child (self, destination_parent, destination_basename, cancellable, NULL); - if (existing_entry != NULL) - { - if (flags & G_FILE_COPY_OVERWRITE) -@@ -1274,7 +1232,7 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend *_self, - } - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); -+ entry = resolve (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1325,7 +1283,7 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - g_debug ("+ delete: %s\n", filename); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); -+ entry = resolve (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1392,17 +1350,6 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --rebuild_entries_timeout_cb (gpointer user_data) --{ -- GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (user_data); -- -- self->entries_stale = TRUE; -- self->entries_stale_timeout = 0; -- -- return G_SOURCE_REMOVE; --} -- - static void - g_vfs_backend_google_enumerate (GVfsBackend *_self, - GVfsJobEnumerate *job, -@@ -1421,29 +1368,8 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - g_rec_mutex_lock (&self->mutex); - g_debug ("+ enumerate: %s\n", filename); - -- if (self->entries_stale_timeout == 0) -- { -- self->entries_stale_timeout = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, -- REBUILD_ENTRIES_TIMEOUT, -- rebuild_entries_timeout_cb, -- g_object_ref (self), -- g_object_unref); -- } -- -- if (self->entries_stale) -- { -- error = NULL; -- rebuild_entries (self, cancellable, &error); -- if (error != NULL) -- { -- g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -- g_error_free (error); -- goto out; -- } -- } -- - error = NULL; -- entry = resolve (self, filename, &parent_path, &error); -+ entry = resolve (self, filename, cancellable, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1457,6 +1383,15 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - goto out; - } - -+ // TODO: Rebuild only if dir listing is not valid -+ rebuild_dir (self, entry, cancellable, &error); -+ if (error != NULL) -+ { -+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -+ g_error_free (error); -+ goto out; -+ } -+ - g_vfs_job_succeeded (G_VFS_JOB (job)); - - /* g_strdup() is necessary to prevent segfault because gdata_entry_get_id() calls g_free() */ -@@ -1523,7 +1458,7 @@ g_vfs_backend_google_make_directory (GVfsBackend *_self, - } - - error = NULL; -- parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &parent_path, &error); -+ parent = resolve_dir (self, filename, cancellable, &basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1539,7 +1474,7 @@ g_vfs_backend_google_make_directory (GVfsBackend *_self, - else - summary = gdata_entry_get_summary (summary_entry); - -- existing_entry = resolve_child (self, parent, basename); -+ existing_entry = resolve_child (self, parent, basename, cancellable, NULL); - if (existing_entry != NULL) - { - g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_EXISTS, _("Target file already exists")); -@@ -1768,7 +1703,7 @@ g_vfs_backend_google_push (GVfsBackend *_self, - } - - error = NULL; -- destination_parent = resolve_dir_and_rebuild (self, destination, cancellable, &destination_basename, &parent_path, &error); -+ destination_parent = resolve_dir (self, destination, cancellable, &destination_basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -1776,7 +1711,7 @@ g_vfs_backend_google_push (GVfsBackend *_self, - goto out; - } - -- existing_entry = resolve_child (self, destination_parent, destination_basename); -+ existing_entry = resolve_child (self, destination_parent, destination_basename, cancellable, NULL); - if (existing_entry != NULL) - { - if (flags & G_FILE_COPY_OVERWRITE) -@@ -2057,7 +1992,7 @@ g_vfs_backend_google_query_info (GVfsBackend *_self, - g_debug ("+ query_info: %s, %d\n", filename, flags); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); -+ entry = resolve (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2218,7 +2153,7 @@ g_vfs_backend_google_open_for_read (GVfsBackend *_self, - g_debug ("+ open_for_read: %s\n", filename); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); -+ entry = resolve (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2406,7 +2341,7 @@ g_vfs_backend_google_set_display_name (GVfsBackend *_self, - g_debug ("+ set_display_name: %s, %s\n", filename, display_name); - - error = NULL; -- entry = resolve_and_rebuild (self, filename, cancellable, &entry_path, &error); -+ entry = resolve (self, filename, cancellable, &entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2478,7 +2413,7 @@ g_vfs_backend_google_create (GVfsBackend *_self, - } - - error = NULL; -- parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &parent_path, &error); -+ parent = resolve_dir (self, filename, cancellable, &basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2488,7 +2423,7 @@ g_vfs_backend_google_create (GVfsBackend *_self, - - g_debug (" parent path: %s\n", parent_path); - -- existing_entry = resolve_child (self, parent, basename); -+ existing_entry = resolve_child (self, parent, basename, cancellable, NULL); - if (existing_entry != NULL) - { - if (flags & G_FILE_CREATE_REPLACE_DESTINATION) -@@ -2587,7 +2522,7 @@ g_vfs_backend_google_replace (GVfsBackend *_self, - } - - error = NULL; -- parent = resolve_dir_and_rebuild (self, filename, cancellable, &basename, &parent_path, &error); -+ parent = resolve_dir (self, filename, cancellable, &basename, &parent_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2597,7 +2532,7 @@ g_vfs_backend_google_replace (GVfsBackend *_self, - - g_debug (" parent path: %s\n", parent_path); - -- existing_entry = resolve_child (self, parent, basename); -+ existing_entry = resolve_child (self, parent, basename, cancellable, NULL); - if (existing_entry != NULL) - { - if (GDATA_IS_DOCUMENTS_FOLDER (existing_entry)) -@@ -2819,12 +2754,6 @@ g_vfs_backend_google_dispose (GObject *_self) - { - GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self); - -- if (self->entries_stale_timeout != 0) -- { -- g_source_remove (self->entries_stale_timeout); -- self->entries_stale_timeout = 0; -- } -- - if (self->dir_collisions != NULL) - { - g_list_free_full (self->dir_collisions, g_object_unref); -@@ -2896,5 +2825,4 @@ g_vfs_backend_google_init (GVfsBackendGoogle *self) - g_object_unref); - self->monitors = g_hash_table_new (NULL, NULL); - g_rec_mutex_init (&self->mutex); -- self->entries_stale = TRUE; - } --- -2.36.1 - - -From 8c8bc7a8c37bbf1493b14cd76b21b077136e3260 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Thu, 16 Aug 2018 15:00:52 +0200 -Subject: [PATCH 09/14] google: Use cache for enumeration also - -The reworked cache hasn't been used for enumeration results and also -for missing files checks, which always caused rebuilding cache. Let's -save timestamps also for enumerations and use it to prevent redundant -cache rebuilds. ---- - daemon/gvfsbackendgoogle.c | 62 ++++++++++++++++++++++++++++---------- - 1 file changed, 46 insertions(+), 16 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index bf50fef6..4eb8dbfe 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -57,6 +57,7 @@ struct _GVfsBackendGoogle - GDataEntry *root; - GHashTable *entries; /* gchar *entry_id -> GDataEntry */ - GHashTable *dir_entries; /* DirEntriesKey -> GDataEntry */ -+ GHashTable *dir_timestamps; /* gchar *entry_id -> gint64 *timestamp */ - GHashTable *monitors; - GList *dir_collisions; - GRecMutex mutex; /* guards cache */ -@@ -463,6 +464,8 @@ remove_entry_full (GVfsBackendGoogle *self, - { - gchar *parent_id = ll->data; - -+ g_hash_table_remove (self->dir_timestamps, parent_id); -+ - k = dir_entries_key_new (id, parent_id); - g_debug (" remove_entry: Removed (%s, %s) -> %p\n", id, parent_id, entry); - g_hash_table_remove (self->dir_entries, k); -@@ -519,6 +522,8 @@ remove_dir (GVfsBackendGoogle *self, - /* g_strdup() is necessary to prevent segfault because gdata_entry_get_id() calls g_free() */ - parent_id = g_strdup (gdata_entry_get_id (parent)); - -+ g_hash_table_remove (self->dir_timestamps, parent_id); -+ - g_hash_table_iter_init (&iter, self->entries); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) - { -@@ -562,6 +567,18 @@ is_entry_valid (GDataEntry *entry) - return (g_get_real_time () - *timestamp < REBUILD_ENTRIES_TIMEOUT * G_USEC_PER_SEC); - } - -+static gboolean -+is_dir_listing_valid (GVfsBackendGoogle *self, GDataEntry *parent) -+{ -+ gint64 *timestamp; -+ -+ timestamp = g_hash_table_lookup (self->dir_timestamps, gdata_entry_get_id (parent)); -+ if (timestamp != NULL) -+ return (g_get_real_time () - *timestamp < REBUILD_ENTRIES_TIMEOUT * G_USEC_PER_SEC); -+ -+ return FALSE; -+} -+ - static void - rebuild_dir (GVfsBackendGoogle *self, - GDataEntry *parent, -@@ -572,9 +589,10 @@ rebuild_dir (GVfsBackendGoogle *self, - GDataDocumentsQuery *query = NULL; - gboolean succeeded_once = FALSE; - gchar *search; -- const gchar *parent_id; -+ gchar *parent_id; - -- parent_id = gdata_entry_get_id (parent); -+ /* g_strdup() is necessary to prevent segfault because gdata_entry_get_id() calls g_free() */ -+ parent_id = g_strdup (gdata_entry_get_id (parent)); - - search = g_strdup_printf ("'%s' in parents", parent_id); - query = gdata_documents_query_new_with_limits (search, 1, MAX_RESULTS); -@@ -599,8 +617,14 @@ rebuild_dir (GVfsBackendGoogle *self, - - if (!succeeded_once) - { -+ gint64 *timestamp; -+ - remove_dir (self, parent); - -+ timestamp = g_new (gint64, 1); -+ *timestamp = g_get_real_time (); -+ g_hash_table_insert (self->dir_timestamps, g_strdup (parent_id), timestamp); -+ - succeeded_once = TRUE; - } - -@@ -621,6 +645,7 @@ rebuild_dir (GVfsBackendGoogle *self, - out: - g_clear_object (&feed); - g_clear_object (&query); -+ g_free (parent_id); - } - - /* ---------------------------------------------------------------------------------------------------- */ -@@ -640,8 +665,8 @@ resolve_child (GVfsBackendGoogle *self, - parent_id = gdata_entry_get_id (parent); - k = dir_entries_key_new (basename, parent_id); - entry = g_hash_table_lookup (self->dir_entries, k); -- // TODO: Rebuild only if dir listing is not valid -- if (entry == NULL || !is_entry_valid (entry)) -+ if ((entry == NULL && !is_dir_listing_valid (self, parent)) || -+ (entry != NULL && !is_entry_valid (entry))) - { - rebuild_dir (self, parent, cancellable, &local_error); - if (local_error != NULL) -@@ -651,11 +676,12 @@ resolve_child (GVfsBackendGoogle *self, - } - - entry = g_hash_table_lookup (self->dir_entries, k); -- if (entry == NULL) -- { -- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory")); -- goto out; -- } -+ } -+ -+ if (entry == NULL) -+ { -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory")); -+ goto out; - } - - out: -@@ -1363,7 +1389,7 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - GError *error; - GHashTableIter iter; - char *parent_path; -- char *id; -+ char *id = NULL; - - g_rec_mutex_lock (&self->mutex); - g_debug ("+ enumerate: %s\n", filename); -@@ -1383,13 +1409,15 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - goto out; - } - -- // TODO: Rebuild only if dir listing is not valid -- rebuild_dir (self, entry, cancellable, &error); -- if (error != NULL) -+ if (!is_dir_listing_valid (self, entry)) - { -- g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -- g_error_free (error); -- goto out; -+ rebuild_dir (self, entry, cancellable, &error); -+ if (error != NULL) -+ { -+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -+ g_error_free (error); -+ goto out; -+ } - } - - g_vfs_job_succeeded (G_VFS_JOB (job)); -@@ -2765,6 +2793,7 @@ g_vfs_backend_google_dispose (GObject *_self) - g_clear_object (&self->client); - g_clear_pointer (&self->entries, g_hash_table_unref); - g_clear_pointer (&self->dir_entries, g_hash_table_unref); -+ g_clear_pointer (&self->dir_timestamps, g_hash_table_unref); - - G_OBJECT_CLASS (g_vfs_backend_google_parent_class)->dispose (_self); - } -@@ -2823,6 +2852,7 @@ g_vfs_backend_google_init (GVfsBackendGoogle *self) - entries_in_folder_equal, - dir_entries_key_free, - g_object_unref); -+ self->dir_timestamps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - self->monitors = g_hash_table_new (NULL, NULL); - g_rec_mutex_init (&self->mutex); - } --- -2.36.1 - - -From 79e1878e1a43e32c0dbce585ea377d0222f85f27 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 1 Aug 2018 16:17:42 +0200 -Subject: [PATCH 10/14] google: Handle child of volatile also as volatile - -Files in volatile folder should be also marked as volatile. - -Volatile handling is a bit simplified as a part of this patch also. ---- - daemon/gvfsbackendgoogle.c | 58 +++++++++++++------------------------- - 1 file changed, 19 insertions(+), 39 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 4eb8dbfe..3823cfe4 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -881,8 +881,7 @@ build_file_info (GVfsBackendGoogle *self, - GFileQueryInfoFlags flags, - GFileInfo *info, - GFileAttributeMatcher *matcher, -- gboolean is_symlink, -- const gchar *symlink_name, -+ const gchar *filename, - const gchar *entry_path, - GError **error) - { -@@ -890,6 +889,7 @@ build_file_info (GVfsBackendGoogle *self, - GList *authors; - gboolean is_folder = FALSE; - gboolean is_root = FALSE; -+ gboolean is_symlink = FALSE; - const gchar *etag; - const gchar *id; - const gchar *name; -@@ -897,6 +897,7 @@ build_file_info (GVfsBackendGoogle *self, - gchar *escaped_name = NULL; - gchar *content_type = NULL; - gchar *copy_name = NULL; -+ gchar *symlink_name = NULL; - gint64 atime; - gint64 ctime; - gint64 mtime; -@@ -908,6 +909,12 @@ build_file_info (GVfsBackendGoogle *self, - if (entry == self->root) - is_root = TRUE; - -+ if (filename != NULL && g_strcmp0 (entry_path, filename) != 0) /* volatile */ -+ { -+ is_symlink = TRUE; -+ symlink_name = g_path_get_basename (filename); -+ } -+ - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, !is_root); - - g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, is_folder); -@@ -1066,6 +1073,7 @@ build_file_info (GVfsBackendGoogle *self, - } - - out: -+ g_free (symlink_name); - g_free (copy_name); - g_free (escaped_name); - g_free (content_type); -@@ -1435,10 +1443,12 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - { - GFileInfo *info; - gchar *entry_path; -+ gchar *child_filename; - - info = g_file_info_new (); - entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (entry)), NULL); -- build_file_info (self, entry, flags, info, matcher, FALSE, NULL, entry_path, NULL); -+ child_filename = g_build_filename (filename, gdata_entry_get_id (GDATA_ENTRY (entry)), NULL); -+ build_file_info (self, entry, flags, info, matcher, child_filename, entry_path, NULL); - g_vfs_job_enumerate_add_info (job, info); - g_object_unref (info); - g_free (entry_path); -@@ -2012,9 +2022,7 @@ g_vfs_backend_google_query_info (GVfsBackend *_self, - GCancellable *cancellable = G_VFS_JOB (job)->cancellable; - GDataEntry *entry; - GError *error; -- gboolean is_symlink = FALSE; - gchar *entry_path = NULL; -- gchar *symlink_name = NULL; - - g_rec_mutex_lock (&self->mutex); - g_debug ("+ query_info: %s, %d\n", filename, flags); -@@ -2028,16 +2036,10 @@ g_vfs_backend_google_query_info (GVfsBackend *_self, - goto out; - } - -- if (g_strcmp0 (entry_path, filename) != 0) /* volatile */ -- { -- is_symlink = TRUE; -- symlink_name = g_path_get_basename (filename); -- } -- -- g_debug (" entry path: %s (%d)\n", entry_path, is_symlink); -+ g_debug (" entry path: %s\n", entry_path); - - error = NULL; -- build_file_info (self, entry, flags, info, matcher, is_symlink, symlink_name, entry_path, &error); -+ build_file_info (self, entry, flags, info, matcher, filename, entry_path, &error); - if (error != NULL) - { - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); -@@ -2049,7 +2051,6 @@ g_vfs_backend_google_query_info (GVfsBackend *_self, - - out: - g_free (entry_path); -- g_free (symlink_name); - g_debug ("- query_info\n"); - g_rec_mutex_unlock (&self->mutex); - } -@@ -2067,10 +2068,8 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self, - GDataEntry *entry; - GError *error; - GInputStream *stream = G_INPUT_STREAM (handle); -- gboolean is_symlink = FALSE; - const gchar *filename; - gchar *entry_path = NULL; -- gchar *symlink_name = NULL; - - g_debug ("+ query_info_on_read: %p\n", handle); - -@@ -2078,13 +2077,7 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self, - filename = g_object_get_data (G_OBJECT (stream), "g-vfs-backend-google-filename"); - entry_path = g_object_get_data (G_OBJECT (stream), "g-vfs-backend-google-entry-path"); - -- if (g_strcmp0 (entry_path, filename) != 0) /* volatile */ -- { -- is_symlink = TRUE; -- symlink_name = g_path_get_basename (filename); -- } -- -- g_debug (" entry path: %s (%d)\n", entry_path, is_symlink); -+ g_debug (" entry path: %s\n", entry_path); - - error = NULL; - build_file_info (self, -@@ -2092,8 +2085,7 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self, - G_FILE_QUERY_INFO_NONE, - info, - matcher, -- is_symlink, -- symlink_name, -+ filename, - entry_path, - &error); - if (error != NULL) -@@ -2106,7 +2098,6 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self, - g_vfs_job_succeeded (G_VFS_JOB (job)); - - out: -- g_free (symlink_name); - g_debug ("- query_info_on_read\n"); - } - -@@ -2122,18 +2113,9 @@ g_vfs_backend_google_query_info_on_write (GVfsBackend *_self, - GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self); - GError *error; - WriteHandle *wh = (WriteHandle *) handle; -- gboolean is_symlink = FALSE; -- gchar *symlink_name = NULL; - - g_debug ("+ query_info_on_write: %p\n", handle); -- -- if (g_strcmp0 (wh->entry_path, wh->filename) != 0) /* volatile */ -- { -- is_symlink = TRUE; -- symlink_name = g_path_get_basename (wh->filename); -- } -- -- g_debug (" entry path: %s (%d)\n", wh->entry_path, is_symlink); -+ g_debug (" entry path: %s\n", wh->entry_path); - - error = NULL; - build_file_info (self, -@@ -2141,8 +2123,7 @@ g_vfs_backend_google_query_info_on_write (GVfsBackend *_self, - G_FILE_QUERY_INFO_NONE, - info, - matcher, -- is_symlink, -- symlink_name, -+ wh->filename, - wh->entry_path, - &error); - if (error != NULL) -@@ -2155,7 +2136,6 @@ g_vfs_backend_google_query_info_on_write (GVfsBackend *_self, - g_vfs_job_succeeded (G_VFS_JOB (job)); - - out: -- g_free (symlink_name); - g_debug ("- query_info_on_write\n"); - return TRUE; - } --- -2.36.1 - - -From 46444e0aacd07a152e3d7958dcc263195cb69433 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Fri, 12 Jul 2019 10:35:47 +0200 -Subject: [PATCH 11/14] google: Do not enumerate volatile entries if title - matches id - -Currently, the volatile entry is enumerated if its title matches id -of another entry. But we don't want to enumerate volatile entries -to not confuse our clients. Let's add simple check to prevent this. ---- - daemon/gvfsbackendgoogle.c | 23 +++++++++++++++++++---- - 1 file changed, 19 insertions(+), 4 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 3823cfe4..60d6142f 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -1437,23 +1437,38 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self, - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry)) - { - DirEntriesKey *k; -+ GDataEntry *child; -+ gchar *child_id; - -- k = dir_entries_key_new (gdata_entry_get_id (entry), id); -- if (g_hash_table_contains (self->dir_entries, k)) -+ /* g_strdup() is necessary to prevent segfault because gdata_entry_get_id() calls g_free() */ -+ child_id = g_strdup (gdata_entry_get_id (entry)); -+ -+ k = dir_entries_key_new (child_id, id); -+ if ((child = g_hash_table_lookup (self->dir_entries, k)) != NULL) - { - GFileInfo *info; - gchar *entry_path; - gchar *child_filename; - -+ /* Be sure that we are not matching title of volatile file */ -+ if (g_strcmp0 (child_id, gdata_entry_get_id (child)) != 0) -+ { -+ g_debug ("Skipping %s as it is volatile path for %s\n", child_id, gdata_entry_get_id (child)); -+ g_free (child_id); -+ dir_entries_key_free (k); -+ continue; -+ } -+ - info = g_file_info_new (); -- entry_path = g_build_path ("/", parent_path, gdata_entry_get_id (GDATA_ENTRY (entry)), NULL); -- child_filename = g_build_filename (filename, gdata_entry_get_id (GDATA_ENTRY (entry)), NULL); -+ entry_path = g_build_path ("/", parent_path, child_id, NULL); -+ child_filename = g_build_filename (filename, child_id, NULL); - build_file_info (self, entry, flags, info, matcher, child_filename, entry_path, NULL); - g_vfs_job_enumerate_add_info (job, info); - g_object_unref (info); - g_free (entry_path); - } - -+ g_free (child_id); - dir_entries_key_free (k); - } - --- -2.36.1 - - -From 7a6419a1a8702516f82002c4a003eb6468ac5e7b Mon Sep 17 00:00:00 2001 -From: Mayank Sharma -Date: Thu, 18 Jul 2019 01:18:43 +0530 -Subject: [PATCH 12/14] google: Fix issue with stale entries remaining after - rename operation - -Currently, whenever we perform a rename operation, we set the `entry`'s -title to new display name, but at the time of removal of this entry from -cache, we still use the newer title. Hence, each time rename is done, a -single stale entry remains. This commit fixes the issue by reverting -back the title to the original display name of `entry` and then -performing a removal from cache. - -Fixes: https://gitlab.gnome.org/GNOME/gvfs/issues/410 ---- - daemon/gvfsbackendgoogle.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 60d6142f..1147e8f1 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -2380,6 +2380,11 @@ g_vfs_backend_google_set_display_name (GVfsBackend *_self, - goto out; - } - -+ /* The internal ref count has to be increased before removing the entry since -+ * remove_entry_full calls g_object_unref(). */ -+ g_object_ref (entry); -+ remove_entry (self, entry); -+ - gdata_entry_set_title (entry, display_name); - auth_domain = gdata_documents_service_get_primary_authorization_domain (); - -@@ -2390,14 +2395,15 @@ g_vfs_backend_google_set_display_name (GVfsBackend *_self, - sanitize_error (&error); - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); - g_error_free (error); -+ g_object_unref (entry); - goto out; - } - -- remove_entry (self, entry); - insert_entry (self, new_entry); - g_hash_table_foreach (self->monitors, emit_attribute_changed_event, entry_path); - g_vfs_job_set_display_name_set_new_path (job, entry_path); - g_vfs_job_succeeded (G_VFS_JOB (job)); -+ g_object_unref (entry); - - out: - g_clear_object (&new_entry); --- -2.36.1 - - -From 00d1e161f47adedf2f05d3574beb05d06c76b4c0 Mon Sep 17 00:00:00 2001 -From: Mayank Sharma -Date: Tue, 23 Jul 2019 09:51:41 +0530 -Subject: [PATCH 13/14] google: Fix crashes when deleting if the file isn't - found - -Currently in delete operation, if the entry gets resolved but parent -resolution fails, the jump to `out` label (while handling error) will -cause the existing entry's ref_count to decrease by 1 (since `out` -label calls g_object_unref on entry). - -We fix the issue by removing g_object_unref from `out` label and -suitably unreffing the entry. ---- - daemon/gvfsbackendgoogle.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 1147e8f1..230b89eb 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -1366,6 +1366,7 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - sanitize_error (&error); - g_vfs_job_failed_from_error (G_VFS_JOB (job), error); - g_error_free (error); -+ g_object_unref (entry); - goto out; - } - -@@ -1373,9 +1374,9 @@ g_vfs_backend_google_delete (GVfsBackend *_self, - insert_entry (self, GDATA_ENTRY (new_entry)); - g_hash_table_foreach (self->monitors, emit_delete_event, entry_path); - g_vfs_job_succeeded (G_VFS_JOB (job)); -+ g_object_unref (entry); - - out: -- g_object_unref (entry); - g_clear_object (&new_entry); - g_free (entry_path); - g_debug ("- delete\n"); --- -2.36.1 - - -From d842aa6c729866343d7a3b0514a6574c01be30ed Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Fri, 29 Jan 2021 14:06:16 +0100 -Subject: [PATCH 14/14] google: Increase number of results in batches for - better performance - -Currently, only 50 results are returned in one batch, which means that -multiple network requests are needed for folders with a lot files, which -makes it slow. I am not sure there was some reason for this limitation -earlier (e.g. before the cache rework), however, I don't see any -rationals for it currently. Let's increase this to its maximum for -better performance. ---- - daemon/gvfsbackendgoogle.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c -index 230b89eb..f97c038c 100644 ---- a/daemon/gvfsbackendgoogle.c -+++ b/daemon/gvfsbackendgoogle.c -@@ -79,8 +79,6 @@ G_DEFINE_TYPE(GVfsBackendGoogle, g_vfs_backend_google, G_VFS_TYPE_BACKEND) - - #define CONTENT_TYPE_PREFIX_GOOGLE "application/vnd.google-apps" - --#define MAX_RESULTS 50 -- - #define REBUILD_ENTRIES_TIMEOUT 60 /* s */ - - #define URI_PREFIX "https://www.googleapis.com/drive/v2/files/" -@@ -595,7 +593,7 @@ rebuild_dir (GVfsBackendGoogle *self, - parent_id = g_strdup (gdata_entry_get_id (parent)); - - search = g_strdup_printf ("'%s' in parents", parent_id); -- query = gdata_documents_query_new_with_limits (search, 1, MAX_RESULTS); -+ query = gdata_documents_query_new_with_limits (search, 1, G_MAXUINT); - gdata_documents_query_set_show_folders (query, TRUE); - g_free (search); - --- -2.36.1 - diff --git a/SOURCES/gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch b/SOURCES/gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch deleted file mode 100644 index cebad56..0000000 --- a/SOURCES/gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch +++ /dev/null @@ -1,92 +0,0 @@ -From e3808a1b4042761055b1d975333a8243d67b8bfe Mon Sep 17 00:00:00 2001 -From: Simon McVittie -Date: Wed, 5 Jun 2019 13:33:38 +0100 -Subject: [PATCH] gvfsdaemon: Check that the connecting client is the same user - -Otherwise, an attacker who learns the abstract socket address from -netstat(8) or similar could connect to it and issue D-Bus method -calls. - -Signed-off-by: Simon McVittie ---- - daemon/gvfsdaemon.c | 36 +++++++++++++++++++++++++++++++++++- - 1 file changed, 35 insertions(+), 1 deletion(-) - -diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c -index 406d4f8e..be148a7b 100644 ---- a/daemon/gvfsdaemon.c -+++ b/daemon/gvfsdaemon.c -@@ -79,6 +79,7 @@ struct _GVfsDaemon - - gint mount_counter; - -+ GDBusAuthObserver *auth_observer; - GDBusConnection *conn; - GVfsDBusDaemon *daemon_skeleton; - GVfsDBusMountable *mountable_skeleton; -@@ -171,6 +172,8 @@ g_vfs_daemon_finalize (GObject *object) - } - if (daemon->conn != NULL) - g_object_unref (daemon->conn); -+ if (daemon->auth_observer != NULL) -+ g_object_unref (daemon->auth_observer); - - g_hash_table_destroy (daemon->registered_paths); - g_hash_table_destroy (daemon->client_connections); -@@ -236,6 +239,35 @@ name_vanished_handler (GDBusConnection *connection, - daemon->lost_main_daemon = TRUE; - } - -+/* -+ * Authentication observer signal handler that authorizes connections -+ * from the same uid as this process. This matches the behaviour of a -+ * libdbus DBusServer/DBusConnection when no DBusAllowUnixUserFunction -+ * has been set, but is not the default in GDBus. -+ */ -+static gboolean -+authorize_authenticated_peer_cb (GDBusAuthObserver *observer, -+ G_GNUC_UNUSED GIOStream *stream, -+ GCredentials *credentials, -+ G_GNUC_UNUSED gpointer user_data) -+{ -+ gboolean authorized = FALSE; -+ -+ if (credentials != NULL) -+ { -+ GCredentials *own_credentials; -+ -+ own_credentials = g_credentials_new (); -+ -+ if (g_credentials_is_same_user (credentials, own_credentials, NULL)) -+ authorized = TRUE; -+ -+ g_object_unref (own_credentials); -+ } -+ -+ return authorized; -+} -+ - static void - g_vfs_daemon_init (GVfsDaemon *daemon) - { -@@ -265,6 +297,8 @@ g_vfs_daemon_init (GVfsDaemon *daemon) - - daemon->conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); - g_assert (daemon->conn != NULL); -+ daemon->auth_observer = g_dbus_auth_observer_new (); -+ g_signal_connect (daemon->auth_observer, "authorize-authenticated-peer", G_CALLBACK (authorize_authenticated_peer_cb), NULL); - - daemon->daemon_skeleton = gvfs_dbus_daemon_skeleton_new (); - g_signal_connect (daemon->daemon_skeleton, "handle-get-connection", G_CALLBACK (handle_get_connection), daemon); -@@ -876,7 +910,7 @@ handle_get_connection (GVfsDBusDaemon *object, - server = g_dbus_server_new_sync (address1, - G_DBUS_SERVER_FLAGS_NONE, - guid, -- NULL, /* GDBusAuthObserver */ -+ daemon->auth_observer, - NULL, /* GCancellable */ - &error); - g_free (guid); --- -2.21.0 - diff --git a/SOURCES/smb-Ignore-EINVAL-for-kerberos-login.patch b/SOURCES/smb-Ignore-EINVAL-for-kerberos-login.patch deleted file mode 100644 index aa42bd9..0000000 --- a/SOURCES/smb-Ignore-EINVAL-for-kerberos-login.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c -index 33d1a209..776b67bc 100644 ---- a/daemon/gvfsbackendsmb.c -+++ b/daemon/gvfsbackendsmb.c -@@ -513,7 +513,13 @@ do_mount (GVfsBackend *backend, - if (res == 0) - break; - -- if (op_backend->mount_cancelled || (errsv != EACCES && errsv != EPERM)) -+ if (errsv == EINVAL && op_backend->mount_try == 0 && op_backend->user == NULL) -+ { -+ /* EINVAL is "expected" when kerberos/ccache is misconfigured, see: -+ * https://gitlab.gnome.org/GNOME/gvfs/-/issues/611 -+ */ -+ } -+ else if (op_backend->mount_cancelled || (errsv != EACCES && errsv != EPERM)) - { - g_debug ("do_mount - (errno != EPERM && errno != EACCES), cancelled = %d, breaking\n", op_backend->mount_cancelled); - break; -diff --git a/daemon/gvfsbackendsmbbrowse.c b/daemon/gvfsbackendsmbbrowse.c -index 57bae9db..7e8facfb 100644 ---- a/daemon/gvfsbackendsmbbrowse.c -+++ b/daemon/gvfsbackendsmbbrowse.c -@@ -967,8 +967,14 @@ do_mount (GVfsBackend *backend, - uri, op_backend->mount_try, dir, op_backend->mount_cancelled, - errsv, g_strerror (errsv)); - -- if (dir == NULL && -- (op_backend->mount_cancelled || (errsv != EPERM && errsv != EACCES))) -+ if (errsv == EINVAL && op_backend->mount_try == 0 && op_backend->user == NULL) -+ { -+ /* EINVAL is "expected" when kerberos is misconfigured, see: -+ * https://gitlab.gnome.org/GNOME/gvfs/-/issues/611 -+ */ -+ } -+ else if (dir == NULL && -+ (op_backend->mount_cancelled || (errsv != EPERM && errsv != EACCES))) - { - g_debug ("do_mount - (errno != EPERM && errno != EACCES), cancelled = %d, breaking\n", op_backend->mount_cancelled); - break; --- -2.35.1 - diff --git a/SOURCES/smb-Improve-enumeration-performance.patch b/SOURCES/smb-Improve-enumeration-performance.patch deleted file mode 100644 index 9019b0a..0000000 --- a/SOURCES/smb-Improve-enumeration-performance.patch +++ /dev/null @@ -1,115 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index daeee728..689667e5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -551,6 +551,11 @@ if test "x$enable_samba" != "xno"; then - AC_DEFINE(HAVE_SMBC_SETOPTIONPROTOCOLS, 1, [Define to 1 if smbc_setOptionProtocols() is available]), - [] - ) -+ -+ AC_CHECK_LIB(smbclient, smbc_readdirplus2, -+ AC_DEFINE(HAVE_SMBC_READDIRPLUS2, 1, [Define to 1 if smbc_readdirplus2() is available]), -+ [] -+ ) - fi - fi - -diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c -index 9571fa0d..ce151648 100644 ---- a/daemon/gvfsbackendsmb.c -+++ b/daemon/gvfsbackendsmb.c -@@ -1738,25 +1738,34 @@ do_enumerate (GVfsBackend *backend, - GFileQueryInfoFlags flags) - { - GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend); -- struct stat st; -- int res; -+ struct stat st = { 0 }; - GError *error; - SMBCFILE *dir; -- char dirents[1024*4]; -- struct smbc_dirent *dirp; - GFileInfo *info; - GString *uri; -- int uri_start_len; - smbc_opendir_fn smbc_opendir; -+ smbc_closedir_fn smbc_closedir; -+#ifndef HAVE_SMBC_READDIRPLUS2 -+ int res; -+ char dirents[1024*4]; -+ struct smbc_dirent *dirp; -+ int uri_start_len; - smbc_getdents_fn smbc_getdents; - smbc_stat_fn smbc_stat; -- smbc_closedir_fn smbc_closedir; -+#else -+ smbc_readdirplus2_fn smbc_readdirplus2; -+ const struct libsmb_file_info *exstat; -+#endif - - uri = create_smb_uri_string (op_backend->server, op_backend->port, op_backend->share, filename); - - smbc_opendir = smbc_getFunctionOpendir (op_backend->smb_context); -+#ifndef HAVE_SMBC_READDIRPLUS2 - smbc_getdents = smbc_getFunctionGetdents (op_backend->smb_context); - smbc_stat = smbc_getFunctionStat (op_backend->smb_context); -+#else -+ smbc_readdirplus2 = smbc_getFunctionReaddirPlus2 (op_backend->smb_context); -+#endif - smbc_closedir = smbc_getFunctionClosedir (op_backend->smb_context); - - dir = smbc_opendir (op_backend->smb_context, uri->str); -@@ -1776,6 +1785,8 @@ do_enumerate (GVfsBackend *backend, - - if (uri->str[uri->len - 1] != '/') - g_string_append_c (uri, '/'); -+ -+#ifndef HAVE_SMBC_READDIRPLUS2 - uri_start_len = uri->len; - - while (TRUE) -@@ -1827,9 +1838,27 @@ do_enumerate (GVfsBackend *backend, - dirp = (struct smbc_dirent *) (((char *)dirp) + dirlen); - res -= dirlen; - } -+ } -+#else -+ while ((exstat = smbc_readdirplus2 (op_backend->smb_context, dir, &st)) != NULL) -+ { -+ if ((S_ISREG (st.st_mode) || -+ S_ISDIR (st.st_mode) || -+ S_ISLNK (st.st_mode)) && -+ g_strcmp0 (exstat->name, ".") != 0 && -+ g_strcmp0 (exstat->name, "..") != 0) -+ { -+ info = g_file_info_new (); -+ set_info_from_stat (op_backend, info, &st, exstat->name, matcher); -+ g_vfs_job_enumerate_add_info (job, info); -+ g_object_unref (info); -+ } -+ -+ memset (&st, 0, sizeof (struct stat)); - } -- -- res = smbc_closedir (op_backend->smb_context, dir); -+#endif -+ -+ smbc_closedir (op_backend->smb_context, dir); - - g_vfs_job_enumerate_done (job); - -diff --git a/meson.build b/meson.build -index 6ae768d9..d3f59457 100644 ---- a/meson.build -+++ b/meson.build -@@ -418,6 +418,7 @@ if enable_samba - smbclient_dep = dependency('smbclient') - - config_h.set('HAVE_SMBC_SETOPTIONPROTOCOLS', cc.has_function('smbc_setOptionProtocols', dependencies: smbclient_dep)) -+ config_h.set('HAVE_SMBC_READDIRPLUS2', cc.has_function('smbc_readdirplus2', dependencies: smbclient_dep)) - endif - - # *** Check for libarchive *** --- -2.26.2 - diff --git a/SOURCES/smb-Rework-anonymous-handling-to-avoid-EINVAL.patch b/SOURCES/smb-Rework-anonymous-handling-to-avoid-EINVAL.patch deleted file mode 100644 index 3486aa7..0000000 --- a/SOURCES/smb-Rework-anonymous-handling-to-avoid-EINVAL.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c -index 776b67bc..a1e3eacd 100644 ---- a/daemon/gvfsbackendsmb.c -+++ b/daemon/gvfsbackendsmb.c -@@ -80,7 +80,6 @@ struct _GVfsBackendSmb - int mount_try; - gboolean mount_try_again; - gboolean mount_cancelled; -- gboolean use_anonymous; - - gboolean password_in_keyring; - GPasswordSave password_save; -@@ -215,13 +214,6 @@ auth_callback (SMBCCTX *context, - backend->mount_try_again = TRUE; - g_debug ("auth_callback - kerberos pass\n"); - } -- else if (backend->use_anonymous) -- { -- /* Try again if anonymous login fails */ -- backend->use_anonymous = FALSE; -- backend->mount_try_again = TRUE; -- g_debug ("auth_callback - anonymous login pass\n"); -- } - else - { - gboolean in_keyring = FALSE; -@@ -304,10 +296,13 @@ auth_callback (SMBCCTX *context, - /* Try again if this fails */ - backend->mount_try_again = TRUE; - -+ smbc_setOptionNoAutoAnonymousLogin (backend->smb_context, -+ !anonymous); -+ - if (anonymous) - { -- backend->use_anonymous = TRUE; - backend->password_save = FALSE; -+ g_debug ("auth_callback - anonymous enabled\n"); - } - else - { -@@ -535,12 +530,6 @@ do_mount (GVfsBackend *backend, - smbc_setOptionFallbackAfterKerberos (op_backend->smb_context, 1); - } - -- /* If the AskPassword reply requested anonymous login, enable the -- * anonymous fallback and try again. -- */ -- smbc_setOptionNoAutoAnonymousLogin (op_backend->smb_context, -- !op_backend->use_anonymous); -- - op_backend->mount_try ++; - } - while (op_backend->mount_try_again); --- -2.36.0 - diff --git a/SOURCES/smb-Use-O_RDWR-to-fix-fstat-when-writing.patch b/SOURCES/smb-Use-O_RDWR-to-fix-fstat-when-writing.patch deleted file mode 100644 index 2142250..0000000 --- a/SOURCES/smb-Use-O_RDWR-to-fix-fstat-when-writing.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3f6f906c7c7b28dc30edb98200b6e13e1a513bb4 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Wed, 9 May 2018 12:54:59 +0200 -Subject: [PATCH] smb: Use O_RDWR to fix fstat when writing - -fstat fails with EINVAL on Windows servers if O_WRONLY is used to open -(though it works properly on SAMBA servers). O_RDWR is needed to make -it work. This causes issues when copying files over gvfsd-fuse among -others. - -https://bugzilla.gnome.org/show_bug.cgi?id=795805 ---- - daemon/gvfsbackendsmb.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c -index d4944197..9571fa0d 100644 ---- a/daemon/gvfsbackendsmb.c -+++ b/daemon/gvfsbackendsmb.c -@@ -808,7 +808,7 @@ do_create (GVfsBackend *backend, - smbc_open = smbc_getFunctionOpen (op_backend->smb_context); - errno = 0; - file = smbc_open (op_backend->smb_context, uri, -- O_CREAT|O_WRONLY|O_EXCL, 0666); -+ O_CREAT|O_RDWR|O_EXCL, 0666); - g_free (uri); - - if (file == NULL) -@@ -850,7 +850,7 @@ do_append_to (GVfsBackend *backend, - smbc_open = smbc_getFunctionOpen (op_backend->smb_context); - errno = 0; - file = smbc_open (op_backend->smb_context, uri, -- O_CREAT|O_WRONLY|O_APPEND, 0666); -+ O_CREAT|O_RDWR|O_APPEND, 0666); - g_free (uri); - - if (file == NULL) -@@ -916,7 +916,7 @@ open_tmpfile (GVfsBackendSmb *backend, - smbc_open = smbc_getFunctionOpen (backend->smb_context); - errno = 0; - file = smbc_open (backend->smb_context, tmp_uri, -- O_CREAT|O_WRONLY|O_EXCL, 0666); -+ O_CREAT|O_RDWR|O_EXCL, 0666); - } while (file == NULL && errno == EEXIST); - - g_free (dir_uri); -@@ -1040,7 +1040,7 @@ do_replace (GVfsBackend *backend, - - errno = 0; - file = smbc_open (op_backend->smb_context, uri, -- O_CREAT|O_WRONLY|O_EXCL, 0); -+ O_CREAT|O_RDWR|O_EXCL, 0); - if (file == NULL && errno != EEXIST) - { - int errsv = fixup_open_errno (errno); -@@ -1110,7 +1110,7 @@ do_replace (GVfsBackend *backend, - - errno = 0; - file = smbc_open (op_backend->smb_context, uri, -- O_CREAT|O_WRONLY|O_TRUNC, 0); -+ O_CREAT|O_RDWR|O_TRUNC, 0); - if (file == NULL) - { - int errsv = fixup_open_errno (errno); --- -2.35.3 - diff --git a/SOURCES/smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch b/SOURCES/smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch deleted file mode 100644 index 4bf9934..0000000 --- a/SOURCES/smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch +++ /dev/null @@ -1,89 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index 3b5836ff..daeee728 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -546,6 +546,11 @@ if test "x$enable_samba" != "xno"; then - if test "x$msg_samba" = "xyes"; then - PKG_CHECK_MODULES([SAMBA], [smbclient]) - AC_DEFINE([HAVE_SAMBA], 1, [Define to 1 if you have the samba libraries]) -+ -+ AC_CHECK_LIB(smbclient, smbc_setOptionProtocols, -+ AC_DEFINE(HAVE_SMBC_SETOPTIONPROTOCOLS, 1, [Define to 1 if smbc_setOptionProtocols() is available]), -+ [] -+ ) - fi - fi - -diff --git a/daemon/gvfsbackendsmbbrowse.c b/daemon/gvfsbackendsmbbrowse.c -index f08d2988..3b11883e 100644 ---- a/daemon/gvfsbackendsmbbrowse.c -+++ b/daemon/gvfsbackendsmbbrowse.c -@@ -45,6 +45,7 @@ - #include "gvfskeyring.h" - #include "gmounttracker.h" - #include "gvfsbackendsmbprivate.h" -+#include "gvfsutils.h" - - #include - -@@ -847,6 +848,47 @@ do_mount (GVfsBackend *backend, - else - op_backend->server = g_strdup (op_backend->mounted_server); - -+#ifdef HAVE_SMBC_SETOPTIONPROTOCOLS -+ /* Force NT1 protocol version if server can't be resolved (i.e. is not -+ * hostname, nor IP address). This is needed for workgroup support, because -+ * "client max protocol" has been changed from NT1 to SMB3 in recent samba -+ * versions. -+ */ -+ -+ if (op_backend->server != NULL) -+ { -+ GResolver *resolver; -+ GList *addresses; -+ GError *error = NULL; -+ gchar *server; -+ -+ resolver = g_resolver_get_default (); -+ -+ /* IPv6 server includes brackets in GMountSpec, GResolver doesn't */ -+ if (gvfs_is_ipv6 (op_backend->server)) -+ server = g_strndup (op_backend->server + 1, strlen (op_backend->server) - 2); -+ else -+ server = g_strdup (op_backend->server); -+ -+ addresses = g_resolver_lookup_by_name (resolver, server, NULL, &error); -+ if (addresses == NULL) -+ { -+ if (error != NULL) -+ { -+ g_debug ("%s\n", error->message); -+ g_error_free (error); -+ } -+ -+ g_debug ("Forcing NT1 protocol version\n"); -+ smbc_setOptionProtocols (smb_context, "NT1", "NT1"); -+ } -+ -+ g_resolver_free_addresses (addresses); -+ g_object_unref (resolver); -+ g_free (server); -+ } -+#endif -+ - icon = NULL; - symbolic_icon = NULL; - if (op_backend->server == NULL) -diff --git a/meson.build b/meson.build -index 34600188..3a876172 100644 ---- a/meson.build -+++ b/meson.build -@@ -416,6 +416,8 @@ config_h.set10('HAVE_LIBUSB', enable_libusb) - enable_samba = get_option('smb') - if enable_samba - smbclient_dep = dependency('smbclient') -+ -+ config_h.set('HAVE_SMBC_SETOPTIONPROTOCOLS', cc.has_function('smbc_setOptionProtocols', dependencies: smbclient_dep)) - endif - - # *** Check for libarchive *** diff --git a/SOURCES/trash-Add-support-for-x-gvfs-notrash-option-to-ignor.patch b/SOURCES/trash-Add-support-for-x-gvfs-notrash-option-to-ignor.patch deleted file mode 100644 index 88a7df3..0000000 --- a/SOURCES/trash-Add-support-for-x-gvfs-notrash-option-to-ignor.patch +++ /dev/null @@ -1,65 +0,0 @@ -From f93bd46c36c8e42f17f0f61b79c55a3794906395 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Fri, 6 Mar 2020 10:08:09 +0100 -Subject: [PATCH] trash: Add support for x-gvfs-notrash option to ignore mounts - -Add support for x-gvfs-notrash mount option, which allows to ignore -trash folder on certain mounts. This might be especially useful e.g. -to prevent wakeups of autofs mounts... - -https://bugzilla.redhat.com/show_bug.cgi?id=1096200 ---- - daemon/trashlib/trashwatcher.c | 30 +++++++++++++++++++++++++++++- - 1 file changed, 29 insertions(+), 1 deletion(-) - -diff --git a/daemon/trashlib/trashwatcher.c b/daemon/trashlib/trashwatcher.c -index 6b455235..01c440a1 100644 ---- a/daemon/trashlib/trashwatcher.c -+++ b/daemon/trashlib/trashwatcher.c -@@ -211,6 +211,34 @@ trash_mount_remove (TrashMount **mount_ptr) - g_slice_free (TrashMount, mount); - } - -+static gboolean -+ignore_trash_mount (GUnixMountEntry *mount) -+{ -+ GUnixMountPoint *mount_point = NULL; -+ const gchar *mount_options; -+ gboolean retval = TRUE; -+ -+ if (g_unix_mount_is_system_internal (mount)) -+ return TRUE; -+ -+ mount_options = g_unix_mount_get_options (mount); -+ if (mount_options == NULL) -+ { -+ mount_point = g_unix_mount_point_at (g_unix_mount_get_mount_path (mount), -+ NULL); -+ if (mount_point != NULL) -+ mount_options = g_unix_mount_point_get_options (mount_point); -+ } -+ -+ if (mount_options == NULL || -+ strstr (mount_options, "x-gvfs-notrash") == NULL) -+ retval = FALSE; -+ -+ g_clear_pointer (&mount_point, g_unix_mount_point_free); -+ -+ return retval; -+} -+ - static void - trash_watcher_remount (TrashWatcher *watcher) - { -@@ -229,7 +257,7 @@ trash_watcher_remount (TrashWatcher *watcher) - { - int result; - -- if (new && g_unix_mount_is_system_internal (new->data)) -+ if (new && ignore_trash_mount (new->data)) - { - g_unix_mount_free (new->data); - new = new->next; --- -2.41.0 - diff --git a/SOURCES/trash-Sync-trash-dir-items-when-files-change.patch b/SOURCES/trash-Sync-trash-dir-items-when-files-change.patch deleted file mode 100644 index 34ae2ee..0000000 --- a/SOURCES/trash-Sync-trash-dir-items-when-files-change.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 41862c0179f834d8bc3bd84ce78ee495050f2676 Mon Sep 17 00:00:00 2001 -From: rong wang -Date: Thu, 23 Mar 2023 10:26:24 +0800 -Subject: [PATCH] trash: Sync trash dir items when files change - -In the case of an application monitoring the trash can, delete a file -on the mounted device to the trash can, and then unmount the device. -At this time, if you check the status of the trash can, you will find -that the number of files queried is inconsistent with the number of -files obtained through the enumeration job. This is because the number -of files queried includes some files that do not exist when the device -is unmounted. The solution is to synchronize the status of the trash -can in time to ensure that the trash can does not record files that do -not exist. ---- - daemon/trashlib/trashdir.c | 21 +++++++++++++++++++-- - 1 file changed, 19 insertions(+), 2 deletions(-) - -diff --git a/daemon/trashlib/trashdir.c b/daemon/trashlib/trashdir.c -index c470d3bd..0d7d2b1b 100644 ---- a/daemon/trashlib/trashdir.c -+++ b/daemon/trashlib/trashdir.c -@@ -163,10 +163,27 @@ trash_dir_changed (GFileMonitor *monitor, - TrashDir *dir = user_data; - - if (event_type == G_FILE_MONITOR_EVENT_CREATED) -- trash_root_add_item (dir->root, file, dir->topdir, dir->is_homedir); -+ { -+ dir->items = g_slist_insert_sorted (dir->items, -+ g_object_ref (file), -+ (GCompareFunc) compare_basename); -+ trash_root_add_item (dir->root, file, dir->topdir, dir->is_homedir); -+ } - - else if (event_type == G_FILE_MONITOR_EVENT_DELETED) -- trash_root_remove_item (dir->root, file, dir->is_homedir); -+ { -+ GSList *node; -+ -+ node = g_slist_find_custom (dir->items, -+ file, -+ (GCompareFunc) compare_basename); -+ if (node) -+ { -+ g_object_unref (node->data); -+ dir->items = g_slist_delete_link (dir->items, node); -+ } -+ trash_root_remove_item (dir->root, file, dir->is_homedir); -+ } - - else if (event_type == G_FILE_MONITOR_EVENT_PRE_UNMOUNT || - event_type == G_FILE_MONITOR_EVENT_UNMOUNTED || --- -2.41.0 - diff --git a/SOURCES/udisks2-Fix-crashes-caused-by-missing-source-tag.patch b/SOURCES/udisks2-Fix-crashes-caused-by-missing-source-tag.patch deleted file mode 100644 index 07c0c97..0000000 --- a/SOURCES/udisks2-Fix-crashes-caused-by-missing-source-tag.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 38831e4ea149a0b4731d123c63d8b493d30ad0be Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Sat, 26 May 2018 08:16:02 +0200 -Subject: [PATCH] udisks2: Fix crashes caused by missing source tag - -GAsyncReadyCallback is never called from g_drive_stop, because -source_tag is not set, but checked. This obviously causes issues -for client applications. Add missing source_tag. - -Closes: https://gitlab.gnome.org/GNOME/gvfs/issues/1 ---- - monitor/udisks2/gvfsudisks2drive.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/monitor/udisks2/gvfsudisks2drive.c b/monitor/udisks2/gvfsudisks2drive.c -index 52e9b75e..87656688 100644 ---- a/monitor/udisks2/gvfsudisks2drive.c -+++ b/monitor/udisks2/gvfsudisks2drive.c -@@ -915,6 +915,7 @@ gvfs_udisks2_drive_stop (GDrive *_drive, - GTask *task; - - task = g_task_new (drive, cancellable, callback, user_data); -+ g_task_set_source_tag (task, gvfs_udisks2_drive_stop); - - /* This information is needed in GVfsDdisks2Volume when apps have - * open files on the device ... we need to know if the button should --- -2.23.0 - diff --git a/SOURCES/udisks2-Handle-lockdown-option-to-disable-writing.patch b/SOURCES/udisks2-Handle-lockdown-option-to-disable-writing.patch deleted file mode 100644 index deb4da3..0000000 --- a/SOURCES/udisks2-Handle-lockdown-option-to-disable-writing.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 9fdd59cfda93b508e76770146a8295d0a26b175d Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 14 May 2019 08:46:48 +0200 -Subject: [PATCH 1/3] udisks2: Handle lockdown option to disable writing - -Handle the new mount-removable-storage-devices-as-read-only option of -org.gnome.desktop.lockdown schema and mount removable devices as read-only -if enabled. ---- - monitor/udisks2/gvfsudisks2volume.c | 8 +++++ - monitor/udisks2/gvfsudisks2volumemonitor.c | 34 ++++++++++++++++++++++ - monitor/udisks2/gvfsudisks2volumemonitor.h | 1 + - 3 files changed, 43 insertions(+) - -diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c -index a509b5dd..b2545058 100644 ---- a/monitor/udisks2/gvfsudisks2volume.c -+++ b/monitor/udisks2/gvfsudisks2volume.c -@@ -1093,6 +1093,7 @@ do_mount (GTask *task) - { - MountData *data = g_task_get_task_data (task); - GVariantBuilder builder; -+ GVfsUDisks2Volume *volume = g_task_get_source_object (task); - - g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - if (data->mount_operation == NULL) -@@ -1101,6 +1102,13 @@ do_mount (GTask *task) - "{sv}", - "auth.no_user_interaction", g_variant_new_boolean (TRUE)); - } -+ if (gvfs_udisks2_volume_monitor_get_readonly_lockdown (volume->monitor)) -+ { -+ g_variant_builder_add (&builder, -+ "{sv}", -+ "options", g_variant_new_string ("ro")); -+ -+ } - udisks_filesystem_call_mount (data->filesystem_to_mount, - g_variant_builder_end (&builder), - g_task_get_cancellable (task), -diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.c b/monitor/udisks2/gvfsudisks2volumemonitor.c -index 0a5ce96e..37c81fcf 100644 ---- a/monitor/udisks2/gvfsudisks2volumemonitor.c -+++ b/monitor/udisks2/gvfsudisks2volumemonitor.c -@@ -65,6 +65,9 @@ struct _GVfsUDisks2VolumeMonitor - /* we keep volumes/mounts for blank and audio discs separate to handle e.g. mixed discs properly */ - GList *disc_volumes; - GList *disc_mounts; -+ -+ GSettings *lockdown_settings; -+ gboolean readonly_lockdown; - }; - - static UDisksClient *get_udisks_client_sync (GError **error); -@@ -140,6 +143,8 @@ gvfs_udisks2_volume_monitor_finalize (GObject *object) - g_list_free_full (monitor->disc_volumes, g_object_unref); - g_list_free_full (monitor->disc_mounts, g_object_unref); - -+ g_clear_object (&monitor->lockdown_settings); -+ - G_OBJECT_CLASS (gvfs_udisks2_volume_monitor_parent_class)->finalize (object); - } - -@@ -304,6 +309,17 @@ gvfs_udisks2_volume_monitor_constructor (GType type, - return ret; - } - -+static void -+lockdown_settings_changed (GSettings *settings, -+ gchar *key, -+ gpointer user_data) -+{ -+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data); -+ -+ monitor->readonly_lockdown = g_settings_get_boolean (settings, -+ "mount-removable-storage-devices-as-read-only"); -+} -+ - static void - gvfs_udisks2_volume_monitor_init (GVfsUDisks2VolumeMonitor *monitor) - { -@@ -325,6 +341,15 @@ gvfs_udisks2_volume_monitor_init (GVfsUDisks2VolumeMonitor *monitor) - G_CALLBACK (mountpoints_changed), - monitor); - -+ monitor->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown"); -+ monitor->readonly_lockdown = g_settings_get_boolean (monitor->lockdown_settings, -+ "mount-removable-storage-devices-as-read-only"); -+ g_signal_connect_object (monitor->lockdown_settings, -+ "changed", -+ G_CALLBACK (lockdown_settings_changed), -+ monitor, -+ 0); -+ - update_all (monitor, FALSE, TRUE); - } - -@@ -388,6 +413,15 @@ gvfs_udisks2_volume_monitor_get_gudev_client (GVfsUDisks2VolumeMonitor *monitor) - - /* ---------------------------------------------------------------------------------------------------- */ - -+gboolean -+gvfs_udisks2_volume_monitor_get_readonly_lockdown (GVfsUDisks2VolumeMonitor *monitor) -+{ -+ g_return_val_if_fail (GVFS_IS_UDISKS2_VOLUME_MONITOR (monitor), FALSE); -+ return monitor->readonly_lockdown; -+} -+ -+/* ---------------------------------------------------------------------------------------------------- */ -+ - void - gvfs_udisks2_volume_monitor_update (GVfsUDisks2VolumeMonitor *monitor) - { -diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.h b/monitor/udisks2/gvfsudisks2volumemonitor.h -index 7f0215dc..751a0236 100644 ---- a/monitor/udisks2/gvfsudisks2volumemonitor.h -+++ b/monitor/udisks2/gvfsudisks2volumemonitor.h -@@ -49,6 +49,7 @@ GVolumeMonitor *gvfs_udisks2_volume_monitor_new (void); - UDisksClient *gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor); - void gvfs_udisks2_volume_monitor_update (GVfsUDisks2VolumeMonitor *monitor); - GUdevClient *gvfs_udisks2_volume_monitor_get_gudev_client (GVfsUDisks2VolumeMonitor *monitor); -+gboolean gvfs_udisks2_volume_monitor_get_readonly_lockdown (GVfsUDisks2VolumeMonitor *monitor); - - G_END_DECLS - --- -2.21.0 - diff --git a/SOURCES/daemon-Add-support-for-edit-mode.patch b/daemon-Add-support-for-edit-mode.patch similarity index 100% rename from SOURCES/daemon-Add-support-for-edit-mode.patch rename to daemon-Add-support-for-edit-mode.patch diff --git a/SOURCES/fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch b/fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch similarity index 100% rename from SOURCES/fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch rename to fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch diff --git a/SOURCES/gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch b/gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch similarity index 100% rename from SOURCES/gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch rename to gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch diff --git a/SPECS/gvfs.spec b/gvfs.spec similarity index 78% rename from SPECS/gvfs.spec rename to gvfs.spec index 87edc9c..73a886d 100644 --- a/SPECS/gvfs.spec +++ b/gvfs.spec @@ -1,109 +1,63 @@ -%define _unpackaged_files_terminate_build 0 - %global avahi_version 0.6 -%global fuse_version 2.8.0 -%global gettext_version 0.19.4 -%global glib2_version 2.56.4-162 +%global fuse_version 3.0.0 +%global glib2_version 2.70.0 +%global gsettings_desktop_schemas_version 3.33.0 %global goa_version 3.17.1 -%global gsettings_desktop_schemas_version 3.28.1-2 %global gudev_version 147 %global libarchive_version 3.0.22 %global libcdio_paranoia_version 0.78.2 %global libgcrypt_version 1.2.2 -%global libgdata_version 0.17.9 +%global libgdata_version 0.18.0 %global libgphoto2_version 2.5.0 %global libimobiledevice_version 1.2 -%global libmtp_version 1.1.12 +%global libmtp_version 1.1.15 %global libnfs_version 1.9.8 -%global libplist_version 0.15 -%global libsmbclient_version 3.4.0 -%global libsoup_version 2.42.0 +%global libplist_version 2.2 +%global libsmbclient_version 4.12.0 +%global libsoup_version 3.0.0 %global libusb_version 1.0.21 %global systemd_version 206 %global talloc_version 1.3.0 %global udisks2_version 1.97 -Name: gvfs -Version: 1.36.2 -Release: 18%{?dist} +Name: gvfs +Version: 1.54.4 +Release: 2%{?dist} Summary: Backends for the gio framework in GLib -License: GPLv3 and LGPLv2+ and BSD and MPLv2.0 -URL: https://wiki.gnome.org/Projects/gvfs -Source0: https://download.gnome.org/sources/gvfs/1.36/gvfs-%{version}.tar.xz +License: LGPL-2.0-or-later AND GPL-3.0-only AND MPL-2.0 AND BSD-3-Clause-Sun -# https://bugzilla.redhat.com/show_bug.cgi?id=1673888 -Patch0: admin-Prevent-access-if-any-authentication-agent-isn.patch +URL: https://wiki.gnome.org/Projects/gvfs +Source0: https://download.gnome.org/sources/gvfs/1.54/gvfs-%{version}.tar.xz -# https://bugzilla.redhat.com/show_bug.cgi?id=1662193 -Patch1: udisks2-Handle-lockdown-option-to-disable-writing.patch -Patch2: daemon-Handle-lockdown-option-to-disable-writing.patch +# https://issues.redhat.com/browse/RHEL-52355 +Patch: trash-Add-support-for-x-gvfs-trash-mount-option.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1729885 -Patch3: gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch +# https://issues.redhat.com/browse/RHEL-71089 +Patch: daemon-Add-support-for-edit-mode.patch +Patch: gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch +Patch: fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch +Patch: smb-Fail-when-initial_offset-can-t-be-determined.patch +Patch: smb-Disable-seek-support-when-appening.patch +Patch: smb-Fix-offset-after-truncate-when-appending.patch +Patch: smb-Implement-support-for-edit-mode.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1739117 -Patch4: daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=1739116 -Patch5: smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=1754506 -Patch6: admin-Add-query_info_on_read-write-functionality.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=1752926 -Patch7: admin-Use-fsuid-to-ensure-correct-file-ownership.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=1753972 -Patch8: admin-Ensure-correct-ownership-when-moving-to-file-u.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=1759075 -Patch9: udisks2-Fix-crashes-caused-by-missing-source-tag.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=1569868 -Patch10: smb-Improve-enumeration-performance.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=1889411 -Patch11: goa-Add-support-for-certificate-prompts.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=2095712 -Patch12: smb-Ignore-EINVAL-for-kerberos-login.patch -Patch13: smb-Rework-anonymous-handling-to-avoid-EINVAL.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=2080478 -Patch14: smb-Use-O_RDWR-to-fix-fstat-when-writing.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=2083481 -Patch15: google-performance-fixes.patch - -# https://issues.redhat.com/browse/RHEL-2824 -Patch16: trash-Add-support-for-x-gvfs-notrash-option-to-ignor.patch -Patch17: trash-Sync-trash-dir-items-when-files-change.patch - -# https://issues.redhat.com/browse/RHEL-52342 -Patch18: trash-Add-support-for-x-gvfs-trash-mount-option.patch - -# https://issues.redhat.com/browse/RHEL-45163 -Patch19: daemon-Add-support-for-edit-mode.patch -Patch20: gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch -Patch21: fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch -Patch22: smb-Fail-when-initial_offset-can-t-be-determined.patch -Patch23: smb-Disable-seek-support-when-appening.patch -Patch24: smb-Fix-offset-after-truncate-when-appending.patch -Patch25: smb-Implement-support-for-edit-mode.patch - -BuildRequires: pkgconfig +BuildRequires: meson +BuildRequires: gcc BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version} -BuildRequires: pkgconfig(dbus-glib-1) -BuildRequires: pkgconfig(gcr-3) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(gcr-4) +BuildRequires: pkgconfig(gsettings-desktop-schemas) >= %{gsettings_desktop_schemas_version} BuildRequires: /usr/bin/ssh +%if ! (0%{?rhel} >= 10) BuildRequires: pkgconfig(libcdio_paranoia) >= %{libcdio_paranoia_version} +%endif BuildRequires: pkgconfig(gudev-1.0) >= %{gudev_version} -BuildRequires: pkgconfig(libsoup-2.4) >= %{libsoup_version} +BuildRequires: pkgconfig(libsoup-3.0) >= %{libsoup_version} BuildRequires: pkgconfig(avahi-client) >= %{avahi_version} BuildRequires: pkgconfig(avahi-glib) >= %{avahi_version} BuildRequires: pkgconfig(libsecret-1) -BuildRequires: gettext-devel >= %{gettext_version} +BuildRequires: gettext-devel BuildRequires: pkgconfig(udisks2) >= %{udisks2_version} %if ! 0%{?rhel} BuildRequires: pkgconfig(libbluray) @@ -114,29 +68,30 @@ BuildRequires: docbook-style-xsl BuildRequires: pkgconfig(polkit-gobject-1) BuildRequires: pkgconfig(libcap) -BuildRequires: automake autoconf -BuildRequires: libtool - Requires: %{name}-client%{?_isa} = %{version}-%{release} Requires: glib2%{?_isa} >= %{glib2_version} -Requires: udisks2 >= %{udisks2_version} Requires: gsettings-desktop-schemas >= %{gsettings_desktop_schemas_version} - -# for file triggers -Requires(post): desktop-file-utils >= 0.22-6 -Requires(postun): desktop-file-utils >= 0.22-6 +Requires: polkit +Requires: udisks2 >= %{udisks2_version} +Requires: /usr/bin/wsdd Obsoletes: gnome-mount <= 0.8 Obsoletes: gnome-mount-nautilus-properties <= 0.8 Obsoletes: gvfs-obexftp < 1.17.91-2 +Obsoletes: gvfs-devel < 1.54.2-1 +Obsoletes: gvfs-tests < 1.54.2-2 +%ifarch s390 s390x +Obsoletes: gvfs-gphoto2 < 1.54.2-3 +Obsoletes: gvfs-mtp < 1.54.2-3 +%endif %description The gvfs package provides backend implementations for the gio framework in GLib. It includes ftp, sftp, cifs. -%package client -Summary: Client modules of backends for the gio framework in GLib +%package client +Summary: Client modules of backends for the gio framework in GLib Conflicts: %{name} < 1.25.2-2 %description client @@ -144,21 +99,12 @@ The gvfs package provides client modules of backend implementations for the gio framework in GLib. -%package devel -Summary: Development files for gvfs -Requires: %{name}-client%{?_isa} = %{version}-%{release} - -%description devel -The gvfs-devel package contains headers and other files that are -required to develop applications using gvfs. - - %package fuse Summary: FUSE support for gvfs Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-client%{?_isa} = %{version}-%{release} -BuildRequires: pkgconfig(fuse) >= %{fuse_version} -Requires: fuse >= %{fuse_version} +BuildRequires: pkgconfig(fuse3) >= %{fuse_version} +Requires: fuse3 >= %{fuse_version} %description fuse This package provides support for applications not using gio @@ -177,6 +123,7 @@ This package provides support for reading and writing files on windows shares (SMB) to applications using gvfs. +%if ! (0%{?rhel} >= 9) %package archive Summary: Archiving support for gvfs Requires: %{name}%{?_isa} = %{version}-%{release} @@ -186,8 +133,10 @@ BuildRequires: pkgconfig(libarchive) >= %{libarchive_version} %description archive This package provides support for accessing files inside Zip and Tar archives, as well as ISO images, to applications using gvfs. +%endif +%ifnarch s390 s390x %package gphoto2 Summary: gphoto2 support for gvfs Requires: %{name}%{?_isa} = %{version}-%{release} @@ -201,21 +150,23 @@ PTP based cameras (Picture Transfer Protocol) and MTP based media players (Media Transfer Protocol) to applications using gvfs. -%ifnarch s390 s390x +%if ! 0%{?rhel} %package afc Summary: AFC support for gvfs Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-client%{?_isa} = %{version}-%{release} Requires: usbmuxd BuildRequires: pkgconfig(libimobiledevice-1.0) >= %{libimobiledevice_version} -BuildRequires: pkgconfig(libplist) >= %{libplist_version} +BuildRequires: pkgconfig(libplist-2.0) >= %{libplist_version} %description afc This package provides support for reading files on mobile devices including phones and music players to applications using gvfs. %endif +%endif +%if ! (0%{?rhel} >= 9) %package afp Summary: AFP support for gvfs Requires: %{name}%{?_isa} = %{version}-%{release} @@ -228,8 +179,10 @@ Obsoletes: %{name} < 1.9.4-1 This package provides support for reading and writing files on Mac OS X and original Mac OS network shares via Apple Filing Protocol to applications using gvfs. +%endif +%ifnarch s390 s390x %package mtp Summary: MTP support for gvfs Requires: %{name}%{?_isa} = %{version}-%{release} @@ -240,6 +193,7 @@ BuildRequires: pkgconfig(libusb-1.0) >= %{libusb_version} %description mtp This package provides support for reading and writing files on MTP based devices (Media Transfer Protocol) to applications using gvfs. +%endif %if ! 0%{?rhel} @@ -260,44 +214,50 @@ Summary: GOA support for gvfs Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-client%{?_isa} = %{version}-%{release} BuildRequires: pkgconfig(goa-1.0) >= %{goa_version} +%if ! (0%{?rhel} >= 10) BuildRequires: pkgconfig(libgdata) >= %{libgdata_version} Requires: libgdata%{?_isa} >= %{libgdata_version} +BuildRequires: pkgconfig(msgraph-0.1) +%endif %description goa This package provides seamless integration with gnome-online-accounts file services. -%package tests -Summary: Tests for the gvfs package -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description tests -The gvfs-tests package contains tests that can be used to verify -the functionality of the installed gvfs package. %prep %autosetup -p1 -autoreconf -fi - %build -%configure \ - --disable-gdu \ - --enable-udisks2 \ - --enable-keyring \ - --enable-installed-tests \ +%meson \ + -Dman=true \ +%ifarch s390 s390x + -Dafc=false \ + -Dgphoto2=false \ + -Dlibusb=false \ + -Dmtp=false \ +%endif %if 0%{?rhel} - --disable-nfs \ - --disable-bluray \ + -Dnfs=false \ + -Dbluray=false \ + -Dafc=false \ + -Donedrive=false \ +%endif +%if 0%{?rhel} >= 9 + -Darchive=false \ + -Dafp=false \ + -Dgcrypt=false \ +%endif +%if 0%{?rhel} >= 10 + -Dgoogle=false \ + -Dcdda=false \ + -Ddeprecated_apis=false \ %endif %{nil} -make %{?_smp_mflags} V=1 +%meson_build %install -%make_install - -rm $RPM_BUILD_ROOT%{_libdir}/gvfs/*.la -rm $RPM_BUILD_ROOT%{_libdir}/gio/modules/*.la +%meson_install # trashlib is GPLv3, include the license cp -p daemon/trashlib/COPYING COPYING.GPL3 @@ -311,25 +271,33 @@ killall -USR1 gvfsd >&/dev/null || : # Reload .mount files when single subpackage is installed: %post smb killall -USR1 gvfsd >&/dev/null || : +%ifnarch s390 s390x %post gphoto2 killall -USR1 gvfsd >&/dev/null || : %post mtp killall -USR1 gvfsd >&/dev/null || : +%endif %post goa killall -USR1 gvfsd >&/dev/null || : %ifnarch s390 s390x +%if ! 0%{?rhel} %post afc killall -USR1 gvfsd >&/dev/null || : %endif +%endif +%if ! (0%{?rhel} >= 9) %post archive killall -USR1 gvfsd >&/dev/null || : +%endif %if ! 0%{?rhel} %post nfs killall -USR1 gvfsd >&/dev/null || : %endif +%if ! (0%{?rhel} >= 9) %post afp killall -USR1 gvfsd >&/dev/null || : +%endif %files @@ -338,18 +306,21 @@ killall -USR1 gvfsd >&/dev/null || : %{_datadir}/gvfs/mounts/admin.mount %{_datadir}/gvfs/mounts/sftp.mount %{_datadir}/gvfs/mounts/trash.mount +%if ! (0%{?rhel} >= 10) %{_datadir}/gvfs/mounts/cdda.mount +%endif %{_datadir}/gvfs/mounts/computer.mount %{_datadir}/gvfs/mounts/dav.mount %{_datadir}/gvfs/mounts/dav+sd.mount %{_datadir}/gvfs/mounts/http.mount %{_datadir}/gvfs/mounts/localtest.mount -%{_datadir}/gvfs/mounts/burn.mount %{_datadir}/gvfs/mounts/dns-sd.mount %{_datadir}/gvfs/mounts/network.mount %{_datadir}/gvfs/mounts/ftp.mount +%{_datadir}/gvfs/mounts/ftpis.mount %{_datadir}/gvfs/mounts/ftps.mount %{_datadir}/gvfs/mounts/recent.mount +%{_datadir}/gvfs/mounts/wsdd.mount %{_datadir}/dbus-1/services/org.gtk.vfs.Daemon.service %{_datadir}/dbus-1/services/org.gtk.vfs.Metadata.service %{_datadir}/dbus-1/services/org.gtk.vfs.UDisks2VolumeMonitor.service @@ -365,48 +336,38 @@ killall -USR1 gvfsd >&/dev/null || : %{_libexecdir}/gvfsd-ftp %{_libexecdir}/gvfsd-sftp %{_libexecdir}/gvfsd-trash +%if ! (0%{?rhel} >= 10) %{_libexecdir}/gvfsd-cdda +%endif %{_libexecdir}/gvfsd-computer %{_libexecdir}/gvfsd-dav %{_libexecdir}/gvfsd-http %{_libexecdir}/gvfsd-localtest -%{_libexecdir}/gvfsd-burn %{_libexecdir}/gvfsd-dnssd %{_libexecdir}/gvfsd-network %{_libexecdir}/gvfsd-metadata %{_libexecdir}/gvfs-udisks2-volume-monitor %{_libexecdir}/gvfsd-recent +%{_libexecdir}/gvfsd-wsdd %{_mandir}/man1/gvfsd.1* %{_mandir}/man1/gvfsd-metadata.1* -%if ! 0%{?flatpak} %{_userunitdir}/gvfs-daemon.service %{_userunitdir}/gvfs-metadata.service %{_userunitdir}/gvfs-udisks2-volume-monitor.service -%endif %files client -f gvfs.lang -%{!?_licensedir:%global license %%doc} %license COPYING COPYING.GPL3 -%doc AUTHORS NEWS README +%doc NEWS README.md %dir %{_libdir}/gvfs %{_libdir}/gvfs/libgvfscommon.so %{_libdir}/gio/modules/libgioremote-volume-monitor.so %{_libdir}/gio/modules/libgvfsdbus.so %{_mandir}/man7/gvfs.7* -%files devel -%dir %{_includedir}/gvfs-client -%dir %{_includedir}/gvfs-client/gvfs -%{_includedir}/gvfs-client/gvfs/gvfsurimapper.h -%{_includedir}/gvfs-client/gvfs/gvfsuriutils.h - - %files fuse %{_libexecdir}/gvfsd-fuse %{_mandir}/man1/gvfsd-fuse.1* -%if ! 0%{?flatpak} %{_tmpfilesdir}/gvfsd-fuse-tmpfiles.conf -%endif %files smb %{_libexecdir}/gvfsd-smb @@ -415,52 +376,52 @@ killall -USR1 gvfsd >&/dev/null || : %{_datadir}/gvfs/mounts/smb.mount +%if ! (0%{?rhel} >= 9) %files archive %{_libexecdir}/gvfsd-archive %{_datadir}/gvfs/mounts/archive.mount +%endif - +%ifnarch s390 s390x %files gphoto2 %{_libexecdir}/gvfsd-gphoto2 %{_datadir}/gvfs/mounts/gphoto2.mount %{_libexecdir}/gvfs-gphoto2-volume-monitor %{_datadir}/dbus-1/services/org.gtk.vfs.GPhoto2VolumeMonitor.service %{_datadir}/gvfs/remote-volume-monitors/gphoto2.monitor -%if ! 0%{?flatpak} %{_userunitdir}/gvfs-gphoto2-volume-monitor.service -%endif -%ifnarch s390 s390x +%if ! 0%{?rhel} %files afc %{_libexecdir}/gvfsd-afc %{_datadir}/gvfs/mounts/afc.mount %{_libexecdir}/gvfs-afc-volume-monitor %{_datadir}/dbus-1/services/org.gtk.vfs.AfcVolumeMonitor.service %{_datadir}/gvfs/remote-volume-monitors/afc.monitor -%if ! 0%{?flatpak} %{_userunitdir}/gvfs-afc-volume-monitor.service %endif %endif +%if ! (0%{?rhel} >= 9) %files afp %{_libexecdir}/gvfsd-afp %{_libexecdir}/gvfsd-afp-browse %{_datadir}/gvfs/mounts/afp.mount %{_datadir}/gvfs/mounts/afp-browse.mount +%endif +%ifnarch s390 s390x %files mtp %{_libexecdir}/gvfsd-mtp %{_datadir}/gvfs/mounts/mtp.mount %{_libexecdir}/gvfs-mtp-volume-monitor %{_datadir}/dbus-1/services/org.gtk.vfs.MTPVolumeMonitor.service %{_datadir}/gvfs/remote-volume-monitors/mtp.monitor -%if ! 0%{?flatpak} %{_userunitdir}/gvfs-mtp-volume-monitor.service %endif %if ! 0%{?rhel} %files nfs -%{_libexecdir}/gvfsd-nfs # for privileged ports %caps(cap_net_bind_service=ep) %{_libexecdir}/gvfsd-nfs %{_datadir}/gvfs/mounts/nfs.mount @@ -470,78 +431,324 @@ killall -USR1 gvfsd >&/dev/null || : %{_libexecdir}/gvfs-goa-volume-monitor %{_datadir}/dbus-1/services/org.gtk.vfs.GoaVolumeMonitor.service %{_datadir}/gvfs/remote-volume-monitors/goa.monitor +%if ! (0%{?rhel} >= 10) %{_datadir}/gvfs/mounts/google.mount %{_libexecdir}/gvfsd-google -%if ! 0%{?flatpak} -%{_userunitdir}/gvfs-goa-volume-monitor.service %endif +%if ! 0%{?rhel} +%{_datadir}/gvfs/mounts/onedrive.mount +%{_libexecdir}/gvfsd-onedrive +%endif +%{_userunitdir}/gvfs-goa-volume-monitor.service -%files tests -%dir %{_libexecdir}/installed-tests -%{_libexecdir}/installed-tests/gvfs -%{_datadir}/installed-tests %changelog -* Thu Feb 13 2025 Ondrej Holy - 1.36.2-18 -- Add edit mode support for smb backend (RHEL-45163) +* Thu Feb 13 2025 Ondrej Holy - 1.54.4-2 +- Add edit mode support for smb backend (RHEL-71089) -* Thu Sep 26 2024 Ondrej Holy - 1.36.2-17 -- Add support for x-gvfs-trash mount option (RHEL-52342) +* Wed Nov 06 2024 nmontero - 1.54.4-1 +- Update to 1.54.4 -* Wed Dec 06 2023 Ondrej Holy - 1.36.2-16 -- Sync trash dir items when files change (RHEL-2824) +* Tue Oct 29 2024 Troy Dawson - 1.54.3-2 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 -* Mon Oct 09 2023 Ondrej Holy - 1.36.2-15 -- Add support for x-gvfs-notrash mount option (RHEL-2824) +* Fri Sep 27 2024 David King - 1.54.3-1 +- Update to 1.54.3 -* Thu Jun 16 2022 Ondrej Holy - 1.36.2-14 -- Backport performance fixes for Google backend (#2083481) +* Thu Sep 26 2024 Ondrej Holy - 1.54.2-4 +- Add support for x-gvfs-trash mount option (RHEL-52355) -* Tue Jun 14 2022 Ondrej Holy - 1.36.2-13 -- Use O_RDWR to fix fstat when writing on SMB share (#2080478) +* Mon Jul 29 2024 Ondrej Holy - 1.54.2-3 +- Drop the gphoto2 and mtp subpackages on s390(x) architectures -* Tue Jun 14 2022 Ondrej Holy - 1.36.2-12 -- Ignore EINVAL for kerberos login to fix SMB mounting (#2095712) +* Mon Jul 29 2024 Ondrej Holy - 1.54.2-2 +- Drop the gvfs-tests subpackage -* Tue Nov 03 2020 Ondrej Holy - 1.36.2-11 -- Add support for certificates prompts for GOA mounts (rhbz#1889411) +* Fri Jun 28 2024 Ondrej Holy - 1.54.2-1 +- Update to 1.54.2 -* Wed Aug 05 2020 Ondrej Holy - 1.36.2-10 -- Fix libusb(x) requirements (rhbz#1866332) +* Mon Jun 24 2024 Troy Dawson - 1.54.1-3 +- Bump release for June 2024 mass rebuild -* Wed Jun 17 2020 Ondrej Holy - 1.36.2-9 -- Improve enumeration performance of smb backend (rhbz#1569868) +* Wed May 29 2024 Ondrej Holy - 1.54.1-2 +- Disable CDDA backend in RHEL 10 -* Tue Oct 8 2019 Ondrej Holy - 1.36.2-8 -- Fix udisks2 volume monitor crashes when stopping drive (rhbz#1759075) +* Mon May 27 2024 Ondrej Holy - 1.54.1-1 +- Update to 1.54.1 -* Thu Sep 19 2019 Ondrej Holy - 1.36.2-7 -- Remove libbluray support (#1747972) -- CVE-2019-12448: Add query_info_on_read/write functionality (rhbz#1754506) -- CVE-2019-12447: Use fsuid to ensure correct file ownership (rhbz#1752926) -- CVE-2019-12449: Ensure correct ownership when moving to file:// uri (rhbz#1753972) +* Tue Mar 19 2024 Ondrej Holy - 1.54.0-2 +- Enable OneDrive support for Fedora -* Fri Aug 09 2019 Ondrej Holy - 1.36.2-6 -- Prevent spawning new daemons if outgoing operation exists (#1739117) -- Force NT1 protocol version for workgroup support (#1739116) +* Fri Mar 15 2024 David King - 1.54.0-1 +- Update to 1.54.0 -* Thu Aug 08 2019 Ondrej Holy - 1.36.2-5 -- CVE-2019-12795 Check that the connecting client is the same user (#1729885) +* Sat Mar 02 2024 David King - 1.53.91-1 +- Update to 1.53.91 -* Thu May 16 2019 Ondrej Holy - 1.36.2-4 -- Handle lockdown option to disable writing (#1662193) +* Wed Feb 14 2024 David King - 1.53.90-1 +- Update to 1.53.90 -* Mon Apr 01 2019 Ondrej Holy - 1.36.2-3 -- CVE-2019-3827: Prevent access if any authentication agent isn't available (#1673888) +* Fri Feb 09 2024 Ondrej Holy - 1.53.1-4 +- Migrate to SPDX license -* Fri Dec 14 2018 Ray Strode - 1.36.2-2 -- rebuild +* Thu Feb 01 2024 Ondrej Holy - 1.53.1-3 +- Make wsdd regular dependency -* Tue Jun 12 2018 Ondrej Holy - 1.36.2-1 -- Update to 1.36.2 +* Wed Jan 24 2024 Fedora Release Engineering - 1.53.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 David King - 1.53.1-1 +- Update to 1.53.1 + +* Thu Jan 11 2024 Kalev Lember - 1.52.2-1 +- Update to 1.52.2 + +* Sat Oct 21 2023 Kalev Lember - 1.52.1-1 +- Update to 1.52.1 + +* Mon Sep 18 2023 Kalev Lember - 1.52.0-1 +- Update to 1.52.0 + +* Tue Sep 05 2023 Kalev Lember - 1.51.91-1 +- Update to 1.51.91 + +* Sun Aug 06 2023 Kalev Lember - 1.51.90-1 +- Update to 1.51.90 + +* Fri Jul 28 2023 Michel Alexandre Salim - 1.51.1-4 +- Rebuilt for libimobiledevice and libplist soname bump + +* Thu Jul 20 2023 Fedora Release Engineering - 1.51.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Fri Jul 14 2023 Ondrej Holy - 1.51.1-2 +- Fix udisks2 volume monitor crashes (#2219172) + +* Fri Jun 30 2023 Kalev Lember - 1.51.1-1 +- Update to 1.51.1 + +* Thu Jun 15 2023 Ondrej Holy - 1.50.4-3 +- Disable Google backend in RHEL + +* Thu Jun 01 2023 David King - 1.50.4-2 +- Rebuilt against libnfs + +* Sat Mar 18 2023 David King - 1.50.4-1 +- Update to 1.50.4 + +* Thu Jan 19 2023 Fedora Release Engineering - 1.50.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Sun Jan 08 2023 David King - 1.50.3-1 +- Update to 1.50.3 + +* Thu Jul 21 2022 Fedora Release Engineering - 1.50.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Thu May 26 2022 David King - 1.50.2-1 +- Update to 1.50.2 + +* Thu May 05 2022 Ondrej Holy - 1.50.1-2 +- Rework anonymous handling of SMB backend to avoid EINVAL (#2068976) +- Unescape prefix to fix handling of encoded HTTP URIs + +* Tue Apr 26 2022 Ondrej Holy - 1.50.1-1 +- Update to 1.50.1 (#2078857) + +* Wed Apr 13 2022 Ondrej Holy - 1.50.0-4 +- Ignore EINVAL for kerberos/ccache login to fix SMB mounting (#2068976, #2072885) + +* Fri Apr 8 2022 Ondrej Holy - 1.50.0-3 +- Rewrite DAV backend to libsoup async API to fix crashes (#2062465) + +* Thu Mar 24 2022 Ondrej Holy - 1.50.0-2 +- Fix DAV backend crashes caused by extra unref (#2066717) + +* Fri Mar 18 2022 David King - 1.50.0-1 +- Update to 1.50.0 + +* Sun Feb 13 2022 David King - 1.49.90-1 +- Update to 1.49.90 + +* Sun Jan 30 2022 Tim Landscheidt - 1.49.1-3 +- Remove obsolete requirements for %%post/%%postun scriptlets + +* Thu Jan 20 2022 Fedora Release Engineering - 1.49.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Fri Jan 07 2022 David King - 1.49.1-1 +- Update to 1.49.1 + +* Thu Jul 22 2021 Fedora Release Engineering - 1.48.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Wed May 05 2021 Kalev Lember - 1.48.1-1 +- Update to 1.48.1 + +* Mon Mar 22 2021 Kalev Lember - 1.48.0-1 +- Update to 1.48.0 + +* Mon Mar 15 2021 Kalev Lember - 1.47.91-1 +- Update to 1.47.91 + +* Wed Feb 17 2021 Kalev Lember - 1.47.90-1 +- Update to 1.47.90 + +* Tue Jan 26 2021 Fedora Release Engineering - 1.46.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Sat Jan 16 2021 Kalev Lember - 1.46.2-1 +- Update to 1.46.2 + +* Mon Oct 5 2020 Kalev Lember - 1.46.1-1 +- Update to 1.46.1 + +* Fri Sep 11 2020 Kalev Lember - 1.46.0-1 +- Update to 1.46.0 + +* Fri Sep 04 2020 Kalev Lember - 1.45.92-1 +- Update to 1.45.92 + +* Mon Aug 17 2020 Kalev Lember - 1.45.90-1 +- Update to 1.45.90 + +* Tue Aug 04 2020 Ondrej Holy - 1.45.3-1 +- Update to 1.45.3 + +* Tue Jul 28 2020 Fedora Release Engineering - 1.45.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 13 2020 Bastien Nocera - 1.45.2-3 ++ gvfs-1.45.2-3 +- Disable afc backend in RHEL + +* Wed Jun 17 2020 Bastien Nocera - 1.45.2-2 ++ gvfs-1.45.2-2 +- Rebuild with libplist 2.2 support + +* Fri May 29 2020 Kalev Lember - 1.45.2-1 +- Update to 1.45.2 + +* Tue Mar 31 2020 Adrian Reber - 1.44.1-2 +- Rebuilt for libcdio-2.1.0 + +* Fri Mar 27 2020 Kalev Lember - 1.44.1-1 +- Update to 1.44.1 + +* Fri Mar 06 2020 Kalev Lember - 1.44.0-1 +- Update to 1.44.0 + +* Mon Mar 02 2020 Kalev Lember - 1.43.92-1 +- Update to 1.43.92 + +* Mon Feb 17 2020 Kalev Lember - 1.43.91-1 +- Update to 1.43.91 + +* Sun Feb 02 2020 Kalev Lember - 1.43.90-1 +- Update to 1.43.90 + +* Wed Jan 29 2020 Fedora Release Engineering - 1.43.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Mon Dec 02 2019 Kalev Lember - 1.43.2-1 +- Update to 1.43.2 + +* Wed Nov 27 2019 Kalev Lember - 1.42.2-1 +- Update to 1.42.2 + +* Mon Oct 07 2019 Kalev Lember - 1.42.1-1 +- Update to 1.42.1 + +* Thu Sep 19 2019 Ondrej Holy - 1.42.0-3 +- Remove libbluray support on RHEL (#1747972) + +* Wed Sep 11 2019 Leigh Scott - 1.42.0-2 +- Rebuild for new libnfs version + +* Mon Sep 09 2019 Kalev Lember - 1.42.0-1 +- Update to 1.42.0 + +* Tue Aug 20 2019 Kalev Lember - 1.41.91-1 +- Update to 1.41.91 + +* Mon Aug 12 2019 Kalev Lember - 1.41.90-1 +- Update to 1.41.90 + +* Thu Jul 25 2019 Fedora Release Engineering - 1.41.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Mon Jul 15 2019 Kalev Lember - 1.41.4-1 +- Update to 1.41.4 + +* Wed Jun 19 2019 Kalev Lember - 1.41.3-1 +- Update to 1.41.3 + +* Tue May 21 2019 Kalev Lember - 1.41.2-1 +- Update to 1.41.2 + +* Thu May 09 2019 Kalev Lember - 1.41.1-1 +- Update to 1.41.1 +- Build against fuse3 + +* Tue Apr 16 2019 Adam Williamson - 1.40.1-2 +- Rebuild with Meson fix for #1699099 + +* Tue Apr 09 2019 Kalev Lember - 1.40.1-1 +- Update to 1.40.1 + +* Mon Mar 11 2019 Kalev Lember - 1.40.0-1 +- Update to 1.40.0 + +* Mon Mar 04 2019 Kalev Lember - 1.39.92-1 +- Update to 1.39.92 + +* Mon Feb 18 2019 Kalev Lember - 1.39.91-1 +- Update to 1.39.91 + +* Mon Feb 04 2019 Kalev Lember - 1.39.90-1 +- Update to 1.39.90 + +* Fri Feb 01 2019 Fedora Release Engineering - 1.39.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Jan 17 2019 Ondrej Holy - 1.39.4-2 +- admin: Prevent access if any authentication agent isn't available + +* Mon Jan 07 2019 Kalev Lember - 1.39.4-1 +- Update to 1.39.4 + +* Tue Oct 09 2018 Kalev Lember - 1.39.1-1 +- Update to 1.39.1 + +* Tue Sep 25 2018 Ondrej Holy - 1.38.1-1 +- Update to 1.38.1 + +* Thu Sep 06 2018 Kalev Lember - 1.38.0-1 +- Update to 1.38.0 + +* Thu Aug 02 2018 Ondrej Holy - 1.37.90-1 +- Update to 1.37.90 + +* Fri Jul 13 2018 Ondrej Holy - 1.37.4-1 +- Update to 1.37.4 + +* Fri Jul 13 2018 Fedora Release Engineering - 1.37.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild +- Add missing gcc dependency + +* Wed May 09 2018 Ondrej Holy - 1.37.2-1 +- Update to 1.37.2 +- Disable NFS support in RHEL + +* Wed May 09 2018 Ondrej Holy - 1.37.1-1 +- Update to 1.37.1 - Remove mount-archive.desktop helper +- Switch to meson build system - Remove obsolete gvfs utils -- Disable nfs support + +* Tue May 08 2018 Kalev Lember - 1.36.2-1 +- Update to 1.36.2 * Mon Apr 09 2018 Kalev Lember - 1.36.1-1 - Update to 1.36.1 diff --git a/SOURCES/smb-Disable-seek-support-when-appening.patch b/smb-Disable-seek-support-when-appening.patch similarity index 100% rename from SOURCES/smb-Disable-seek-support-when-appening.patch rename to smb-Disable-seek-support-when-appening.patch diff --git a/SOURCES/smb-Fail-when-initial_offset-can-t-be-determined.patch b/smb-Fail-when-initial_offset-can-t-be-determined.patch similarity index 100% rename from SOURCES/smb-Fail-when-initial_offset-can-t-be-determined.patch rename to smb-Fail-when-initial_offset-can-t-be-determined.patch diff --git a/SOURCES/smb-Fix-offset-after-truncate-when-appending.patch b/smb-Fix-offset-after-truncate-when-appending.patch similarity index 100% rename from SOURCES/smb-Fix-offset-after-truncate-when-appending.patch rename to smb-Fix-offset-after-truncate-when-appending.patch diff --git a/SOURCES/smb-Implement-support-for-edit-mode.patch b/smb-Implement-support-for-edit-mode.patch similarity index 100% rename from SOURCES/smb-Implement-support-for-edit-mode.patch rename to smb-Implement-support-for-edit-mode.patch diff --git a/sources b/sources new file mode 100644 index 0000000..b368cca --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (gvfs-1.54.4.tar.xz) = a7f9b8f6a9a8a4fe0f049e4f5d696e0709d2e812420aa8617b773fda16db547712068fb067a2f48e43a19548ccc191930c70d53a512e553dc4d24332ffa96af9 diff --git a/SOURCES/trash-Add-support-for-x-gvfs-trash-mount-option.patch b/trash-Add-support-for-x-gvfs-trash-mount-option.patch similarity index 100% rename from SOURCES/trash-Add-support-for-x-gvfs-trash-mount-option.patch rename to trash-Add-support-for-x-gvfs-trash-mount-option.patch