[gvfs/nfs] Set CAN_DELETE, CAN_TRASH and CAN_RENAME from query_info



commit 478d70165648b0660b3c67f5f637a8ebef372f27
Author: Ross Lagerwall <rosslagerwall gmail com>
Date:   Wed Feb 4 20:56:43 2015 +0000

    Set CAN_DELETE, CAN_TRASH and CAN_RENAME from query_info

 daemon/gvfsbackendnfs.c |   62 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 50 insertions(+), 12 deletions(-)
---
diff --git a/daemon/gvfsbackendnfs.c b/daemon/gvfsbackendnfs.c
index 255f26c..8d1d9cc 100644
--- a/daemon/gvfsbackendnfs.c
+++ b/daemon/gvfsbackendnfs.c
@@ -543,6 +543,7 @@ set_info_from_stat (GFileInfo *info, struct nfs_stat_64 *st, GFileAttributeMatch
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, st->nfs_mtime_nsec / 1000);
   g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CHANGED, st->nfs_ctime);
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CHANGED_USEC, st->nfs_ctime_nsec / 1000);
+  g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE);
 }
 
 static void
@@ -1903,6 +1904,9 @@ try_enumerate (GVfsBackend *backend,
   return TRUE;
 }
 
+static void stat_access_parent_cb (int err,
+                                   struct nfs_context *ctx,
+                                   void *data, void *private_data);
 static void stat_readlink_cb (int err,
                               struct nfs_context *ctx,
                               void *data, void *private_data);
@@ -1924,13 +1928,18 @@ stat_access_cb (int err,
     }
 
   if (g_file_attribute_matcher_matches (op_job->attribute_matcher,
-                                        G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
+                                        G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME) ||
+      g_file_attribute_matcher_matches (op_job->attribute_matcher,
+                                        G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE))
     {
-      if (!(op_job->flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) ||
-          g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK)
-        nfs_readlink_async (ctx, op_job->filename, stat_readlink_cb, job);
-      else
-        g_vfs_job_succeeded (job);
+      char *dirname = g_path_get_dirname (op_job->filename);
+      nfs_access2_async (ctx, dirname, stat_access_parent_cb, job);
+      g_free (dirname);
+    }
+  else if (g_file_attribute_matcher_matches (op_job->attribute_matcher,
+                                             G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
+    {
+      nfs_readlink_async (ctx, op_job->filename, stat_readlink_cb, job);
     }
   else
     {
@@ -1939,6 +1948,28 @@ stat_access_cb (int err,
 }
 
 static void
+stat_access_parent_cb (int err,
+                       struct nfs_context *ctx,
+                       void *data, void *private_data)
+{
+  GVfsJob *job = G_VFS_JOB (private_data);
+  GVfsJobQueryInfo *op_job = G_VFS_JOB_QUERY_INFO (job);
+  GFileInfo *info = op_job->file_info;
+
+  if (err >= 0)
+    {
+      g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, err & W_OK);
+      g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, err & W_OK);
+    }
+
+  if (g_file_attribute_matcher_matches (op_job->attribute_matcher,
+                                        G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
+    nfs_readlink_async (ctx, op_job->filename, stat_readlink_cb, job);
+  else
+    g_vfs_job_succeeded (job);
+}
+
+static void
 stat_readlink_cb (int err,
                   struct nfs_context *ctx,
                   void *data, void *private_data)
@@ -1996,13 +2027,18 @@ stat_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
           nfs_access2_async (ctx, op_job->filename, stat_access_cb, job);
         }
       else if (g_file_attribute_matcher_matches (op_job->attribute_matcher,
-                                            G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
+                                                 G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME) ||
+               g_file_attribute_matcher_matches (op_job->attribute_matcher,
+                                                 G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE))
         {
-          if (!(op_job->flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) ||
-              S_ISLNK (st->nfs_mode))
-            nfs_readlink_async (ctx, op_job->filename, stat_readlink_cb, job);
-          else
-            g_vfs_job_succeeded (job);
+          char *dirname = g_path_get_dirname (op_job->filename);
+          nfs_access2_async (ctx, dirname, stat_access_parent_cb, job);
+          g_free (dirname);
+        }
+      else if (g_file_attribute_matcher_matches (op_job->attribute_matcher,
+                                                 G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
+        {
+          nfs_readlink_async (ctx, op_job->filename, stat_readlink_cb, job);
         }
       else
         {
@@ -2027,6 +2063,8 @@ stat_is_symlink_cb (int err,
       GVfsJobQueryInfo *op_job = G_VFS_JOB_QUERY_INFO (job);
       struct nfs_stat_64 *st = data;
 
+      /* In the case that symlinks are not followed, this is set by
+       * set_type_from_mode in stat_cb(). */
       g_file_info_set_is_symlink (op_job->file_info, S_ISLNK (st->nfs_mode));
 
       /* If the filename is a link, call stat to get the real info.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]