Browse Source

Merge pull request #1533 from jderriks/1.11.x

Github #1532 Filesystem inconsistency when moving folders
Julio 8 years ago
parent
commit
08ed2d721b

+ 60 - 36
main/inc/lib/fileManage.lib.php

@@ -177,40 +177,59 @@ function my_rename($file_path, $new_file_name) {
  * @return bool true if the move succeed, false otherwise.
  * @see move() uses check_name_exist() and copyDirTo() functions
  */
-function move($source, $target, $forceMove = false, $moveContent = false)
+function move($source, $target, $forceMove = true, $moveContent = false) 
 {
-	if (check_name_exist($source)) {
-		$file_name = basename($source);
+    $target = realpath($target); // remove trailing slash
+    $source = realpath($source);
+    if (check_name_exist($source)) {
+        $file_name = basename($source);
+        // move onto self illegal: mv a/b/c a/b/c or mv a/b/c a/b
+        if (strcasecmp($target, dirname($source)) === 0) {
+               return false;
+        }
         $isWindowsOS = api_is_windows_os();
         $canExec = function_exists('exec');
-
-		/* File case */
-		if (is_file($source)) {
-			if ($forceMove && !$isWindowsOS && $canExec) {
-				exec('mv ' . $source . ' ' . $target . '/' . $file_name);
-			} else {
-				copy($source, $target . '/' . $file_name);
-				unlink($source);
-			}
-			return true;
-		} elseif (is_dir($source)) {
-			/* Directory */
-			if ($forceMove && !$isWindowsOS && $canExec) {
-				if ($moveContent) {
-					$base = basename($source);
-					exec('mv '.$source.'/* '.$target.$base.'/');
-					exec('rm -rf '.$source);
-				} else {
-					exec('mv $source $target');
-				}
-			} else {
-				copyDirTo($source, $target);
-			}
-			return true;
-		}
-	} else {
-		return false;
-	}
+      
+        /* File case */
+        if (is_file($source)) {
+            if ($forceMove && !$isWindowsOS && $canExec) {
+                exec('mv ' . $source . ' ' . $target . '/' . $file_name);
+            } else {
+                copy($source, $target . '/' . $file_name);
+                unlink($source);
+            }
+            return true;
+        } elseif (is_dir($source)) {
+            // move dir down will cause loop: mv a/b/ a/b/c/ not legal
+            if (strncasecmp($target, $source, strlen($source)) == 0) {
+                return false;
+            }
+            /* Directory */
+            if ($forceMove && !$isWindowsOS && $canExec) {
+                if ($moveContent) {
+                    $base = basename($source);
+                    $out = []; $retVal = -1;
+                    exec('mv '.$source.'/* '.$target.'/'.$base, $out, $retVal);
+                    if ($retVal !== 0) {
+                        return false; // mv should return 0 on success
+                    }
+                    exec('rm -rf '.$source);
+                } else {
+                    $out = []; $retVal = -1;
+                    exec("mv $source $target", $out, $retVal);
+                    if ($retVal !== 0) {
+                        error_log("Chamilo error fileManage.lib.php: mv $source $target\n");
+                        return false; // mv should return 0 on success
+                    }
+                }
+            } else {
+                return copyDirTo($source, $target);        
+            }
+            return true;
+        }
+    } else {
+        return false;
+    }
 }
 
 /**
@@ -219,18 +238,23 @@ function move($source, $target, $forceMove = false, $moveContent = false)
  * @author Hugues Peeters <peeters@ipm.ucl.ac.be>
  * @param string $orig_dir_path the path of the directory to move
  * @param string $destination the path of the new area
- * @return void
+ * @return bool false on error
  */
-function copyDirTo($orig_dir_path, $destination, $move = true)
-{
+function copyDirTo($orig_dir_path, $destination, $move = true) {
     $fs = new Filesystem();
     if (is_dir($orig_dir_path)) {
-        $fs->mirror($orig_dir_path, $destination);
-
+        $destinationDir = $destination . "/" . basename($orig_dir_path);
+        $fs->mkdir($destinationDir);
+        if (! is_dir($destinationDir)){
+            error_log("Chamilo copyDirTo cannot mkdir $destinationDir\n");
+            return false; // could not create destination dir
+        }
+        $fs->mirror($orig_dir_path, $destinationDir);
         if ($move) {
             $fs->remove($orig_dir_path);
         }
     }
+    return true;
 }
 
 /**

+ 4 - 3
main/lang/dutch/trad4all.inc.php

@@ -6545,8 +6545,9 @@ $SupportedScormContentMakers = "Ondersteunde Scorm Auteurstools";
 $DisableEndDate = "Schakel einddatum uit";
 $ForumCategories = "Forum categorieën";
 $Copy = "Copy";
-$ArchiveDirCleanup = "Archive directory cleanup";
-$ArchiveDirCleanupProceedButton = "Proceed with cleanup";
+$ArchiveDirCleanupDescr = "Chamilo bewaart tijdelijke bestanden (voor backups, exports, etc) in de app/cache/ directory. Dit kan onnodig veel diskruimte kosten. Klik op onderstaande knop om de app/cache map op te schonen. Deze actie dient te worden geautomatiseerd via cron maar als dat niet kan, gebruik dan deze knop regelmatig om alle tijdelijke bestanden te wissen.";
+$ArchiveDirCleanup = "Archief directory opschonen";
+$ArchiveDirCleanupProceedButton = "Doorgaan met opschonen";
 $ArchiveDirCleanupSucceeded = "Het archief is succesvol opgeschoond";
 $EnableStartTime = "Instellen tijdstip begin";
 $EnableEndTime = "Instellen tijdstip einde";
@@ -6851,4 +6852,4 @@ $YourPasswordContainsSequences = "Uw wachtwoord bevat reeksen";
 $PasswordVeryWeak = "Heel zwak";
 $UserXHasBeenAssignedToBoss = "U bent toegewezen aan de student %s";
 $UserXHasBeenAssignedToBossWithUrlX = "U bent als tutor toegewezen aan student %s. U kunt zijn profiel bekijken van hier: %s";
-?>
+?>

+ 3 - 3
main/lang/english/trad4all.inc.php

@@ -6661,10 +6661,10 @@ $DisableEndDate = "Disable end date";
 $ForumCategories = "Forum Categories";
 $Copy = "Copy";
 $ArchiveDirCleanup = "Archive directory cleanup";
-$ArchiveDirCleanupDescr = "Chamilo keeps a copy of most of the temporary files it generates (for backups, exports, copies, etc) into its archive/ directory. After a while, this can add up to a very large amount of disk space being used for nothing. Click the button below to clean your archive directory up. This operation should be automated by a cron process, but if this is not possible, you can come to this page regularly to remove all temporary files from the directory.";
+$ArchiveDirCleanupDescr = "Chamilo keeps a copy of most of the temporary files it generates (for backups, exports, copies, etc) into its app/cache/ archive directory. After a while, this can add up to a very large amount of disk space being used for nothing. Click the button below to cleanup your app/cache directory. This operation should be automated by a cron process, but if this is not possible, you can come to this page regularly to remove all temporary files from the directory.";
 $ArchiveDirCleanupProceedButton = "Proceed with cleanup";
-$ArchiveDirCleanupSucceeded = "The archive/ directory cleanup has been executed successfully.";
-$ArchiveDirCleanupFailed = "For some reason, the archive/ directory could not be cleaned up. Please clean it up by manually connecting to the server and delete all files and symbolic links under the chamilo/archive/ directory, except the .htaccess file. On Linux: # find archive/ \( -type f -or -type l \) -not -name .htaccess -exec echo rm -v \{} \;";
+$ArchiveDirCleanupSucceeded = "The archive directory cleanup has been executed successfully.";
+$ArchiveDirCleanupFailed = "For some reason, the archive directory could not be cleaned up. Please clean it up by manually connecting to the server and delete all files and symbolic links under the chamilo/archive/ directory, except the .htaccess file. On Linux: # find archive/ \( -type f -or -type l \) -not -name .htaccess -exec echo rm -v \{} \;";
 $EnableStartTime = "Enable start time";
 $EnableEndTime = "Enable end time";
 $LocalTimeUsingPortalTimezoneXIsY = "The local time in the portal timezone (%s) is %s";