From 78c69a0cdcfcd44d8e8be2d3973265a11ffdc05a Mon Sep 17 00:00:00 2001 From: Erik Duisters Date: Mon, 17 Dec 2018 19:10:47 +0100 Subject: [PATCH] Allow browsing sdcard when there is an unreadable file in it (eg .android_secure) Summary: On my Samsung Galaxy S5 mini (Android 6.0.1) browsing the sdcard is not possible because there is a hidden file .android_secure that is not readable by a normal user. For such a file File.exists() returns false while File.listFiles() does return it and SftpSubsystem.writeAttrs() throws an exception Test Plan: On a device where the SDCard cannot be browsed (I think its API 23 and up) install kdeconnect with this patch and verify that the SDCard can now be browsed successfully Reviewers: #kde_connect, albertvaka Reviewed By: #kde_connect, albertvaka Subscribers: albertvaka, nicolasfella, kdeconnect Tags: #kde_connect Differential Revision: https://phabricator.kde.org/D17644 --- .../Plugins/SftpPlugin/SimpleSftpServer.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java b/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java index 2df9896b..3df3bdb5 100644 --- a/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java +++ b/src/org/kde/kdeconnect/Plugins/SftpPlugin/SimpleSftpServer.java @@ -28,7 +28,6 @@ import org.apache.sshd.SshServer; import org.apache.sshd.common.Session; import org.apache.sshd.common.file.FileSystemFactory; import org.apache.sshd.common.file.FileSystemView; -import org.apache.sshd.common.file.SshFile; import org.apache.sshd.common.file.nativefs.NativeFileSystemView; import org.apache.sshd.common.file.nativefs.NativeSshFile; import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider; @@ -214,10 +213,11 @@ class SimpleSftpServer { this.context = context; } + // NativeFileSystemView.getFile(), NativeSshFile.getParentFile() and NativeSshFile.listSshFiles() call + // createNativeSshFile to create new NativeSshFiles so override that instead of getFile() to always create a AndroidSshFile @Override - protected SshFile getFile(final String dir, final String file) { - File fileObj = new File(dir, file); - return new AndroidSshFile(this, fileObj, userName, context); + public AndroidSshFile createNativeSshFile(String name, File file, String username) { + return new AndroidSshFile(this, name, file, username, context); } } @@ -226,8 +226,8 @@ class SimpleSftpServer { final private Context context; final private File file; - AndroidSshFile(final AndroidFileSystemView view, final File file, final String userName, Context context) { - super(view, file.getAbsolutePath(), file, userName); + AndroidSshFile(final AndroidFileSystemView view, String name, final File file, final String userName, Context context) { + super(view, name, file, userName); this.context = context; this.file = file; } @@ -279,6 +279,29 @@ class SimpleSftpServer { return ret; } + + // Based on https://github.com/wolpi/prim-ftpd/blob/master/primitiveFTPd/src/org/primftpd/filesystem/FsFile.java + @Override + public boolean doesExist() { + boolean exists = file.exists(); + + if (!exists) { + // file.exists() returns false when we don't have read permission + // try to figure out if it really does not exist + File parentFile = file.getParentFile(); + File[] children = parentFile.listFiles(); + if (children != null) { + for (File child : children) { + if (file.equals(child)) { + exists = true; + break; + } + } + } + } + + return exists; + } } static class SimplePasswordAuthenticator implements PasswordAuthenticator {