/* * EncFS Java Library * Copyright (C) 2011 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. */ package org.mrpdaemon.sec.encfs; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.List; /** * Class implementing an EncFSFileProvider for accessing the local filesystem * <p/> * Note that all path parameters are relative to the rootPath provided to the * constructor. Thus, if one instantiates an EncFSFileProvider("/home/jdoe"), * the proper way to refer to /home/jdoe/dir/file.ext is by "dir/file.ext". */ public class EncFSLocalFileProvider implements EncFSFileProvider { private final String separator; private final File rootPath; public EncFSLocalFileProvider(File rootPath) { this.rootPath = rootPath; this.separator = File.separator; } /** * Returns whether the given source path represents a directory in the * underlying filesystem * * @param srcPath * Path of the source file or directory */ public boolean isDirectory(String srcPath) { File file = new File(rootPath.getAbsoluteFile(), srcPath); return file.isDirectory(); } /** * Get a File object representing the given path * * @param path * Path of the file or directory */ File getFile(String path) { return new File(rootPath.getAbsoluteFile(), path); } /** * Returns the path separator for the underlying filesystem * * @return String representing the path separator */ public final String getSeparator() { return separator; } /** * Returns the root path for the underlying filesystem * * @return String representing the root path */ public final String getFilesystemRootPath() { return "/"; } /** * Returns whether the file or directory exists * * @param srcPath * Path of the file or directory */ public boolean exists(String srcPath) { return new File(rootPath.getAbsoluteFile(), srcPath).exists(); } /** * Return EncFSFileInfo for the given file or directory * * @param srcPath * Path of the file or directory */ public EncFSFileInfo getFileInfo(String srcPath) { File sourceFile = new File(rootPath.getAbsoluteFile(), srcPath); return convertToFileInfo(sourceFile); } /** * Returns the list of files under the given directory path * * @param dirPath * Path of the directory to list files from */ public List<EncFSFileInfo> listFiles(String dirPath) throws IOException { File srcDir = new File(rootPath.getAbsoluteFile(), dirPath); if (!srcDir.isDirectory()) { throw new IOException("Path: "+dirPath+" not a directory!"); } File[] files = srcDir.listFiles(); List<EncFSFileInfo> results = new ArrayList<EncFSFileInfo>(files.length); for (File file : files) { results.add(convertToFileInfo(file)); } return results; } /** * Move a file/directory to a different location * * @param srcPath * Path to the source file or directory * @param dstPath * Path for the destination file or directory */ public boolean move(String srcPath, String dstPath) throws IOException { File sourceFile = new File(rootPath.getAbsoluteFile(), srcPath); if (!sourceFile.exists()) { throw new FileNotFoundException("Path '"+srcPath +"' doesn't exist!"); } File destFile = new File(rootPath.getAbsoluteFile(), dstPath); return sourceFile.renameTo(destFile); } /* * Recursive delete function */ private void recursiveDelete(File file) throws IOException { if (file.isDirectory()) { for (File childFile : file.listFiles()) { recursiveDelete(childFile); } } if (!file.delete()) { throw new IOException("Failed to delete file "+file); } } /** * Delete the file or directory with the given path * * @param srcPath * Path of the source file or directory * @return true if deletion is successful, false otherwise */ public boolean delete(String srcPath) { File toEncFile = new File(rootPath.getAbsoluteFile(), srcPath); try { recursiveDelete(toEncFile); } catch (IOException e) { return false; } return true; } /** * Create a directory with the given path * <p/> * Note that all path elements except the last one must exist for this * method. If that is not true mkdirs should be used instead * * @param dirPath * Path to create a directory under */ public boolean mkdir(String dirPath) throws IOException { File file = new File(rootPath.getAbsoluteFile(), dirPath); File parentFile = file.getParentFile(); if (!parentFile.exists()) { throw new FileNotFoundException("Path '" +parentFile.getAbsolutePath()+"' doesn't exist!"); } return file.mkdir(); } /** * Create a directory with the given path * <p/> * Intermediate directories are also created by this method * * @param dirPath * Path to create a directory under */ public boolean mkdirs(String dirPath) { File toEncFile = new File(rootPath.getAbsoluteFile(), dirPath); return toEncFile.mkdirs(); } /** * Create a file with the given path * * @param dstFilePath * Path for the file to create * @return EncFSFileInfo for the created file */ public EncFSFileInfo createFile(String dstFilePath) throws IOException { if (exists(dstFilePath)) { throw new IOException("File already exists"); } File targetFile = getFile(dstFilePath); if (!targetFile.createNewFile()) { throw new IOException("failed to create new file"); } return convertToFileInfo(targetFile); } /** * Copy the file with the given path to another destination * * @param srcFilePath * Path to the file to copy * @param dstFilePath * Path to the destination file */ public boolean copy(String srcFilePath, String dstFilePath) throws IOException { File sourceFile = new File(rootPath.getAbsoluteFile(), srcFilePath); if (!sourceFile.exists()) { throw new FileNotFoundException("Source file '"+srcFilePath +"' doesn't exist!"); } File destFile = new File(rootPath.getAbsoluteFile(), dstFilePath); if (!destFile.exists()) { destFile.createNewFile(); } FileChannel source = null; FileChannel destination = null; try { source = new FileInputStream(sourceFile).getChannel(); destination = new FileOutputStream(destFile).getChannel(); destination.transferFrom(source, 0, source.size()); } finally { if (source!=null) { source.close(); } if (destination!=null) { destination.close(); } } return true; } /** * Open an InputStream to the given file * * @param srcFilePath * Path to the source file * @return InputStream to read from the file */ public InputStream openInputStream(String srcFilePath) throws FileNotFoundException { File srcF = new File(rootPath.getAbsoluteFile(), srcFilePath); return new FileInputStream(srcF); } /** * Open an OutputStream to the given file * * @param dstFilePath * Path to the destination file */ public OutputStream openOutputStream(String dstFilePath) throws IOException { return openOutputStream(dstFilePath, 0); } /** * Open an OutputStream to the given file * * @param dstFilePath * Path to the destination file * @param outputLength * Length in bytes of the stream that will be written to this * stream. It is ignored by this class. */ public OutputStream openOutputStream(String dstFilePath, long outputLength) throws IOException { File srcF = new File(rootPath.getAbsoluteFile(), dstFilePath); if (!srcF.exists()) { try { srcF.createNewFile(); } catch (Exception e) { throw new IOException(e); } } return new FileOutputStream(srcF); } // Convert the given File to an EncFSFileInfo private EncFSFileInfo convertToFileInfo(File file) { String relativePath; if (file.equals(rootPath.getAbsoluteFile())) { // we're dealing with the root dir relativePath = separator; } else if (file.getParentFile().equals(rootPath.getAbsoluteFile())) { // File is child of the root path relativePath = separator; } else { relativePath = file.getParentFile().getAbsolutePath() .substring(rootPath.getAbsoluteFile().toString().length()); } String name = file.getName(); return new EncFSFileInfo(name, relativePath, file.isDirectory(), file.lastModified(), file.length(), file.canRead(), file.canWrite(), file.canExecute()); } }