package org.primftpd.filesystem; import org.apache.ftpserver.ftplet.FtpException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; public abstract class AndroidFileSystemView<T extends AndroidFile<X>, X> { private final Logger logger = LoggerFactory.getLogger(getClass()); private final File homeDir; private T workingDir; public AndroidFileSystemView(File homeDir) { this.homeDir = homeDir; workingDir = createHomeDirObj(); } protected abstract T createFile(File file); private T createHomeDirObj() { return createFile(homeDir); } public T getHomeDirectory() { logger.trace("getHomeDirectory()"); return createHomeDirObj(); } public T getWorkingDirectory() { logger.trace("getWorkingDirectory()"); return workingDir; } public boolean changeWorkingDirectory(String dir) { logger.trace("changeWorkingDirectory({})", dir); File dirObj = new File(dir); String currentAbsPath = workingDir.getAbsolutePath(); String path = dir; if (!dirObj.isAbsolute()) { path = currentAbsPath + File.separator + dir; } logger.trace("using path for cwd operation: {}", path); dirObj = new File(path); // check if new path is a dir if (!dirObj.isDirectory()) { logger.trace("not changing WD as new one is not a directory"); return false; } // some clients issue CWD commands // and are confused about home dir // do some checks to avoid issues // happened for keepass String paraAbs = dirObj.getAbsolutePath(); if (currentAbsPath.length() * 2 == paraAbs.length()) { String pathDoubled = currentAbsPath + currentAbsPath; if (pathDoubled.equals(paraAbs)) { // this is the confusion case // just tell client everything is alright logger.trace( "client is confused about WD ({}), just tell him it is alright", currentAbsPath); return true; } } logger.trace("current WD '{}', new path '{}'", currentAbsPath, path); workingDir = createFile(new File(path)); return true; } public T getFile(String file) { logger.trace("getFile({})", file); File fileObj = new File(file); if (fileObj.isAbsolute()) { logger.trace("getFile(), returning abs: '{}'", file); return createFile(fileObj); } // handle relative paths file = workingDir.getAbsolutePath() + File.separator + file; logger.trace("getFile(), returning rel: '{}'", file); return createFile(new File(file)); } public boolean isRandomAccessible() throws FtpException { logger.trace("isRandomAccessible()"); return true; } public void dispose() { logger.trace("dispose()"); } }