From ef0be9c2b7d2ea1aaa14e3280d1e61b90e04d1ec Mon Sep 17 00:00:00 2001 From: mgutt <10757176+mgutt@users.noreply.github.com> Date: Sat, 25 Oct 2025 15:50:53 +0200 Subject: [PATCH] Rename $move to $delete_empty_dirs and add commented parent-to-subfolder check - Renamed $move variable to $delete_empty_dirs for clearer intent - Variable now only set to true for rsync copy-delete (not for rsync-rename) - rsync-rename doesn't need cleanup since source is atomically moved - Added commented code to prevent moving directory into its own subdirectory --- emhttp/plugins/dynamix/nchan/file_manager | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/emhttp/plugins/dynamix/nchan/file_manager b/emhttp/plugins/dynamix/nchan/file_manager index 43bc4ea18..76bdd8fe4 100755 --- a/emhttp/plugins/dynamix/nchan/file_manager +++ b/emhttp/plugins/dynamix/nchan/file_manager @@ -167,8 +167,8 @@ if (!file_exists($empty_dir)) { mkdir($empty_dir); } -// initialize $move state: null = not a move operation (yet), true = rsync phase, false = cleanup phase -$move = null; +// initialize $delete_empty_dirs state: null = not a move operation (yet), true = rsync copy-delete phase, false = cleanup phase (done) +$delete_empty_dirs = null; while (true) { unset($action, $source, $target, $H, $sparse, $exist, $zfs); @@ -251,11 +251,11 @@ while (true) { // return status of running action if (!empty($pid)) { - // set move state for resume: true=rsync phase, false=cleanup phase - if ($move === null) $move = true; + // set delete_empty_dirs state for resume after file_manager restart (only relevant for rsync copy-delete) + if ($delete_empty_dirs === null) $delete_empty_dirs = true; // cleanup empty directories: simple status - if ($move === false) { + if ($delete_empty_dirs === false) { $reply['status'] = json_encode([ 'action' => $action, 'text' => [htmlspecialchars(mb_strimhalf(exec("tail -1 $status"), 70, '...'), ENT_QUOTES, 'UTF-8')] @@ -273,7 +273,6 @@ while (true) { } else { $target = validname($target, false); if ($target) { - $move = true; $mkpath = isdir($target) ? '--mkpath' : ''; // determine if we can use rsync with rename(2) @@ -335,6 +334,14 @@ while (true) { } } + // // target must not be a subdirectory of source parent (backup-dir should be outside source tree) + // $source_parent_dir = dirname($valid_source_path); + // if (strpos(rtrim($target,'/'), rtrim($source_parent_dir,'/') . '/') === 0) { + // $reply['error'] = 'Cannot move directory into its own subdirectory'; + // $use_rsync_rename = false; + // break 2; // break out of both foreach and if + // } + } } @@ -350,6 +357,7 @@ while (true) { // use rsync copy-delete } else { + $delete_empty_dirs = true; // cleanup needed: rsync --remove-source-files leaves empty directories $cmd = "rsync -ahPIX$H $sparse $exist $mkpath --out-format=%f --info=flist0,misc0,stats0,name1,progress2 --remove-source-files ".quoted($source)." ".escapeshellarg($target)." 1>$status 2>$error & echo \$!"; exec($cmd, $pid); } @@ -383,7 +391,8 @@ while (true) { case 99: // kill running background process if (!empty($pid)) exec("kill $pid"); delete_file($active, $pid_file, $status, $error); - unset($pid, $move); + unset($pid); + $delete_empty_dirs = null; break; default: continue 2; @@ -396,9 +405,9 @@ while (true) { } if ($pid === false) { - if (!empty($move)) { + if (!empty($delete_empty_dirs)) { exec("find ".quoted($source)." -type d -empty -print -delete 1>$status 2>$null & echo \$!", $pid); - $move = false; + $delete_empty_dirs = false; $pid = pgrep($pid); } else { if ($action != 15) { @@ -418,7 +427,8 @@ while (true) { } if (file_exists($error)) $reply['error'] = str_replace("\n","
", trim(file_get_contents($error))); delete_file($active, $pid_file, $status, $error); - unset($pid, $move); + unset($pid); + $delete_empty_dirs = null; } } }