Bug 593406 - Permissions set to 777 after copying via Nautilus
authorBenjamin Otte <otte@gnome.org>
Tue, 1 Sep 2009 09:54:48 +0000 (11:54 +0200)
committerBenjamin Otte <otte@gnome.org>
Tue, 1 Sep 2009 10:15:31 +0000 (12:15 +0200)
When doing a g_file_copy() with nofollow-symlinks (to copy a link for
example), the later copying of the file attributes copies the source
links 777 attributes to the target's attributes. As chmod affects the
symlink target, this would cause such copies to always set the target to
777 mode.

This patch makes setting the mode with nofollow-symlinks fail with
NOT_SUPPORTED.

The aforementioned g_file_copy() will still succeed, because it ignores
errors of the attribute copy.

gio/glocalfileinfo.c

index 72a59b5..7933ed9 100644 (file)
@@ -1869,6 +1869,7 @@ get_string (const GFileAttributeValue  *value,
 
 static gboolean
 set_unix_mode (char                       *filename,
+               GFileQueryInfoFlags         flags,
               const GFileAttributeValue  *value,
               GError                    **error)
 {
@@ -1877,6 +1878,13 @@ set_unix_mode (char                       *filename,
   if (!get_uint32 (value, &val, error))
     return FALSE;
   
+  if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) {
+    g_set_error_literal (error, G_IO_ERROR,
+                         G_IO_ERROR_NOT_SUPPORTED,
+                         _("Cannot set permissions on symlinks"));
+    return FALSE;
+  }
+
   if (g_chmod (filename, val) == -1)
     {
       int errsv = errno;
@@ -2172,7 +2180,7 @@ _g_local_file_info_set_attribute (char                 *filename,
   _g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE);
   
   if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0)
-    return set_unix_mode (filename, &value, error);
+    return set_unix_mode (filename, flags, &value, error);
   
 #ifdef HAVE_CHOWN
   else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0)
@@ -2316,7 +2324,7 @@ _g_local_file_info_set_attributes  (char                 *filename,
   value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_MODE);
   if (value)
     {
-      if (!set_unix_mode (filename, value, error))
+      if (!set_unix_mode (filename, flags, value, error))
        {
          value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
          res = FALSE;