Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 15520 invoked from network); 20 Feb 2003 07:30:38 -0000 Received: from exchange.sun.com (192.18.33.10) by daedalus.apache.org with SMTP; 20 Feb 2003 07:30:38 -0000 Received: (qmail 9071 invoked by uid 97); 20 Feb 2003 07:32:13 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@nagoya.betaversion.org Received: (qmail 9064 invoked from network); 20 Feb 2003 07:32:13 -0000 Received: from daedalus.apache.org (HELO apache.org) (208.185.179.12) by nagoya.betaversion.org with SMTP; 20 Feb 2003 07:32:13 -0000 Received: (qmail 15337 invoked by uid 500); 20 Feb 2003 07:30:35 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 15325 invoked by uid 500); 20 Feb 2003 07:30:35 -0000 Received: (qmail 15322 invoked from network); 20 Feb 2003 07:30:35 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 20 Feb 2003 07:30:35 -0000 Received: (qmail 62979 invoked by uid 1439); 20 Feb 2003 07:30:36 -0000 Date: 20 Feb 2003 07:30:36 -0000 Message-ID: <20030220073036.62978.qmail@icarus.apache.org> From: adammurdoch@apache.org To: jakarta-commons-sandbox-cvs@apache.org Subject: cvs commit: jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/sftp SftpFileObject.java SftpFileProvider.java SftpFileSystem.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N adammurdoch 2003/02/19 23:30:36 Modified: vfs/src/java/org/apache/commons/vfs/impl StandardFileSystemManager.java vfs/src/java/org/apache/commons/vfs Resources.properties Added: vfs/src/java/org/apache/commons/vfs/provider/sftp SftpFileObject.java SftpFileProvider.java SftpFileSystem.java Log: Added an initial SFTP provider. Revision Changes Path 1.11 +2 -1 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/impl/StandardFileSystemManager.java Index: StandardFileSystemManager.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/impl/StandardFileSystemManager.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- StandardFileSystemManager.java 17 Feb 2003 09:22:14 -0000 1.10 +++ StandardFileSystemManager.java 20 Feb 2003 07:30:36 -0000 1.11 @@ -93,6 +93,7 @@ addProvider( "ftp", "org.apache.commons.vfs.provider.ftp.FtpFileProvider" ); addProvider( "smb", "org.apache.commons.vfs.provider.smb.SmbFileProvider" ); addProvider( "webdav", "org.apache.commons.vfs.provider.webdav.WebdavFileProvider" ); + addProvider( "sftp", "org.apache.commons.vfs.provider.sftp.SftpFileProvider" ); addProvider( "tmp", "org.apache.commons.vfs.provider.temp.TemporaryFileProvider" ); // Add a default provider 1.18 +10 -0 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/Resources.properties Index: Resources.properties =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/Resources.properties,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- Resources.properties 15 Feb 2003 02:35:35 -0000 1.17 +++ Resources.properties 20 Feb 2003 07:30:36 -0000 1.18 @@ -139,6 +139,16 @@ vfs.provider.webdav/delete-file.error=Delete file failed with message: "{0}". vfs.provider.webdav/create-client.error=Could not create client for server "{0}". +# SFTP Provider +vfs.provider.sftp/connect.error=Could not connect to SFTP server at "{0}". +vfs.provider.sftp/unknown-permissions.error=File permissions not fetched. +vfs.provider.sftp/unknown-size.error=File size not fetched. +vfs.provider.sftp/create-folder.error=Folder creation failed with unknown error. +vfs.provider.sftp/delete.error=Delete failed with unknown error. +vfs.provider.sftp/list-children.error=List folder contents failed with unknown error. +vfs.provider.sftp/put-file.error=Write file contents failed with unknown error. +vfs.provider.sftp/get-file.error=Read file contents failed with unknown error. + # Ant tasks vfs.tasks/sync.no-destination.error=No destination file or directory specified. vfs.tasks/sync.too-many-destinations.error=Cannot specify both a destination file and a destination directory. 1.1 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/sftp/SftpFileObject.java Index: SftpFileObject.java =================================================================== /* ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.commons.vfs.provider.sftp; import org.apache.commons.vfs.FileObject; import org.apache.commons.vfs.FileName; import org.apache.commons.vfs.FileType; import org.apache.commons.vfs.FileSystemException; import org.apache.commons.vfs.util.MonitorOutputStream; import org.apache.commons.vfs.provider.AbstractFileObject; import org.apache.commons.vfs.provider.TemporaryFileStore; import java.io.InputStream; import java.io.File; import java.io.FileInputStream; import java.io.OutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Vector; import java.util.ArrayList; import java.util.Iterator; import java.util.StringTokenizer; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.SftpATTRS; /** * An SFTP file. * * @author Adam Murdoch * @version $Revision: 1.1 $ $Date: 2003/02/20 07:30:36 $ */ class SftpFileObject extends AbstractFileObject implements FileObject { // TODO - This was copied from SftpATTRS source. Need to fix jsch to make the constant public static final int S_IFDIR = 0x4000; private final SftpFileSystem fileSystem; private SftpATTRS attrs; private TemporaryFileStore tempFileStore; public SftpFileObject( final FileName name, final SftpFileSystem fileSystem, final TemporaryFileStore tempFileStore ) { super( name, fileSystem ); this.fileSystem = fileSystem; this.tempFileStore = tempFileStore; } /** * Determines the type of this file, returns null if the file does not * exist. */ protected FileType doGetType() throws Exception { statSelf(); if ( attrs == null ) { // TODO - not quite true, but ChannelSftp.stat() swallows exceptions return null; } if ( ( attrs.getFlags() & SftpATTRS.SSH_FILEXFER_ATTR_PERMISSIONS ) == 0 ) { throw new FileSystemException( "vfs.provider.sftp/unknown-permissions.error" ); } if ( ( attrs.getPermissions() & S_IFDIR ) != 0 ) { return FileType.FOLDER; } else { return FileType.FILE; } } /** * Called when the type or content of this file changes. */ protected void onChange() throws Exception { statSelf(); } /** Fetches file attrs from server. */ private void statSelf() throws Exception { final ChannelSftp channel = fileSystem.getChannel(); try { attrs = channel.stat( getName().getPath() ); } finally { fileSystem.putChannel( channel ); } } /** * Creates this file as a folder. */ protected void doCreateFolder() throws Exception { final ChannelSftp channel = fileSystem.getChannel(); try { final boolean ok = channel.mkdir( getName().getPath() ); if ( !ok ) { throw new FileSystemException( "vfs.provider.sftp/create-folder.error" ); } } finally { fileSystem.putChannel( channel ); } } /** * Deletes the file. */ protected void doDelete() throws Exception { final ChannelSftp channel = fileSystem.getChannel(); try { final boolean ok; if ( getType() == FileType.FILE ) { ok = channel.rm( getName().getPath() ); } else { ok = channel.rmdir( getName().getPath() ); } if ( !ok ) { throw new FileSystemException( "vfs.provider.sftp/delete.error" ); } } finally { fileSystem.putChannel( channel ); } } /** * Lists the children of this file. */ protected String[] doListChildren() throws Exception { // List the contents of the folder final Vector vector; final ChannelSftp channel = fileSystem.getChannel(); try { vector = channel.ls( getName().getPath() ); } finally { fileSystem.putChannel( channel ); } if ( vector == null ) { throw new FileSystemException( "vfs.provider.sftp/list-children.error" ); } // Extract the child names final ArrayList children = new ArrayList(); for ( Iterator iterator = vector.iterator(); iterator.hasNext(); ) { // Each entry is in unix ls format final String stat = (String)iterator.next(); final StringTokenizer tokens = new StringTokenizer( stat ); // TODO - check there are the correct number of tokens // TODO - handle names with spaces in 'em for ( int i = 0; i < 8; tokens.nextToken(), i++ ) { } final String name = tokens.nextToken(); if ( name.equals( "." ) || name.equals( ".." ) ) { continue; } children.add( name ); } return (String[])children.toArray( new String[ children.size() ] ); } /** * Returns the size of the file content (in bytes). */ protected long doGetContentSize() throws Exception { if ( (attrs.getFlags() & SftpATTRS.SSH_FILEXFER_ATTR_SIZE) == 0 ) { throw new FileSystemException( "vfs.provider.sftp/unknown-size.error" ); } return attrs.getSize(); } /** * Creates an input stream to read the file content from. */ protected InputStream doGetInputStream() throws Exception { final ChannelSftp channel = fileSystem.getChannel(); try { // TODO - this is a dud, need to add stream based methods to Jsch // TODO - reuse the cached file // TODO - delete the file on end-of-stream final File file = tempFileStore.allocateFile( getName().getBaseName() ); final boolean ok = channel.get( getName().getPath(), '/' + file.getAbsolutePath() ); if ( !ok ) { throw new FileSystemException( "vfs.provider.sftp/get-file.error" ); } return new FileInputStream( file ); } finally { fileSystem.putChannel( channel ); } } /** * Creates an output stream to write the file content to. */ protected OutputStream doGetOutputStream() throws Exception { // TODO - this is a dud, need to add stream based methods to Jsch // TODO - reuse the same file for all content operations final File file = tempFileStore.allocateFile( getName().getBaseName() ); return new SftpOutputStream( file ); } /** * Writes the content from a file. */ private void putContent( final File file ) throws IOException { final ChannelSftp channel = fileSystem.getChannel(); try { final boolean ok = channel.put( '/' + file.getAbsolutePath(), getName().getPath() ); if ( !ok ) { throw new FileSystemException( "vfs.provider.sftp/put-file.error" ); } } finally { fileSystem.putChannel( channel ); } } /** * An output stream that pushes content to the server when this stream * is closed. */ private class SftpOutputStream extends MonitorOutputStream { private File file; public SftpOutputStream( final File file ) throws IOException { super( new FileOutputStream( file ) ); this.file = file; } /** * Called after this stream is closed. */ protected void onClose() throws IOException { // TODO - need to delete the file putContent( file ); } } } 1.1 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/sftp/SftpFileProvider.java Index: SftpFileProvider.java =================================================================== /* ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.commons.vfs.provider.sftp; import org.apache.commons.vfs.FileName; import org.apache.commons.vfs.FileSystem; import org.apache.commons.vfs.FileSystemException; import org.apache.commons.vfs.util.Os; import org.apache.commons.vfs.provider.AbstractOriginatingFileProvider; import org.apache.commons.vfs.provider.GenericFileName; import com.jcraft.jsch.JSch; /** * A provider for accessing files over SFTP. * * @author Adam Murdoch * @version $Revision: 1.1 $ $Date: 2003/02/20 07:30:36 $ */ public class SftpFileProvider extends AbstractOriginatingFileProvider { private JSch jSch = new JSch(); /** * Initialises the component. */ public void init() throws FileSystemException { // Figure out where the known_hosts file is final String knownHostsPath; if ( Os.isFamily( Os.OS_FAMILY_WINDOWS ) ) { // TODO - this may not be true final String userName = System.getProperty( "user.name" ); knownHostsPath = "C:\\cygwin\\home\\" + userName + "\\.ssh\\known_hosts"; } else { knownHostsPath = System.getProperty( "user.home") + "/.ssh/known_hosts"; } jSch.setKnownHosts( knownHostsPath ); } /** * Parses an absolute URI. */ protected FileName parseUri( final String uri ) throws FileSystemException { return GenericFileName.parseUri( uri, 22 ); } /** * Creates a {@link FileSystem}. */ protected FileSystem doCreateFileSystem( final FileName rootName ) throws FileSystemException { return new SftpFileSystem( (GenericFileName)rootName, jSch ); } } 1.1 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/sftp/SftpFileSystem.java Index: SftpFileSystem.java =================================================================== /* ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.commons.vfs.provider.sftp; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.JSchException; import java.util.Collection; import java.io.IOException; import org.apache.commons.vfs.FileName; import org.apache.commons.vfs.FileObject; import org.apache.commons.vfs.FileSystem; import org.apache.commons.vfs.FileSystemException; import org.apache.commons.vfs.Capability; import org.apache.commons.vfs.provider.AbstractFileSystem; import org.apache.commons.vfs.provider.GenericFileName; /** * Represents the files on an SFTP server. * * @author Adam Murdoch * @version $Revision: 1.1 $ $Date: 2003/02/20 07:30:36 $ */ class SftpFileSystem extends AbstractFileSystem implements FileSystem { private Session session; private final JSch jSch; private ChannelSftp idleChannel; public SftpFileSystem( final GenericFileName rootName, final JSch jSch ) { super( rootName, null ); this.jSch = jSch; } /** * Returns an SFTP channel to the server. */ protected ChannelSftp getChannel() throws IOException { // Create the session if ( session == null ) { try { final GenericFileName rootName = (GenericFileName)getRootName(); session = jSch.getSession( rootName.getUserName(), rootName.getHostName(), rootName.getPort() ); session.setPassword( rootName.getPassword() ); session.connect(); } catch ( final JSchException e ) { throw new FileSystemException( "vfs.provider.sftp/connect.error", getRootName(), e ); } } // Use the pooled channel, or create a new one final ChannelSftp channel; if ( idleChannel != null ) { channel = idleChannel; idleChannel = null; } else { channel = (ChannelSftp)session.openChannel( "sftp" ); channel.connect(); } return channel; } /** * Returns a channel to the pool. */ protected void putChannel( final ChannelSftp channel ) { if ( idleChannel == null ) { idleChannel = channel; } else { channel.disconnect(); } } /** * Adds the capabilities of this file system. */ protected void addCapabilities( final Collection caps ) { caps.add( Capability.CREATE ); caps.add( Capability.DELETE ); caps.add( Capability.GET_TYPE ); caps.add( Capability.LIST_CHILDREN ); caps.add( Capability.READ_CONTENT ); caps.add( Capability.URI ); caps.add( Capability.WRITE_CONTENT ); } /** * Creates a file object. This method is called only if the requested * file is not cached. */ protected FileObject createFile( final FileName name ) throws FileSystemException { return new SftpFileObject( name, this, getContext().getTemporaryFileStore() ); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org