From 34533f4df2c9103c112a13bbe47c0595879d2407 Mon Sep 17 00:00:00 2001 From: Nova Date: Tue, 29 Apr 2014 23:28:56 +0800 Subject: [PATCH] Add root directory for ftp server. Fix some bugs on huawei p6. --- .../FileExplorerPreferenceActivity.java | 18 ++++++++++++- .../micode/fileexplorer/FileViewActivity.java | 9 +++++++ .../fileexplorer/ServerControlActivity.java | 15 ++++++++++- src/org/swiftp/CmdPWD.java | 6 ++++- src/org/swiftp/Globals.java | 26 +++++++++++++++++++ src/org/swiftp/SessionThread.java | 4 +-- 6 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/net/micode/fileexplorer/FileExplorerPreferenceActivity.java b/src/net/micode/fileexplorer/FileExplorerPreferenceActivity.java index e2a3215..b44d3bd 100644 --- a/src/net/micode/fileexplorer/FileExplorerPreferenceActivity.java +++ b/src/net/micode/fileexplorer/FileExplorerPreferenceActivity.java @@ -20,6 +20,7 @@ package net.micode.fileexplorer; import java.io.File; +import java.io.IOException; import android.content.Context; import android.content.SharedPreferences; @@ -104,7 +105,22 @@ public static boolean isReadRoot(Context context) { SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); boolean isReadRootFromSetting = settings.getBoolean(READ_ROOT, false); - boolean isReadRootWhenSettingPrimaryFolderWithoutSdCardPrefix = !getPrimaryFolder(context).startsWith(Util.getSdDirectory()); + boolean isReadRootWhenSettingPrimaryFolderWithoutSdCardPrefix; + + /* Modified by Nova, fix a bug. + * In huawei p6, Util.getSdDirectory() returns "/storage/emulated/0", primary folder is "/mnt/sdcard", they are the same, + * it make isReadRootWhenSettingPrimaryFolderWithoutSdCardPrefix get a wrong value. + */ + String primary, sd; + try { + primary = (new File(getPrimaryFolder(context))).getCanonicalPath(); + sd = (new File(Util.getSdDirectory())).getCanonicalPath(); + } catch (IOException e) { + e.printStackTrace(); + primary = getPrimaryFolder(context); + sd = Util.getSdDirectory(); + } + isReadRootWhenSettingPrimaryFolderWithoutSdCardPrefix = !primary.startsWith(sd); return isReadRootFromSetting || isReadRootWhenSettingPrimaryFolderWithoutSdCardPrefix; } diff --git a/src/net/micode/fileexplorer/FileViewActivity.java b/src/net/micode/fileexplorer/FileViewActivity.java index 2678bb5..2a8dfa7 100644 --- a/src/net/micode/fileexplorer/FileViewActivity.java +++ b/src/net/micode/fileexplorer/FileViewActivity.java @@ -20,6 +20,7 @@ package net.micode.fileexplorer; import java.io.File; +import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; @@ -174,6 +175,14 @@ public void onClick(View v) { currentDir = uri.getPath(); } } + + // added by Nova, for root path checking. + try { + currentDir = new File(currentDir).getCanonicalPath(); + } catch (IOException e) { + Log.d(LOG_TAG, "fail to get CanonicalPath, currentDir = " + currentDir); + } + mFileViewInteractionHub.setCurrentPath(currentDir); Log.i(LOG_TAG, "CurrentDir = " + currentDir); diff --git a/src/net/micode/fileexplorer/ServerControlActivity.java b/src/net/micode/fileexplorer/ServerControlActivity.java index fe5b666..d9695b2 100644 --- a/src/net/micode/fileexplorer/ServerControlActivity.java +++ b/src/net/micode/fileexplorer/ServerControlActivity.java @@ -246,7 +246,18 @@ private void setText(int id, String text) { OnClickListener startStopListener = new OnClickListener() { public void onClick(View v) { Globals.setLastError(null); - File chrootDir = new File(Defaults.chrootDir); + + /* + * check whether ftp user can access root path according to the settings. + * added by Nova. + */ + File chrootDir; + if (FileExplorerPreferenceActivity.isReadRoot(mActivity)) { + chrootDir = new File(GlobalConsts.ROOT_PATH); // system root, "/" + } else { + chrootDir = new File(Defaults.chrootDir); // sd home + } + if (!chrootDir.isDirectory()) return; @@ -254,6 +265,8 @@ public void onClick(View v) { Intent intent = new Intent(context, FTPServerService.class); Globals.setChrootDir(chrootDir); + Globals.setPrimaryDir(new File(Defaults.chrootDir)); + if (!FTPServerService.isRunning()) { warnIfNoExternalStorage(); if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { diff --git a/src/org/swiftp/CmdPWD.java b/src/org/swiftp/CmdPWD.java index ac6d6c8..487b768 100644 --- a/src/org/swiftp/CmdPWD.java +++ b/src/org/swiftp/CmdPWD.java @@ -43,7 +43,11 @@ public void run() { File workingDir = sessionThread.getWorkingDir(); String currentDir = workingDir != null ? workingDir.getCanonicalPath() : Globals.getChrootDir() .getCanonicalPath(); - currentDir = currentDir.substring(Globals.getChrootDir().getCanonicalPath().length()); + + // modified by nova, if root path is "/", it requires special handling + if (!Globals.getChrootDir().getCanonicalPath().equals("/")) { + currentDir = currentDir.substring(Globals.getChrootDir().getCanonicalPath().length()); + } // The root directory requires special handling to restore its // leading slash if (currentDir.length() == 0) { diff --git a/src/org/swiftp/Globals.java b/src/org/swiftp/Globals.java index ab6caf7..a53d20e 100644 --- a/src/org/swiftp/Globals.java +++ b/src/org/swiftp/Globals.java @@ -27,6 +27,7 @@ public class Globals { private static Context context; private static String lastError; private static File chrootDir = new File(Defaults.chrootDir); + private static File primaryDir = chrootDir; // added by Nova, set primary directory for ftp user. private static ProxyConnector proxyConnector = null; private static String username = null; @@ -50,6 +51,31 @@ public static File getChrootDir() { public static void setChrootDir(File chrootDir) { if(chrootDir.isDirectory()) { Globals.chrootDir = chrootDir; + Globals.primaryDir = chrootDir; + } + } + + /** Get primary directory for ftp user. + */ + public static File getPrimaryDir() { + return primaryDir; + } + + /** Set primary directory for ftp user. when root directory is "/", we can change the primary directory of ftp user by setting this value. + * Notes: + * 1. It must be invoked after setChrootDir. + * 2. Globals.primaryDir must be subdirectory of Globals.chrootDir. + */ + public static void setPrimaryDir(File dir) { + if (dir.isDirectory()) { + try { + if (dir.getCanonicalPath().startsWith(Globals.getChrootDir().getPath())) { + Globals.primaryDir = dir; // the primary directory name must begin with the Globals.chrootDir. + } + return ; + } catch (Exception e) { + e.printStackTrace(); + } } } diff --git a/src/org/swiftp/SessionThread.java b/src/org/swiftp/SessionThread.java index ea62fab..3cf9e9c 100644 --- a/src/org/swiftp/SessionThread.java +++ b/src/org/swiftp/SessionThread.java @@ -45,7 +45,7 @@ public class SessionThread extends Thread { protected boolean binaryMode = false; protected Account account = new Account(); protected boolean authenticated = false; - protected File workingDir = Globals.getChrootDir(); + protected File workingDir = Globals.getPrimaryDir(); // protected ServerSocket dataServerSocket = null; protected Socket dataSocket = null; // protected FTPServerService service; @@ -247,7 +247,7 @@ protected InetAddress getLocalAddress() { static int numNulls = 0; public void run() { - myLog.l(Log.INFO, "SessionThread started"); + myLog.l(Log.INFO, "SessionThread started. root = " + Globals.getChrootDir() + ", primary dir = " + Globals.getPrimaryDir()); if(sendWelcomeBanner) { writeString("220 SwiFTP " + Util.getVersion() + " ready\r\n");