Tomas Bzatek cc540d5
Index: libnautilus-private/nautilus-file-operations.c
Tomas Bzatek cc540d5
===================================================================
Tomas Bzatek cc540d5
--- libnautilus-private/nautilus-file-operations.c	(revision 14108)
Tomas Bzatek cc540d5
+++ libnautilus-private/nautilus-file-operations.c	(working copy)
Tomas Bzatek cc540d5
@@ -3224,6 +3224,24 @@
Tomas Bzatek cc540d5
 	}
Tomas Bzatek cc540d5
 }
Tomas Bzatek cc540d5
 
Tomas Bzatek cc540d5
+static gboolean
Tomas Bzatek cc540d5
+g_file_struct_contains (GFile *child, GFile *root)
Tomas Bzatek cc540d5
+{
Tomas Bzatek cc540d5
+    GFile *f;
Tomas Bzatek cc540d5
+    
Tomas Bzatek cc540d5
+    f = g_file_dup (child);
Tomas Bzatek cc540d5
+    while (f) {
Tomas Bzatek cc540d5
+	if (g_file_equal (f, root)) {
Tomas Bzatek cc540d5
+	    g_object_unref (f);
Tomas Bzatek cc540d5
+	    return TRUE;
Tomas Bzatek cc540d5
+	}
Tomas Bzatek cc540d5
+	f = g_file_get_parent (f);
Tomas Bzatek cc540d5
+    }
Tomas Bzatek cc540d5
+    
Tomas Bzatek cc540d5
+    if (f)  g_object_unref (f);
Tomas Bzatek cc540d5
+    return FALSE;
Tomas Bzatek cc540d5
+}
Tomas Bzatek cc540d5
+
Tomas Bzatek cc540d5
 /* Debuting files is non-NULL only for toplevel items */
Tomas Bzatek cc540d5
 static void
Tomas Bzatek cc540d5
 copy_move_file (CopyMoveJob *copy_job,
Tomas Bzatek cc540d5
@@ -3264,6 +3282,41 @@
Tomas Bzatek cc540d5
 		dest = get_target_file (src, dest_dir, same_fs);
Tomas Bzatek cc540d5
 	}
Tomas Bzatek cc540d5
 
Tomas Bzatek cc540d5
+
Tomas Bzatek cc540d5
+	/* Don't allow recursive move/copy into itself.  
Tomas Bzatek cc540d5
+         * (We would get a file system error if we proceeded but it is nicer to 
Tomas Bzatek cc540d5
+         * detect and report it at this level) */
Tomas Bzatek cc540d5
+	if (g_file_struct_contains (dest_dir, src)) {
Tomas Bzatek cc540d5
+		if (job->skip_all_error) {
Tomas Bzatek cc540d5
+			g_error_free (error);
Tomas Bzatek cc540d5
+			goto out;
Tomas Bzatek cc540d5
+		}
Tomas Bzatek cc540d5
+		
Tomas Bzatek cc540d5
+		/*  the run_warning() frees all strings passed in automatically  */
Tomas Bzatek cc540d5
+		primary = copy_job->is_move ? g_strdup (_("You cannot move a folder into itself."))
Tomas Bzatek cc540d5
+					    : g_strdup (_("You cannot copy a folder into itself."));
Tomas Bzatek cc540d5
+		secondary = g_strdup (_("The destination folder is inside the source folder."));
Tomas Bzatek cc540d5
+		
Tomas Bzatek cc540d5
+		response = run_warning (job,
Tomas Bzatek cc540d5
+					primary,
Tomas Bzatek cc540d5
+					secondary,
Tomas Bzatek cc540d5
+					NULL,
Tomas Bzatek cc540d5
+					GTK_STOCK_CANCEL, SKIP_ALL, SKIP,
Tomas Bzatek cc540d5
+					NULL);
Tomas Bzatek cc540d5
+
Tomas Bzatek cc540d5
+		if (response == 0 || response == GTK_RESPONSE_DELETE_EVENT) {
Tomas Bzatek cc540d5
+			abort_job (job);
Tomas Bzatek cc540d5
+		} else if (response == 1) { /* skip all */
Tomas Bzatek cc540d5
+			job->skip_all_error = TRUE;
Tomas Bzatek cc540d5
+		} else if (response == 2) { /* skip */
Tomas Bzatek cc540d5
+			/* do nothing */
Tomas Bzatek cc540d5
+		} else {
Tomas Bzatek cc540d5
+			g_assert_not_reached ();
Tomas Bzatek cc540d5
+		}
Tomas Bzatek cc540d5
+
Tomas Bzatek cc540d5
+		goto out;
Tomas Bzatek cc540d5
+	}
Tomas Bzatek cc540d5
+	
Tomas Bzatek cc540d5
  retry:
