Java tutorial
/* * SSHTools - Java SSH2 API * * Copyright (C) 2002-2003 Lee David Painter and Contributors. * * Contributions made by: * * Brett Smith * Richard Pernavas * Erwin Bolwidt * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package jag.sftp; import java.io.EOFException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sshtools.daemon.configuration.PlatformConfiguration; import com.sshtools.daemon.platform.InvalidHandleException; import com.sshtools.daemon.platform.NativeAuthenticationProvider; import com.sshtools.daemon.platform.NativeFileSystemProvider; import com.sshtools.daemon.platform.PermissionDeniedException; import com.sshtools.daemon.platform.UnsupportedFileOperationException; import com.sshtools.daemon.vfs.VFSMount; import com.sshtools.daemon.vfs.VFSPermission; import com.sshtools.daemon.vfs.VFSPermissionHandler; import com.sshtools.j2ssh.SshThread; import com.sshtools.j2ssh.configuration.ConfigurationException; import com.sshtools.j2ssh.configuration.ConfigurationLoader; import com.sshtools.j2ssh.io.UnsignedInteger32; import com.sshtools.j2ssh.io.UnsignedInteger64; import com.sshtools.j2ssh.sftp.FileAttributes; import com.sshtools.j2ssh.sftp.SftpFile; /** * * * @author $author$ * @version $Revision: 1.32 $ */ public class VirtualFileSystem extends NativeFileSystemProvider { private static String USER_HOME = "/home/"; private static Map vfsmounts; private static VFSMount vfsroot; private static Log log = LogFactory.getLog(VirtualFileSystem.class); private static VFSPermissionHandler permissionHandler = null; static { try { vfsmounts = ((PlatformConfiguration) ConfigurationLoader.getConfiguration(PlatformConfiguration.class)) .getVFSMounts(); vfsroot = ((PlatformConfiguration) ConfigurationLoader.getConfiguration(PlatformConfiguration.class)) .getVFSRoot(); } catch (ConfigurationException ex) { log.error("Failed to initialize the Virtual File System", ex); } } private Map openFiles = new HashMap(); /** * Creates a new VirtualFileSystem object. * * @throws IOException */ public VirtualFileSystem() throws IOException { if (!ConfigurationLoader.isConfigurationAvailable(PlatformConfiguration.class)) { throw new IOException("No valid platform configuration available"); } } public static void setPermissionHandler(VFSPermissionHandler permissionHandler) { VirtualFileSystem.permissionHandler = permissionHandler; } private static String getVFSHomeDirectory(String username) throws FileNotFoundException { if (permissionHandler != null) { return permissionHandler.getVFSHomeDirectory(username); } else { return USER_HOME + username; } } private static String getNFSHomeDirectory() throws FileNotFoundException { try { if (Thread.currentThread() instanceof SshThread && SshThread.hasUserContext()) { NativeAuthenticationProvider nap = NativeAuthenticationProvider.getInstance(); return nap.getHomeDirectory(SshThread.getCurrentThreadUser()); } else { throw new FileNotFoundException("There is no user logged in"); } } catch (IOException e) { throw new FileNotFoundException(e.getMessage()); } } /** * * * @param str * @param with * * @return */ public static boolean startsWithIgnoreCase(String str, String with) { return str.substring(0, (with.length() > str.length()) ? str.length() : with.length()) .equalsIgnoreCase(with); } /** * * * @param nfspath * * @return * * @throws FileNotFoundException */ public static String translateNFSPath(String nfspath) throws FileNotFoundException { nfspath = nfspath.replace('\\', '/'); // ./ means home if (nfspath.startsWith("./")) { nfspath = nfspath.substring(2); } //if (startsWithIgnoreCase(nfspath, nfshome)) { try { String nfshome = getNFSHomeDirectory().replace('\\', '/'); nfshome = translateCanonicalPath(nfshome, nfshome); String vfshome = getVFSHomeDirectory(SshThread.getCurrentThreadUser()); // First check for the userhome log.debug("NFSPath=" + nfspath); log.debug("NFSHome=" + nfshome); nfspath = translateCanonicalPath(nfspath, nfshome); int idx = nfspath.indexOf(nfshome); return vfshome + nfspath.substring(nfshome.length()); // StringBuffer buf = new StringBuffer(nfspath); // buf = buf.replace(idx, idx + nfshome.length(), vfshome); // return buf.toString(); /*nfspath.replaceFirst(nfshome, vfshome);*/ //} } catch (FileNotFoundException ex) { /* Ignore as we will try other mounts */ } // Now lets translate from the available mounts Iterator it = vfsmounts.entrySet().iterator(); Map.Entry entry; String mount; String path; VFSMount m; while (it.hasNext()) { entry = (Map.Entry) it.next(); mount = (String) entry.getKey(); m = (VFSMount) entry.getValue(); path = m.getPath(); log.debug(m.getMount() + "=" + m.getPath()); // if (startsWithIgnoreCase(nfspath, path)) { try { nfspath = translateCanonicalPath(nfspath, path); int idx = nfspath.indexOf(path); StringBuffer buf = new StringBuffer(nfspath); buf = buf.replace(idx, idx + path.length(), mount); return buf.toString(); } catch (FileNotFoundException ex) { /* Ingore as we will try other mounts */ } // } } // if (startsWithIgnoreCase(nfspath, vfsroot.getPath())) { log.debug("VFSRoot=" + vfsroot.getPath()); nfspath = translateCanonicalPath(nfspath, vfsroot.getPath()); path = nfspath.substring(vfsroot.getPath().length()); //replaceFirst(vfsroot.getPath(), ""); return (path.startsWith("/") ? path : ("/" + path)); // } else { // throw new FileNotFoundException(nfspath + " could not be found"); // } } private static VFSMount getMount(String vfspath) throws FileNotFoundException, IOException { String vfshome = getVFSHomeDirectory(SshThread.getCurrentThreadUser()); VFSMount m; if (vfspath.startsWith("/")) { if (vfspath.startsWith(vfshome)) { m = new VFSMount(vfshome, getNFSHomeDirectory()); m.setPermissions(new VFSPermission(SshThread.getCurrentThreadUser(), "rwx")); return m; } else { Iterator it = vfsmounts.entrySet().iterator(); Map.Entry entry; String mount; while (it.hasNext()) { entry = (Map.Entry) it.next(); mount = (String) entry.getKey(); if (vfspath.startsWith(mount)) { return (VFSMount) entry.getValue(); } } if (vfsroot != null) { return vfsroot; } else { throw new FileNotFoundException("The path was not found"); } } } else { m = new VFSMount(vfshome, getNFSHomeDirectory()); m.setPermissions(new VFSPermission(vfshome.substring(vfshome.lastIndexOf("/")), "rwx")); return m; } } /** * * * @param vfspath * * @return * * @throws FileNotFoundException */ public static String translateVFSPath(String vfspath) throws FileNotFoundException { return translateVFSPath(vfspath, null); } public static String translateVFSPath(String vfspath, String vfscwd) throws FileNotFoundException { // Translate any backslashes for sanity vfspath = vfspath.replace('\\', '/').trim(); try { if (!vfspath.startsWith("/")) { // Work out the path using the current directory String path = (((vfscwd == null) || vfscwd.trim().equals("")) ? getVFSHomeDirectory(SshThread.getCurrentThreadUser()) : vfscwd); vfspath = path + (path.endsWith("/") ? "" : "/") + vfspath; } String nfshome = getNFSHomeDirectory().replace('\\', '/'); String vfshome = getVFSHomeDirectory(SshThread.getCurrentThreadUser()); if (vfspath.startsWith(vfshome)) { // Return the canonicalized system dependent path if (vfspath.length() > vfshome.length()) { if (!nfshome.endsWith("/")) { nfshome = nfshome + "/"; } return translateCanonicalPath(nfshome + vfspath.substring(vfshome.length()), nfshome); } else { return translateCanonicalPath(nfshome, nfshome); } } } catch (FileNotFoundException ex) { // Ignore since we dont always need to be running as a user } // The path does not refer to the absolute USER_HOME // so we will look up using the platform.xml VFS mounts Iterator it = vfsmounts.entrySet().iterator(); Map.Entry entry; String mount; String path; VFSMount m; while (it.hasNext()) { entry = (Map.Entry) it.next(); mount = (String) entry.getKey(); m = (VFSMount) entry.getValue(); path = m.getPath(); if (vfspath.startsWith(mount)) { // Lets translate the path, making sure we do not move outside // vfs with .. String str = path + vfspath.substring(mount.length()); // vfspath.replaceFirst(mount, // path) return translateCanonicalPath(str, path); } } // If we reached here then the VFS path did not refer to an optional mount // or the users home directory, so lets attempt to use the VFS root is there // is one defined if (vfsroot != null) { path = vfsroot.getPath() + (vfsroot.getPath().endsWith("/") ? vfspath.substring(1) : vfspath); return translateCanonicalPath(path, vfsroot.getPath()); } else { throw new FileNotFoundException("The file could not be found"); } } /*else { try { String nfshome = (nfscwd == null || nfscwd.trim().equals("") ? getNFSHomeDirectory() : nfscwd); String path = nfshome + (nfshome.endsWith("/") ? "" : "/") + vfspath; return translateCanonicalPath(path, nfshome); } catch (FileNotFoundException ex1) { throw new FileNotFoundException( "Only fully qualified VFS paths can be translated outside of a user context"); } /* String path = nfshome + (nfshome.endsWith("/") ? "" : "/") + vfspath; return translateCanonicalPath(path, nfshome);*/ //} /** * * * @param path * @param securemount * * @return * * @throws FileNotFoundException */ public static String translateCanonicalPath(String path, String securemount) throws FileNotFoundException { try { log.debug("Translating for canonical path " + path + " against secure mount " + securemount); File f = new File(path); String canonical = f.getCanonicalPath().replace('\\', '/'); File f2 = new File(securemount); String canonical2 = f2.getCanonicalPath().replace('\\', '/'); // Verify that the canonical path does not exit out of the mount if (canonical.startsWith(canonical2)) { return canonical; } else { throw new FileNotFoundException(path + " could not be found"); } } catch (IOException ex) { throw new FileNotFoundException(path + " could not be found"); } } /** * * * @param path * * @return * * @throws PermissionDeniedException * @throws FileNotFoundException * @throws IOException */ public boolean makeDirectory(String path) throws PermissionDeniedException, FileNotFoundException, IOException { // String realPath = path; path = VirtualFileSystem.translateVFSPath(path); File f = new File(path); verifyPermissions(SshThread.getCurrentThreadUser(), path, "rw"); log.debug("Creating directory " + f.getAbsolutePath()); return f.mkdir(); } /** * * * @param path * * @return * * @throws FileNotFoundException * @throws IOException */ public VFSPermission getVFSPermission(String path) throws FileNotFoundException, IOException { VFSMount mount = getMount(translateNFSPath(path)); if (mount.getPermissions().containsKey(SshThread.getCurrentThreadUser())) { return (VFSPermission) mount.getPermissions().get(SshThread.getCurrentThreadUser()); } else { return (VFSPermission) mount.getPermissions().get("default"); } } /** * * * @param handle * * @return * * @throws IOException * @throws InvalidHandleException */ public FileAttributes getFileAttributes(byte[] handle) throws IOException, InvalidHandleException { String shandle = new String(handle); if (openFiles.containsKey(shandle)) { Object obj = openFiles.get(shandle); File f; if (obj instanceof OpenFile) { f = ((OpenFile) obj).getFile(); } else if (obj instanceof OpenDirectory) { f = ((OpenDirectory) obj).getFile(); } else { throw new IOException("Unexpected open file handle"); } VFSPermission permissions = getVFSPermission(f.getAbsolutePath()); if (permissions == null) { throw new IOException("No default permissions set"); } FileAttributes attrs = new FileAttributes(); attrs.setSize(new UnsignedInteger64(String.valueOf(f.length()))); attrs.setTimes(new UnsignedInteger32(f.lastModified() / 1000), new UnsignedInteger32(f.lastModified() / 1000)); boolean canExec = true; try { if (System.getSecurityManager() != null) { System.getSecurityManager().checkExec(f.getCanonicalPath()); } } catch (SecurityException ex1) { canExec = false; } attrs.setPermissions((((f.canRead() && permissions.canRead()) ? "r" : "-") + ((f.canWrite() && permissions.canWrite()) ? "w" : "-") + ((canExec && permissions.canExecute()) ? "x" : "-"))); attrs.setPermissions(new UnsignedInteger32(attrs.getPermissions().longValue() | (f.isDirectory() ? FileAttributes.S_IFDIR : FileAttributes.S_IFREG))); return attrs; } else { throw new InvalidHandleException("The handle is invalid"); } } /** * * * @param path * * @return * * @throws IOException * @throws FileNotFoundException */ public FileAttributes getFileAttributes(String path) throws IOException, FileNotFoundException { log.debug("Getting file attributes for " + path); path = translateVFSPath(path); // Look up the VFS mount attributes File f = new File(path); path = f.getCanonicalPath(); if (!f.exists()) { throw new FileNotFoundException(path + " doesn't exist"); } VFSPermission permissions = getVFSPermission(path); if (permissions == null) { throw new IOException("No default permissions set"); } FileAttributes attrs = new FileAttributes(); attrs.setSize(new UnsignedInteger64(String.valueOf(f.length()))); attrs.setTimes(new UnsignedInteger32(f.lastModified() / 1000), new UnsignedInteger32(f.lastModified() / 1000)); boolean canExec = true; try { if (System.getSecurityManager() != null) { System.getSecurityManager().checkExec(f.getCanonicalPath()); } } catch (SecurityException ex1) { canExec = false; } attrs.setPermissions((((f.canRead() && permissions.canRead()) ? "r" : "-") + ((f.canWrite() && permissions.canWrite()) ? "w" : "-") + ((canExec && permissions.canExecute()) ? "x" : "-"))); attrs.setPermissions(new UnsignedInteger32(attrs.getPermissions().longValue() | (f.isDirectory() ? FileAttributes.S_IFDIR : FileAttributes.S_IFREG))); return attrs; } /** * * * @param path * * @return * * @throws PermissionDeniedException * @throws FileNotFoundException * @throws IOException */ public byte[] openDirectory(String path) throws PermissionDeniedException, FileNotFoundException, IOException { String realPath = path; path = VirtualFileSystem.translateVFSPath(path); File f = new File(path); verifyPermissions(SshThread.getCurrentThreadUser(), path, "r"); if (f.exists()) { if (f.isDirectory()) { openFiles.put(f.toString(), new OpenDirectory(realPath, path, f)); return f.toString().getBytes("US-ASCII"); } else { throw new IOException(translateNFSPath(path) + " is not a directory"); } } else { throw new FileNotFoundException(translateNFSPath(path) + " does not exist"); } } /** * * * @param handle * * @return * * @throws InvalidHandleException * @throws EOFException * @throws IOException */ public SftpFile[] readDirectory(byte[] handle) throws InvalidHandleException, EOFException, IOException { String shandle = new String(handle); if (openFiles.containsKey(shandle)) { Object obj = openFiles.get(shandle); if (obj instanceof OpenDirectory) { OpenDirectory dir = (OpenDirectory) obj; int pos = dir.getPosition(); File[] children = dir.getChildren(); if (children == null) { throw new IOException("Permission denined."); } int count = ((children.length - pos) < 100) ? (children.length - pos) : 100; if (count > 0) { SftpFile[] files = new SftpFile[count]; for (int i = 0; i < files.length; i++) { File f = children[pos + i]; String absolutePath = dir.realPath + "/" + f.getName(); SftpFile sftpfile = new SftpFile(f.getName(), getFileAttributes(absolutePath)); files[i] = sftpfile; } dir.readpos = pos + files.length; return files; } else { throw new EOFException("There are no more files"); } } else { throw new InvalidHandleException("Handle is not an open directory"); } } else { throw new InvalidHandleException("The handle is invalid"); } } /** * * * @param path * @param flags * @param attrs * * @return * * @throws PermissionDeniedException * @throws FileNotFoundException * @throws IOException */ public byte[] openFile(String path, UnsignedInteger32 flags, FileAttributes attrs) throws PermissionDeniedException, FileNotFoundException, IOException { System.out.println(path); path = VirtualFileSystem.translateVFSPath(path); System.out.println(path); File f = new File(path); verifyPermissions(SshThread.getCurrentThreadUser(), path, "r"); // Check if the file does not exist and process according to flags if (!f.exists()) { if ((flags.intValue() & NativeFileSystemProvider.OPEN_CREATE) == NativeFileSystemProvider.OPEN_CREATE) { // The file does not exist and the create flag is present so lets create it if (!f.createNewFile()) { throw new IOException(translateNFSPath(path) + " could not be created"); } } else { // The file does not exist and no create flag present throw new FileNotFoundException(translateNFSPath(path) + " does not exist"); } } else { if (((flags.intValue() & NativeFileSystemProvider.OPEN_CREATE) == NativeFileSystemProvider.OPEN_CREATE) && ((flags.intValue() & NativeFileSystemProvider.OPEN_EXCLUSIVE) == NativeFileSystemProvider.OPEN_EXCLUSIVE)) { // The file exists but the EXCL flag is set which requires that the // file should not exist prior to creation, so throw a status exception throw new IOException(translateNFSPath(path) + " already exists"); } } // The file now exists so open the file according to the flags yb building the relevant // flags for the RandomAccessFile class String mode = "r" + (((flags.intValue() & NativeFileSystemProvider.OPEN_WRITE) == NativeFileSystemProvider.OPEN_WRITE) ? "ws" : ""); RandomAccessFile raf = new RandomAccessFile(f, mode); // Determine whether we need to truncate the file if (((flags.intValue() & NativeFileSystemProvider.OPEN_CREATE) == NativeFileSystemProvider.OPEN_CREATE) && ((flags.intValue() & NativeFileSystemProvider.OPEN_TRUNCATE) == NativeFileSystemProvider.OPEN_TRUNCATE)) { // Set the length to zero raf.setLength(0); } // Record the open file openFiles.put(raf.toString(), new OpenFile(f, raf, flags)); // Return the handle return raf.toString().getBytes("US-ASCII"); } /** * * * @param handle * @param offset * @param len * * @return * * @throws InvalidHandleException * @throws EOFException * @throws IOException */ public byte[] readFile(byte[] handle, UnsignedInteger64 offset, UnsignedInteger32 len) throws InvalidHandleException, EOFException, IOException { String shandle = new String(handle); if (openFiles.containsKey(shandle)) { Object obj = openFiles.get(shandle); if (obj instanceof OpenFile) { OpenFile file = (OpenFile) obj; if ((file.getFlags().intValue() & NativeFileSystemProvider.OPEN_READ) == NativeFileSystemProvider.OPEN_READ) { byte[] buf = new byte[len.intValue()]; if (file.getRandomAccessFile().getFilePointer() != offset.longValue()) { file.getRandomAccessFile().seek(offset.longValue()); } int read = file.getRandomAccessFile().read(buf); if (read >= 0) { if (read == buf.length) { return buf; } else { byte[] tmp = new byte[read]; System.arraycopy(buf, 0, tmp, 0, read); return tmp; } } else { throw new EOFException("The file is EOF"); } } else { throw new InvalidHandleException("The file handle was not opened for reading"); } } else { throw new InvalidHandleException("Handle is not an open file"); } } else { throw new InvalidHandleException("The handle is invalid"); } } /** * * * @param handle * @param offset * @param data * @param off * @param len * * @throws InvalidHandleException * @throws IOException */ public void writeFile(byte[] handle, UnsignedInteger64 offset, byte[] data, int off, int len) throws InvalidHandleException, IOException { String shandle = new String(handle); if (openFiles.containsKey(shandle)) { Object obj = openFiles.get(shandle); if (obj instanceof OpenFile) { OpenFile file = (OpenFile) obj; if ((file.getFlags().intValue() & NativeFileSystemProvider.OPEN_WRITE) == NativeFileSystemProvider.OPEN_WRITE) { if ((file.getFlags().intValue() & NativeFileSystemProvider.OPEN_APPEND) == NativeFileSystemProvider.OPEN_APPEND) { // Force the data to be written to the end of the file by seeking to the end file.getRandomAccessFile().seek(file.getRandomAccessFile().length()); } else if (file.getRandomAccessFile().getFilePointer() != offset.longValue()) { // Move the file pointer if its not in the write place file.getRandomAccessFile().seek(offset.longValue()); } file.getRandomAccessFile().write(data, off, len); } else { throw new InvalidHandleException("The file was not opened for writing"); } } else { throw new InvalidHandleException("Handle is not an open file"); } } else { throw new InvalidHandleException("The handle is invalid"); } } /** * * * @param handle * * @throws InvalidHandleException * @throws IOException */ public void closeFile(byte[] handle) throws InvalidHandleException, IOException { String shandle = new String(handle); if (openFiles.containsKey(shandle)) { Object obj = openFiles.get(shandle); if (obj instanceof OpenDirectory) { openFiles.remove(shandle); } else if (obj instanceof OpenFile) { ((OpenFile) obj).getRandomAccessFile().close(); openFiles.remove(shandle); } else { throw new InvalidHandleException("Internal server error"); } } else { throw new InvalidHandleException("The handle is invalid"); } } /** * * * @param path * * @throws PermissionDeniedException * @throws IOException * @throws FileNotFoundException */ public void removeFile(String path) throws PermissionDeniedException, IOException, FileNotFoundException { path = VirtualFileSystem.translateVFSPath(path); File f = new File(path); if (f.exists()) { try { if (f.isFile()) { if (!f.delete()) { throw new IOException("Failed to delete " + translateNFSPath(path)); } } else { throw new IOException( translateNFSPath(path) + " is a directory, use remove directory command to remove"); } } catch (SecurityException se) { throw new PermissionDeniedException("Permission denied"); } } else { throw new FileNotFoundException(translateNFSPath(path) + " does not exist"); } } /** * * * @param oldpath * @param newpath * * @throws PermissionDeniedException * @throws FileNotFoundException * @throws IOException */ public void renameFile(String oldpath, String newpath) throws PermissionDeniedException, FileNotFoundException, IOException { oldpath = VirtualFileSystem.translateVFSPath(oldpath); newpath = VirtualFileSystem.translateVFSPath(newpath); File f = new File(oldpath); verifyPermissions(SshThread.getCurrentThreadUser(), oldpath, "rw"); verifyPermissions(SshThread.getCurrentThreadUser(), newpath, "rw"); if (f.exists()) { File f2 = new File(newpath); if (!f2.exists()) { if (!f.renameTo(f2)) { throw new IOException("Failed to rename file " + translateNFSPath(oldpath)); } } else { throw new IOException(translateNFSPath(newpath) + " already exists"); } } else { throw new FileNotFoundException(translateNFSPath(oldpath) + " does not exist"); } } /** * * * @param path * * @throws PermissionDeniedException * @throws FileNotFoundException * @throws IOException */ public void removeDirectory(String path) throws PermissionDeniedException, FileNotFoundException, IOException { path = VirtualFileSystem.translateVFSPath(path); File f = new File(path); verifyPermissions(SshThread.getCurrentThreadUser(), path, "rw"); if (f.isDirectory()) { if (f.exists()) { if (f.listFiles().length == 0) { if (!f.delete()) { throw new IOException("Failed to remove directory " + translateNFSPath(path)); } } else { throw new IOException(translateNFSPath(path) + " is not an empty directory"); } } else { throw new FileNotFoundException(translateNFSPath(path) + " does not exist"); } } else { throw new IOException(translateNFSPath(path) + " is not a directory"); } } /** * * * @param path * @param attrs * * @throws PermissionDeniedException * @throws IOException * @throws FileNotFoundException */ public void setFileAttributes(String path, FileAttributes attrs) throws PermissionDeniedException, IOException, FileNotFoundException { // Since we cannot really set permissions, this should be ignored as we // do not want applications to fail. /*String realPath = VirtualFileSystem.translateVFSPath(path); throw new PermissionDeniedException( "Cannot set file attributes using virtual file system for file " + realPath);*/ } /** * * * @param handle * @param attrs * * @throws PermissionDeniedException * @throws IOException * @throws InvalidHandleException */ public void setFileAttributes(byte[] handle, FileAttributes attrs) throws PermissionDeniedException, IOException, InvalidHandleException { } /** * * * @param path * * @return * * @throws UnsupportedFileOperationException * @throws FileNotFoundException * @throws IOException * @throws PermissionDeniedException */ public SftpFile readSymbolicLink(String path) throws UnsupportedFileOperationException, FileNotFoundException, IOException, PermissionDeniedException { throw new UnsupportedFileOperationException("Symbolic links are not supported by the Virtual File System"); } /** * * * @param link * @param target * * @throws UnsupportedFileOperationException * @throws FileNotFoundException * @throws IOException * @throws PermissionDeniedException */ public void createSymbolicLink(String link, String target) throws UnsupportedFileOperationException, FileNotFoundException, IOException, PermissionDeniedException { throw new UnsupportedFileOperationException("Symbolic links are not supported by the Virtual File System"); } /** * * * @param path * * @return * * @throws IOException */ public boolean fileExists(String path) throws IOException { File f = new File(VirtualFileSystem.translateVFSPath(path)); return f.exists(); } public String getDefaultPath(String username) throws FileNotFoundException { return getVFSHomeDirectory(username); } /** * * * @param path * * @return * * @throws IOException * @throws FileNotFoundException */ public String getCanonicalPath(String path) throws IOException, FileNotFoundException { File f = new File(VirtualFileSystem.translateVFSPath(path)); return f.getCanonicalPath(); } /** * * * @param path * * @return * * @throws FileNotFoundException */ public String getRealPath(String path) throws FileNotFoundException { log.debug("Get real path for '" + path + "'"); path = VirtualFileSystem.translateVFSPath(path); log.debug("Translated VFS is '" + path + "'"); path = VirtualFileSystem.translateNFSPath(path); log.debug("Translated NFS is '" + path + "'"); return path; } /** * * * @param username * @param path * @param permissions * * @throws PermissionDeniedException * @throws FileNotFoundException * @throws IOException */ public void verifyPermissions(String username, String path, String permissions) throws PermissionDeniedException, FileNotFoundException, IOException { String vfspath = translateNFSPath(path); if (permissionHandler == null) { VFSMount mount = getMount(vfspath); VFSPermission perm; if (mount.getPermissions().containsKey(SshThread.getCurrentThreadUser())) { perm = (VFSPermission) mount.getPermissions().get(SshThread.getCurrentThreadUser()); } else if (mount.getPermissions().containsKey("default")) { perm = (VFSPermission) mount.getPermissions().get("default"); } else { throw new PermissionDeniedException("No permissions set for mount"); } if (!perm.verifyPermissions(permissions)) { throw new PermissionDeniedException("Permission denied for " + translateNFSPath(path)); } } else { permissionHandler.verifyPermissions(username, path, permissions); } } class OpenFile { File f; RandomAccessFile raf; UnsignedInteger32 flags; public OpenFile(File f, RandomAccessFile raf, UnsignedInteger32 flags) { this.f = f; this.raf = raf; this.flags = flags; } public File getFile() { return f; } public RandomAccessFile getRandomAccessFile() { return raf; } public UnsignedInteger32 getFlags() { return flags; } } class OpenDirectory { File f; File[] children; int readpos = 0; String path; String realPath; public OpenDirectory(String realPath, String path, File f) { this.path = path; this.realPath = realPath; this.f = f; this.children = f.listFiles(); } public File getFile() { return f; } public File[] getChildren() { return children; } public int getPosition() { return readpos; } public void setPosition(int readpos) { this.readpos = readpos; } } }