From 6848f1a38e6d6f4e004a63efb5c9ddedb884ccef Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 6 Nov 2020 11:07:22 +0100 Subject: [PATCH] Renamed IrregularUnmountCleaner and relayouted code --- .../mountpoint/IrregularUnmountCleaner.java | 64 +++++++++++++++++++ .../mountpoint/UnregularUnmountCleaner.java | 60 ----------------- .../cryptomator/ui/launcher/UiLauncher.java | 4 +- 3 files changed, 66 insertions(+), 62 deletions(-) create mode 100644 main/commons/src/main/java/org/cryptomator/common/mountpoint/IrregularUnmountCleaner.java delete mode 100644 main/commons/src/main/java/org/cryptomator/common/mountpoint/UnregularUnmountCleaner.java diff --git a/main/commons/src/main/java/org/cryptomator/common/mountpoint/IrregularUnmountCleaner.java b/main/commons/src/main/java/org/cryptomator/common/mountpoint/IrregularUnmountCleaner.java new file mode 100644 index 000000000..3104ae20b --- /dev/null +++ b/main/commons/src/main/java/org/cryptomator/common/mountpoint/IrregularUnmountCleaner.java @@ -0,0 +1,64 @@ +package org.cryptomator.common.mountpoint; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +public class IrregularUnmountCleaner { + + public static Logger LOG = LoggerFactory.getLogger(IrregularUnmountCleaner.class); + + public static void removeUnregularUnmountDebris(Path dirContainingMountPoints) { + IOException cleanupFailed = new IOException("Cleanup failed"); + + try { + LOG.debug("Performing cleanup of mountpoint dir {}.", dirContainingMountPoints); + for (Path p : Files.newDirectoryStream(dirContainingMountPoints)) { + try { + var attr = Files.readAttributes(p, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); + if (attr.isOther() && attr.isDirectory()) { // yes, this is possible with windows junction points -.- + Files.delete(p); + } else if (attr.isDirectory()) { + deleteEmptyDir(p); + } else if (attr.isSymbolicLink()) { + deleteDeadLink(p); + } else { + LOG.debug("Found non-directory element in mountpoint dir: {}", p); + } + } catch (IOException e) { + cleanupFailed.addSuppressed(e); + } + } + + if (cleanupFailed.getSuppressed().length > 0) { + throw cleanupFailed; + } + } catch (IOException e) { + LOG.warn("Unable to perform cleanup of mountpoint dir {}.", dirContainingMountPoints, e); + } + + } + + private static void deleteEmptyDir(Path dir) throws IOException { + assert Files.isDirectory(dir, LinkOption.NOFOLLOW_LINKS); + try { + Files.delete(dir); // attempt to delete dir non-recursively (will fail, if there are contents) + } catch (DirectoryNotEmptyException e) { + LOG.info("Found non-empty directory in mountpoint dir: {}", dir); + } + } + + private static void deleteDeadLink(Path symlink) throws IOException { + assert Files.isSymbolicLink(symlink); + if (Files.notExists(symlink)) { // following link: target does not exist + Files.delete(symlink); + } + } + +} diff --git a/main/commons/src/main/java/org/cryptomator/common/mountpoint/UnregularUnmountCleaner.java b/main/commons/src/main/java/org/cryptomator/common/mountpoint/UnregularUnmountCleaner.java deleted file mode 100644 index 3229f909c..000000000 --- a/main/commons/src/main/java/org/cryptomator/common/mountpoint/UnregularUnmountCleaner.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.cryptomator.common.mountpoint; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.LinkOption; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Collection; - -public class UnregularUnmountCleaner { - - public static Logger LOG = LoggerFactory.getLogger(UnregularUnmountCleaner.class); - - public static void removeUnregularUnmountDebris(Path dirOfMountPoints) { - Collection exceptionCatcher = new ArrayList<>(); - try { - LOG.debug("Performing cleanup of mountpoint dir {}.", dirOfMountPoints); - Files.list(dirOfMountPoints).filter(p -> { - if (Files.isDirectory(p, LinkOption.NOFOLLOW_LINKS)) { - return true; - } else { - LOG.debug("Found non-directory element in mountpoint dir: {}", p); - return false; - } - }).forEach(dir -> { - try { - try { - Files.readAttributes(dir, BasicFileAttributes.class); //we follow the link and see if it exists - } catch (NoSuchFileException e) { - Files.delete(dir); //broken link file, we delete it - LOG.debug("Removed broken entry {} from mountpoint dir."); - return; - } - //check if dir is empty - if (Files.list(dir).findFirst().isEmpty()) { - Files.delete(dir); - LOG.debug("Removed empty dir {} from mountpoint dir."); - } else { - LOG.debug("Found non-empty directory in mountpoint dir: {}", dir); - } - } catch (IOException e) { - exceptionCatcher.add(e); - } - }); - - exceptionCatcher.forEach(exception -> { - LOG.debug("Unable to clean element from mountpoint dir due to", exception); - }); - } catch (IOException e) { - LOG.debug("Unable to perform cleanup of mountpoint dir {}.", dirOfMountPoints, e); - } - - } - -} diff --git a/main/ui/src/main/java/org/cryptomator/ui/launcher/UiLauncher.java b/main/ui/src/main/java/org/cryptomator/ui/launcher/UiLauncher.java index 9b9e7ee05..f1de98ea7 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/launcher/UiLauncher.java +++ b/main/ui/src/main/java/org/cryptomator/ui/launcher/UiLauncher.java @@ -1,7 +1,7 @@ package org.cryptomator.ui.launcher; import org.cryptomator.common.Environment; -import org.cryptomator.common.mountpoint.UnregularUnmountCleaner; +import org.cryptomator.common.mountpoint.IrregularUnmountCleaner; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.vaults.Vault; import org.cryptomator.jni.JniException; @@ -67,7 +67,7 @@ public class UiLauncher { //clean leftovers of not-regularly unmounted vaults //see https://github.com/cryptomator/cryptomator/issues/1013 and https://github.com/cryptomator/cryptomator/issues/1061 - env.getMountPointsDir().ifPresent(UnregularUnmountCleaner::removeUnregularUnmountDebris); + env.getMountPointsDir().ifPresent(IrregularUnmountCleaner::removeUnregularUnmountDebris); // auto unlock Collection vaultsToAutoUnlock = vaults.filtered(this::shouldAttemptAutoUnlock);