Tomas Bzatek cc540d5
 	
Tomas Bzatek cc540d5
 	error = NULL;
Tomas Bzatek cc540d5
@@ -3791,6 +3844,41 @@
Tomas Bzatek cc540d5
 	
Tomas Bzatek cc540d5
 	dest = get_target_file (src, dest_dir, same_fs);
Tomas Bzatek cc540d5
 
Tomas Bzatek cc540d5
+
Tomas Bzatek cc540d5
+	/* Don't allow recursive move/copy into itself.  
Tomas Bzatek cc540d5
+         * (We would get a file system error if we proceeded but it is nicer to 
Tomas Bzatek cc540d5
+         * detect and report it at this level) */
Tomas Bzatek cc540d5
+	if (g_file_struct_contains (dest_dir, src)) {
Tomas Bzatek cc540d5
+		if (job->skip_all_error) {
Tomas Bzatek cc540d5
+			g_error_free (error);
Tomas Bzatek cc540d5
+			goto out;
Tomas Bzatek cc540d5
+		}
Tomas Bzatek cc540d5
+		
Tomas Bzatek cc540d5
+		/*  the run_warning() frees all strings passed in automatically  */
Tomas Bzatek cc540d5
+		primary = move_job->is_move ? g_strdup (_("You cannot move a folder into itself."))
Tomas Bzatek cc540d5
+					    : g_strdup (_("You cannot copy a folder into itself."));
Tomas Bzatek cc540d5
+		secondary = g_strdup (_("The destination folder is inside the source folder."));
Tomas Bzatek cc540d5
+		
Tomas Bzatek cc540d5
+		response = run_warning (job,
Tomas Bzatek cc540d5
+					primary,
Tomas Bzatek cc540d5
+					secondary,
Tomas Bzatek cc540d5
+					NULL,
Tomas Bzatek cc540d5
+					GTK_STOCK_CANCEL, SKIP_ALL, SKIP,
Tomas Bzatek cc540d5
+					NULL);
Tomas Bzatek cc540d5
+		
Tomas Bzatek cc540d5
+		if (response == 0 || response == GTK_RESPONSE_DELETE_EVENT) {
Tomas Bzatek cc540d5
+			abort_job (job);
Tomas Bzatek cc540d5
+		} else if (response == 1) { /* skip all */
Tomas Bzatek cc540d5
+			job->skip_all_error = TRUE;
Tomas Bzatek cc540d5
+		} else if (response == 2) { /* skip */
Tomas Bzatek cc540d5
+			/* do nothing */
Tomas Bzatek cc540d5
+		} else {
Tomas Bzatek cc540d5
+			g_assert_not_reached ();
Tomas Bzatek cc540d5
+		}
Tomas Bzatek cc540d5
+
Tomas Bzatek cc540d5
+		goto out;
Tomas Bzatek cc540d5
+	}
Tomas Bzatek cc540d5
+
Tomas Bzatek cc540d5
  retry:
Tomas Bzatek cc540d5
 	
Tomas Bzatek cc540d5
 	flags = G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_NO_FALLBACK_FOR_MOVE;