From e8782308bb09049587534de8cc96233dedd4da20 Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Tue, 25 Oct 2022 18:19:59 +0800 Subject: [PATCH 1/8] Allow case sensitive local file rename --- .../filemanager/filesystem/Operations.java | 106 +++++++++++------- 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index 4e17a514d..874b42037 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -441,6 +441,63 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); + private final Boolean isCaseSensitiveRename = + !oldFile.getSimpleName().equals(newFile.getSimpleName()) && + oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()); + + // random string that is appended to file to prevent name collision + private static final String TEMP_FILE_EXT = "qwerty"; + + private boolean defaultRename( + @NonNull HybridFile oldFile, + @NonNull HybridFile newFile + ) { + File file = new File(oldFile.getPath()); + File file1 = new File(newFile.getPath()); + boolean result = false; + + switch (oldFile.getMode()) { + case FILE: + int mode = checkFolder(file.getParentFile(), context); + if (mode == 2) { + errorCallBack.launchSAF(oldFile, newFile); + } else if (mode == 1 || mode == 0) { + try { + RenameOperation.renameFolder(file, file1, context); + result = true; + } catch (ShellNotRunningException e) { + LOG.warn("failed to rename file in local filesystem", e); + } + boolean a = !file.exists() && file1.exists(); + if (!a && rootMode) { + try { + RenameFileCommand.INSTANCE.renameFile(file.getPath(), file1.getPath()); + result = true; + } catch (ShellNotRunningException e) { + LOG.warn("failed to rename file in local filesystem", e); + } + oldFile.setMode(OpenMode.ROOT); + newFile.setMode(OpenMode.ROOT); + a = !file.exists() && file1.exists(); + } + errorCallBack.done(newFile, a); + } + break; + case ROOT: + try { + RenameFileCommand.INSTANCE.renameFile(file.getPath(), file1.getPath()); + result = true; + } catch (ShellNotRunningException e) { + LOG.warn("failed to rename file in root", e); + } + + newFile.setMode(OpenMode.ROOT); + errorCallBack.done(newFile, true); + break; + } + return result; + } + private Function safRenameFile = input -> { boolean result = false; @@ -462,7 +519,7 @@ public class Operations { return null; } - if (newFile.exists()) { + if (newFile.exists() && !isCaseSensitiveRename) { errorCallBack.exists(newFile); return null; } @@ -610,44 +667,15 @@ public class Operations { false)); return null; } else { - File file = new File(oldFile.getPath()); - File file1 = new File(newFile.getPath()); - switch (oldFile.getMode()) { - case FILE: - int mode = checkFolder(file.getParentFile(), context); - if (mode == 2) { - errorCallBack.launchSAF(oldFile, newFile); - } else if (mode == 1 || mode == 0) { - try { - RenameOperation.renameFolder(file, file1, context); - } catch (ShellNotRunningException e) { - LOG.warn("failed to rename file in local filesystem", e); - } - boolean a = !file.exists() && file1.exists(); - if (!a && rootMode) { - try { - RenameFileCommand.INSTANCE.renameFile(file.getPath(), file1.getPath()); - } catch (ShellNotRunningException e) { - LOG.warn("failed to rename file in local filesystem", e); - } - oldFile.setMode(OpenMode.ROOT); - newFile.setMode(OpenMode.ROOT); - a = !file.exists() && file1.exists(); - } - errorCallBack.done(newFile, a); - return null; - } - break; - case ROOT: - try { - RenameFileCommand.INSTANCE.renameFile(file.getPath(), file1.getPath()); - } catch (ShellNotRunningException e) { - LOG.warn("failed to rename file in root", e); - } - - newFile.setMode(OpenMode.ROOT); - errorCallBack.done(newFile, true); - break; + if (isCaseSensitiveRename) { + HybridFile tempFile = new HybridFile( + oldFile.mode, oldFile.getPath().concat(TEMP_FILE_EXT) + ); + if (defaultRename(oldFile, tempFile)) { + defaultRename(tempFile, newFile); + } + } else { + defaultRename(oldFile, newFile); } } return null; From 8bc1656154b0025b62dabf3f7f84f1d91ac2079d Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Wed, 26 Oct 2022 11:47:22 +0800 Subject: [PATCH 2/8] Allow case sensitive local file rename --- .../filemanager/filesystem/Operations.java | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index 874b42037..671178905 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -442,16 +442,14 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); private final Boolean isCaseSensitiveRename = - !oldFile.getSimpleName().equals(newFile.getSimpleName()) && - oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()); + !oldFile.getSimpleName().equals(newFile.getSimpleName()) + && oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()); - // random string that is appended to file to prevent name collision - private static final String TEMP_FILE_EXT = "qwerty"; + // random string that is appended to file to prevent name collision, max file name is 255 + // bytes + private static final String TEMP_FILE_EXT = "u0CtHRqWUnvxIaeBQ@nY2umVm9MDyR1P"; - private boolean defaultRename( - @NonNull HybridFile oldFile, - @NonNull HybridFile newFile - ) { + private boolean localRename(@NonNull HybridFile oldFile, @NonNull HybridFile newFile) { File file = new File(oldFile.getPath()); File file1 = new File(newFile.getPath()); boolean result = false; @@ -668,14 +666,17 @@ public class Operations { return null; } else { if (isCaseSensitiveRename) { - HybridFile tempFile = new HybridFile( - oldFile.mode, oldFile.getPath().concat(TEMP_FILE_EXT) - ); - if (defaultRename(oldFile, tempFile)) { - defaultRename(tempFile, newFile); + HybridFile tempFile = + new HybridFile(oldFile.mode, oldFile.getPath().concat(TEMP_FILE_EXT)); + if (localRename(oldFile, tempFile)) { + // stop if first rename failed + if (!localRename(tempFile, newFile)) { + // revert changes + localRename(tempFile, oldFile); + } } } else { - defaultRename(oldFile, newFile); + localRename(oldFile, newFile); } } return null; From b56b12b960fdf68f49e26455f806de049e19161a Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Wed, 26 Oct 2022 20:36:22 +0800 Subject: [PATCH 3/8] Allow case sensitive local file rename --- .../amaze/filemanager/filesystem/Operations.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index 671178905..c845d400c 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -442,8 +442,8 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); private final Boolean isCaseSensitiveRename = - !oldFile.getSimpleName().equals(newFile.getSimpleName()) - && oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()); + oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()) + && !oldFile.getSimpleName().equals(newFile.getSimpleName()); // random string that is appended to file to prevent name collision, max file name is 255 // bytes @@ -668,12 +668,10 @@ public class Operations { if (isCaseSensitiveRename) { HybridFile tempFile = new HybridFile(oldFile.mode, oldFile.getPath().concat(TEMP_FILE_EXT)); - if (localRename(oldFile, tempFile)) { - // stop if first rename failed - if (!localRename(tempFile, newFile)) { - // revert changes - localRename(tempFile, oldFile); - } + if (localRename(oldFile, tempFile) && !localRename(tempFile, newFile)) { + // revert changes + LOG.warn("reverting temporary file rename"); + localRename(tempFile, oldFile); } } else { localRename(oldFile, newFile); From 73cf6a0b1281f0ec00219fe8d44965fe8b80802e Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Fri, 28 Oct 2022 22:16:13 +0800 Subject: [PATCH 4/8] Refactored rename function and fixed errorCallback invocations --- .../filemanager/filesystem/Operations.java | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index c845d400c..765d6f80c 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -441,12 +441,18 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); - private final Boolean isCaseSensitiveRename = + /** + * Determines whether double rename is required based on original and new file name regardless + * of the case-sensitivity of the filesystem + */ + private final boolean isCaseSensitiveRename = oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()) && !oldFile.getSimpleName().equals(newFile.getSimpleName()); - // random string that is appended to file to prevent name collision, max file name is 255 - // bytes + /** + * random string that is appended to file to prevent name collision, max file name is 255 + * bytes + */ private static final String TEMP_FILE_EXT = "u0CtHRqWUnvxIaeBQ@nY2umVm9MDyR1P"; private boolean localRename(@NonNull HybridFile oldFile, @NonNull HybridFile newFile) { @@ -457,45 +463,52 @@ public class Operations { switch (oldFile.getMode()) { case FILE: int mode = checkFolder(file.getParentFile(), context); - if (mode == 2) { - errorCallBack.launchSAF(oldFile, newFile); - } else if (mode == 1 || mode == 0) { + if (mode == 1 || mode == 0) { try { RenameOperation.renameFolder(file, file1, context); - result = true; } catch (ShellNotRunningException e) { LOG.warn("failed to rename file in local filesystem", e); } - boolean a = !file.exists() && file1.exists(); - if (!a && rootMode) { + result = !file.exists() && file1.exists(); + if (!result && rootMode) { try { RenameFileCommand.INSTANCE.renameFile(file.getPath(), file1.getPath()); - result = true; } catch (ShellNotRunningException e) { LOG.warn("failed to rename file in local filesystem", e); } oldFile.setMode(OpenMode.ROOT); newFile.setMode(OpenMode.ROOT); - a = !file.exists() && file1.exists(); + result = !file.exists() && file1.exists(); } - errorCallBack.done(newFile, a); } break; case ROOT: try { - RenameFileCommand.INSTANCE.renameFile(file.getPath(), file1.getPath()); - result = true; + result = RenameFileCommand.INSTANCE.renameFile(file.getPath(), file1.getPath()); } catch (ShellNotRunningException e) { LOG.warn("failed to rename file in root", e); } - newFile.setMode(OpenMode.ROOT); - errorCallBack.done(newFile, true); break; } return result; } + private boolean localDoubleRename(@NonNull HybridFile oldFile, @NonNull HybridFile newFile) { + HybridFile tempFile = new HybridFile(oldFile.mode, oldFile.getPath().concat(TEMP_FILE_EXT)); + if (localRename(oldFile, tempFile)) { + if (localRename(tempFile, newFile)) { + return true; + } else { + // attempts to rollback + // changes the temporary file name back to original file name + LOG.warn("reverting temporary file rename"); + return localRename(tempFile, oldFile); + } + } + return false; + } + private Function safRenameFile = input -> { boolean result = false; @@ -665,17 +678,21 @@ public class Operations { false)); return null; } else { - if (isCaseSensitiveRename) { - HybridFile tempFile = - new HybridFile(oldFile.mode, oldFile.getPath().concat(TEMP_FILE_EXT)); - if (localRename(oldFile, tempFile) && !localRename(tempFile, newFile)) { - // revert changes - LOG.warn("reverting temporary file rename"); - localRename(tempFile, oldFile); + File file = new File(oldFile.getPath()); + if (oldFile.getMode() == OpenMode.FILE) { + int mode = checkFolder(file.getParentFile(), context); + if (mode == 2) { + errorCallBack.launchSAF(oldFile, newFile); } - } else { - localRename(oldFile, newFile); } + + boolean result; + if (isCaseSensitiveRename) { + result = localDoubleRename(oldFile, newFile); + } else { + result = localRename(oldFile, newFile); + } + errorCallBack.done(newFile, result); } return null; } From 9a1b5acc078c5961fcf723ef5eb97d1ec62fc57d Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Sat, 5 Nov 2022 20:23:08 +0800 Subject: [PATCH 5/8] Changed file name case check to local filesystem case-sensitivity check. --- .../filemanager/filesystem/Operations.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index 765d6f80c..e75c14c39 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -30,6 +30,7 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.Objects; import java.util.concurrent.Executor; import org.apache.commons.net.ftp.FTPClient; @@ -441,13 +442,12 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); - /** - * Determines whether double rename is required based on original and new file name regardless - * of the case-sensitivity of the filesystem - */ - private final boolean isCaseSensitiveRename = - oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()) - && !oldFile.getSimpleName().equals(newFile.getSimpleName()); + private final boolean isLocalFilesystemCaseInsensitive = + Objects.requireNonNull(oldFile.getFile()).exists() + && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toUpperCase()) + .exists() + && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toLowerCase()) + .exists(); /** * random string that is appended to file to prevent name collision, max file name is 255 @@ -530,7 +530,7 @@ public class Operations { return null; } - if (newFile.exists() && !isCaseSensitiveRename) { + if (newFile.exists() && !isLocalFilesystemCaseInsensitive) { errorCallBack.exists(newFile); return null; } @@ -687,7 +687,7 @@ public class Operations { } boolean result; - if (isCaseSensitiveRename) { + if (isLocalFilesystemCaseInsensitive) { result = localDoubleRename(oldFile, newFile); } else { result = localRename(oldFile, newFile); From 46a7a2a24289a82cfafa4f697cb0a9c2c7161e94 Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Wed, 9 Nov 2022 01:47:38 +0800 Subject: [PATCH 6/8] Changed file name case check to local filesystem case-sensitivity check. --- .../main/java/com/amaze/filemanager/filesystem/Operations.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index e75c14c39..e93dea2cf 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -443,7 +443,8 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); private final boolean isLocalFilesystemCaseInsensitive = - Objects.requireNonNull(oldFile.getFile()).exists() + oldFile.isLocal() + && Objects.requireNonNull(oldFile.getFile()).exists() && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toUpperCase()) .exists() && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toLowerCase()) From 5cb5d69d03be281f5c32278401d0b2cdaab8bd73 Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Thu, 17 Nov 2022 18:22:33 +0800 Subject: [PATCH 7/8] Revert "Changed file name case check to local filesystem case-sensitivity check." This reverts commit 46a7a2a24289a82cfafa4f697cb0a9c2c7161e94. --- .../main/java/com/amaze/filemanager/filesystem/Operations.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index e93dea2cf..e75c14c39 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -443,8 +443,7 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); private final boolean isLocalFilesystemCaseInsensitive = - oldFile.isLocal() - && Objects.requireNonNull(oldFile.getFile()).exists() + Objects.requireNonNull(oldFile.getFile()).exists() && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toUpperCase()) .exists() && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toLowerCase()) From c54f3f21ff2154fc772e4501436114de7263d9c7 Mon Sep 17 00:00:00 2001 From: stevealexrs Date: Thu, 17 Nov 2022 18:22:41 +0800 Subject: [PATCH 8/8] Revert "Changed file name case check to local filesystem case-sensitivity check." This reverts commit 9a1b5acc078c5961fcf723ef5eb97d1ec62fc57d. --- .../filemanager/filesystem/Operations.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index e75c14c39..765d6f80c 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -30,7 +30,6 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; -import java.util.Objects; import java.util.concurrent.Executor; import org.apache.commons.net.ftp.FTPClient; @@ -442,12 +441,13 @@ public class Operations { private final DataUtils dataUtils = DataUtils.getInstance(); - private final boolean isLocalFilesystemCaseInsensitive = - Objects.requireNonNull(oldFile.getFile()).exists() - && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toUpperCase()) - .exists() - && new File(oldFile.getFile().getParent(), oldFile.getSimpleName().toLowerCase()) - .exists(); + /** + * Determines whether double rename is required based on original and new file name regardless + * of the case-sensitivity of the filesystem + */ + private final boolean isCaseSensitiveRename = + oldFile.getSimpleName().equalsIgnoreCase(newFile.getSimpleName()) + && !oldFile.getSimpleName().equals(newFile.getSimpleName()); /** * random string that is appended to file to prevent name collision, max file name is 255 @@ -530,7 +530,7 @@ public class Operations { return null; } - if (newFile.exists() && !isLocalFilesystemCaseInsensitive) { + if (newFile.exists() && !isCaseSensitiveRename) { errorCallBack.exists(newFile); return null; } @@ -687,7 +687,7 @@ public class Operations { } boolean result; - if (isLocalFilesystemCaseInsensitive) { + if (isCaseSensitiveRename) { result = localDoubleRename(oldFile, newFile); } else { result = localRename(oldFile, newFile);