git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274792 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -105,7 +105,7 @@ public class ExtensionAdapter extends DataType { | |||
| * The URL from which the most recent version of this optional package | |||
| * can be obtained if it is not already installed. | |||
| */ | |||
| private String implementationVendorURL; | |||
| private String implementationURL; | |||
| /** | |||
| * Set the name of extension. | |||
| @@ -174,7 +174,7 @@ public class ExtensionAdapter extends DataType { | |||
| */ | |||
| public void setImplementationUrl(final String implementationURL) { | |||
| verifyNotAReference(); | |||
| this.implementationVendorURL = implementationURL; | |||
| this.implementationURL = implementationURL; | |||
| } | |||
| /** | |||
| @@ -195,7 +195,7 @@ public class ExtensionAdapter extends DataType { | |||
| || null != implementationVersion | |||
| || null != implementationVendorID | |||
| || null != implementationVendor | |||
| || null != implementationVendorURL) { | |||
| || null != implementationURL) { | |||
| throw tooManyAttributes(); | |||
| } | |||
| // change this to get the objects from the other reference | |||
| @@ -208,7 +208,7 @@ public class ExtensionAdapter extends DataType { | |||
| implementationVersion = other.implementationVersion; | |||
| implementationVendorID = other.implementationVendorID; | |||
| implementationVendor = other.implementationVendor; | |||
| implementationVendorURL = other.implementationVendorURL; | |||
| implementationURL = other.implementationURL; | |||
| } else { | |||
| final String message = | |||
| reference.getRefId() + " doesn\'t refer to a Extension"; | |||
| @@ -251,7 +251,7 @@ public class ExtensionAdapter extends DataType { | |||
| implementationVersionString, | |||
| implementationVendor, | |||
| implementationVendorID, | |||
| implementationVendorURL); | |||
| implementationURL); | |||
| } | |||
| /** | |||
| @@ -66,8 +66,8 @@ import java.text.NumberFormat; | |||
| public abstract class AbstractSshMessage { | |||
| protected Session session; | |||
| protected LogListener listener = new LogListener() { | |||
| private Session session; | |||
| private LogListener listener = new LogListener() { | |||
| public void log(String message) { | |||
| // do nothing; | |||
| } | |||
| @@ -77,9 +77,9 @@ public abstract class AbstractSshMessage { | |||
| this.session = session; | |||
| } | |||
| protected Channel openExecChannel( String command ) throws JSchException { | |||
| ChannelExec channel = (ChannelExec) session.openChannel( "exec" ); | |||
| channel.setCommand( command ); | |||
| protected Channel openExecChannel(String command) throws JSchException { | |||
| ChannelExec channel = (ChannelExec) session.openChannel("exec"); | |||
| channel.setCommand(command); | |||
| return channel; | |||
| } | |||
| @@ -87,7 +87,7 @@ public abstract class AbstractSshMessage { | |||
| protected void sendAck(OutputStream out) throws IOException { | |||
| byte[] buf = new byte[1]; | |||
| buf[0] = 0; | |||
| out.write( buf ); | |||
| out.write(buf); | |||
| out.flush(); | |||
| } | |||
| @@ -100,23 +100,23 @@ public abstract class AbstractSshMessage { | |||
| public abstract void execute() throws IOException, JSchException; | |||
| public void setLogListener( LogListener aListener ) { | |||
| public void setLogListener(LogListener aListener) { | |||
| listener = aListener; | |||
| } | |||
| protected void log( String message ) { | |||
| listener.log( message ); | |||
| protected void log(String message) { | |||
| listener.log(message); | |||
| } | |||
| protected void logStats( long timeStarted, | |||
| protected void logStats(long timeStarted, | |||
| long timeEnded, | |||
| int totalLength) { | |||
| double duration = (timeEnded - timeStarted) / 1000.0; | |||
| NumberFormat format = NumberFormat.getNumberInstance(); | |||
| format.setMaximumFractionDigits( 2 ); | |||
| format.setMinimumFractionDigits( 1 ); | |||
| listener.log( "File transfer time: " + format.format( duration ) + | |||
| " Average Rate: " + format.format( totalLength / duration ) + | |||
| " B/s" ); | |||
| format.setMaximumFractionDigits(2); | |||
| format.setMinimumFractionDigits(1); | |||
| listener.log("File transfer time: " + format.format(duration) | |||
| + " Average Rate: " + format.format(totalLength / duration) | |||
| + " B/s"); | |||
| } | |||
| } | |||
| @@ -66,24 +66,25 @@ public class Directory { | |||
| private ArrayList files; | |||
| private Directory parent; | |||
| public Directory( File directory ) { | |||
| this( directory, null ); | |||
| public Directory(File directory) { | |||
| this(directory, null); | |||
| } | |||
| public Directory( File directory , Directory parent ) { | |||
| public Directory(File directory , Directory parent) { | |||
| this.parent = parent; | |||
| this.childDirectories = new ArrayList(); | |||
| this.files = new ArrayList(); | |||
| this.directory = directory; | |||
| } | |||
| public void addDirectory( Directory directory ) { | |||
| if( !childDirectories.contains( directory ) ) | |||
| childDirectories.add( directory ); | |||
| public void addDirectory(Directory directory) { | |||
| if (!childDirectories.contains(directory)) { | |||
| childDirectories.add(directory); | |||
| } | |||
| } | |||
| public void addFile( File file ) { | |||
| files.add( file ); | |||
| public void addFile(File file) { | |||
| files.add(file); | |||
| } | |||
| public Iterator directoryIterator() { | |||
| @@ -106,10 +107,10 @@ public class Directory { | |||
| return directory; | |||
| } | |||
| public Directory getChild( File dir ) { | |||
| for( int i = 0; i < childDirectories.size(); i++ ) { | |||
| public Directory getChild(File dir) { | |||
| for (int i = 0; i < childDirectories.size(); i++) { | |||
| Directory current = (Directory) childDirectories.get(i); | |||
| if( current.getDirectory().equals( dir ) ) { | |||
| if (current.getDirectory().equals(dir)) { | |||
| return current; | |||
| } | |||
| } | |||
| @@ -118,13 +119,17 @@ public class Directory { | |||
| } | |||
| public boolean equals(Object obj) { | |||
| if( obj == this ) return true; | |||
| if (obj == this) { | |||
| return true; | |||
| } | |||
| if( !(obj instanceof Directory) ) return false; | |||
| if (!(obj instanceof Directory)) { | |||
| return false; | |||
| } | |||
| Directory d = (Directory)obj; | |||
| Directory d = (Directory) obj; | |||
| return this.directory.equals( d.directory ); | |||
| return this.directory.equals(d.directory); | |||
| } | |||
| public int hashCode() { | |||
| @@ -132,16 +137,16 @@ public class Directory { | |||
| } | |||
| public String[] getPath() { | |||
| return getPath( directory.getAbsolutePath() ); | |||
| return getPath(directory.getAbsolutePath()); | |||
| } | |||
| public static String[] getPath( String thePath ) { | |||
| StringTokenizer tokenizer = new StringTokenizer( thePath, | |||
| File.separator ); | |||
| public static String[] getPath(String thePath) { | |||
| StringTokenizer tokenizer = new StringTokenizer(thePath, | |||
| File.separator); | |||
| String[] path = new String[ tokenizer.countTokens() ]; | |||
| int i = 0; | |||
| while( tokenizer.hasMoreTokens() ) { | |||
| while (tokenizer.hasMoreTokens()) { | |||
| path[i] = tokenizer.nextToken(); | |||
| i++; | |||
| } | |||
| @@ -55,5 +55,5 @@ | |||
| package org.apache.tools.ant.taskdefs.optional.ssh; | |||
| public interface LogListener { | |||
| void log( String message ); | |||
| void log(String message); | |||
| } | |||
| @@ -54,9 +54,9 @@ | |||
| package org.apache.tools.ant.taskdefs.optional.ssh; | |||
| import com.jcraft.jsch.*; | |||
| import java.io.*; | |||
| import com.jcraft.jsch.JSchException; | |||
| import com.jcraft.jsch.Session; | |||
| import com.jcraft.jsch.JSch; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.BuildException; | |||
| @@ -70,15 +70,18 @@ import org.apache.tools.ant.Project; | |||
| * @since Ant 1.6 | |||
| */ | |||
| public abstract class SSHBase extends Task implements LogListener { | |||
| /** Default listen port for SSH daemon */ | |||
| private static final int SSH_PORT = 22; | |||
| private String host; | |||
| private String keyfile; | |||
| private String knownHosts; | |||
| private boolean trust = false; | |||
| private int port = 22; | |||
| private int port = SSH_PORT; | |||
| private boolean failOnError = true; | |||
| private SSHUserInfo userInfo; | |||
| /** | |||
| * Constructor for SSHBase. | |||
| */ | |||
| @@ -86,7 +89,7 @@ public abstract class SSHBase extends Task implements LogListener { | |||
| super(); | |||
| userInfo = new SSHUserInfo(); | |||
| } | |||
| /** | |||
| * Remote host, either DNS name or IP. | |||
| * | |||
| @@ -99,8 +102,8 @@ public abstract class SSHBase extends Task implements LogListener { | |||
| public String getHost() { | |||
| return host; | |||
| } | |||
| public void setFailonerror( boolean failure ) { | |||
| public void setFailonerror(boolean failure) { | |||
| failOnError = failure; | |||
| } | |||
| @@ -129,22 +132,22 @@ public abstract class SSHBase extends Task implements LogListener { | |||
| /** | |||
| * Sets the keyfile for the user. | |||
| * | |||
| * | |||
| * @param keyfile The new keyfile value | |||
| */ | |||
| public void setKeyfile(String keyfile) { | |||
| userInfo.setKeyfile(keyfile); | |||
| } | |||
| /** | |||
| * Sets the passphrase for the users key. | |||
| * | |||
| * | |||
| * @param passphrase The new passphrase value | |||
| */ | |||
| public void setPassphrase(String passphrase) { | |||
| userInfo.setPassphrase(passphrase); | |||
| } | |||
| /** | |||
| * Sets the path to the file that has the identities of | |||
| * all known hosts. This is used by SSH protocol to validate | |||
| @@ -153,7 +156,7 @@ public abstract class SSHBase extends Task implements LogListener { | |||
| * | |||
| * @param knownHosts a path to the known hosts file. | |||
| */ | |||
| public void setKnownhosts( String knownHosts ) { | |||
| public void setKnownhosts(String knownHosts) { | |||
| this.knownHosts = knownHosts; | |||
| } | |||
| @@ -162,7 +165,7 @@ public abstract class SSHBase extends Task implements LogListener { | |||
| * | |||
| * @param yesOrNo if true trust the identity of unknown hosts. | |||
| */ | |||
| public void setTrust( boolean yesOrNo ) { | |||
| public void setTrust(boolean yesOrNo) { | |||
| userInfo.setTrust(yesOrNo); | |||
| } | |||
| @@ -171,35 +174,35 @@ public abstract class SSHBase extends Task implements LogListener { | |||
| * | |||
| * @param port port number of remote host. | |||
| */ | |||
| public void setPort( int port ) { | |||
| public void setPort(int port) { | |||
| this.port = port; | |||
| } | |||
| public int getPort() { | |||
| return port; | |||
| } | |||
| public void init() throws BuildException{ | |||
| public void init() throws BuildException { | |||
| super.init(); | |||
| this.knownHosts = System.getProperty("user.home") + "/.ssh/known_hosts"; | |||
| this.trust = false; | |||
| this.port = 22; | |||
| this.port = SSH_PORT; | |||
| } | |||
| protected Session openSession() throws JSchException { | |||
| JSch jsch = new JSch(); | |||
| if (null != userInfo.getKeyfile()) { | |||
| jsch.addIdentity(userInfo.getKeyfile()); | |||
| } | |||
| if( knownHosts != null ) { | |||
| log( "Using known hosts: " + knownHosts, Project.MSG_DEBUG ); | |||
| jsch.setKnownHosts( knownHosts ); | |||
| if (knownHosts != null) { | |||
| log("Using known hosts: " + knownHosts, Project.MSG_DEBUG); | |||
| jsch.setKnownHosts(knownHosts); | |||
| } | |||
| Session session = jsch.getSession( userInfo.getName(), host, port ); | |||
| Session session = jsch.getSession(userInfo.getName(), host, port); | |||
| session.setUserInfo(userInfo); | |||
| log("Connecting to " + host + ":" + port ); | |||
| log("Connecting to " + host + ":" + port); | |||
| session.connect(); | |||
| return session; | |||
| } | |||
| @@ -78,12 +78,19 @@ import com.jcraft.jsch.Session; | |||
| */ | |||
| public class SSHExec extends SSHBase { | |||
| private String command = null; // the command to execute via ssh | |||
| private long maxwait = 0; // units are milliseconds, default is 0=infinite | |||
| private Thread thread = null; // for waiting for the command to finish | |||
| private final int BUFFER_SIZE = 1024; | |||
| private String output_property = null; // like <exec> | |||
| private File output_file = null; // like <exec> | |||
| /** the command to execute via ssh */ | |||
| private String command = null; | |||
| /** units are milliseconds, default is 0=infinite */ | |||
| private long maxwait = 0; | |||
| /** for waiting for the command to finish */ | |||
| private Thread thread = null; | |||
| private String outputProperty = null; // like <exec> | |||
| private File outputFile = null; // like <exec> | |||
| private boolean append = false; // like <exec> | |||
| /** | |||
| @@ -119,7 +126,7 @@ public class SSHExec extends SSHBase { | |||
| * @param output The file to write to. | |||
| */ | |||
| public void setOutput(File output) { | |||
| output_file = output; | |||
| outputFile = output; | |||
| } | |||
| /** | |||
| @@ -140,7 +147,7 @@ public class SSHExec extends SSHBase { | |||
| * will be stored. | |||
| */ | |||
| public void setOutputproperty(String property) { | |||
| output_property = property; | |||
| outputProperty = property; | |||
| } | |||
| /** | |||
| @@ -155,7 +162,7 @@ public class SSHExec extends SSHBase { | |||
| if (getUserInfo().getName() == null) { | |||
| throw new BuildException("Username is required."); | |||
| } | |||
| if (getUserInfo().getKeyfile() == null | |||
| if (getUserInfo().getKeyfile() == null | |||
| && getUserInfo().getPassword() == null) { | |||
| throw new BuildException("Password or Keyfile is required."); | |||
| } | |||
| @@ -170,7 +177,7 @@ public class SSHExec extends SSHBase { | |||
| // execute the command | |||
| Session session = openSession(); | |||
| session.setTimeout((int) maxwait); | |||
| final ChannelExec channel=(ChannelExec) session.openChannel("exec"); | |||
| final ChannelExec channel = (ChannelExec) session.openChannel("exec"); | |||
| channel.setCommand(command); | |||
| channel.setOutputStream(tee); | |||
| channel.connect(); | |||
| @@ -191,25 +198,25 @@ public class SSHExec extends SSHBase { | |||
| } | |||
| } | |||
| }; | |||
| thread.start(); | |||
| thread.join(maxwait); | |||
| if (thread.isAlive()) { | |||
| // ran out of time | |||
| thread = null; | |||
| log("Timeout period exceeded, connection dropped."); | |||
| } else { | |||
| // completed successfully | |||
| if (output_property != null) { | |||
| getProject().setProperty(output_property, out.toString()); | |||
| if (outputProperty != null) { | |||
| getProject().setProperty(outputProperty, out.toString()); | |||
| } | |||
| if (output_file != null) { | |||
| writeToFile(out.toString(), append, output_file); | |||
| if (outputFile != null) { | |||
| writeToFile(out.toString(), append, outputFile); | |||
| } | |||
| } | |||
| } catch(Exception e){ | |||
| } catch (Exception e) { | |||
| if (getFailonerror()) { | |||
| throw new BuildException(e); | |||
| } else { | |||
| @@ -228,20 +235,20 @@ public class SSHExec extends SSHBase { | |||
| * @param append if true, append to existing file, else overwrite | |||
| * @exception Exception most likely an IOException | |||
| */ | |||
| private void writeToFile(String from, boolean append, File to) | |||
| private void writeToFile(String from, boolean append, File to) | |||
| throws IOException { | |||
| FileWriter out = null; | |||
| try { | |||
| out = new FileWriter(to.getAbsolutePath(), append); | |||
| StringReader in = new StringReader(from); | |||
| char[] buffer = new char[8192]; | |||
| int bytes_read; | |||
| int bytesRead; | |||
| while (true) { | |||
| bytes_read = in.read(buffer); | |||
| if (bytes_read == -1) { | |||
| bytesRead = in.read(buffer); | |||
| if (bytesRead == -1) { | |||
| break; | |||
| } | |||
| out.write(buffer, 0, bytes_read); | |||
| out.write(buffer, 0, bytesRead); | |||
| } | |||
| out.flush(); | |||
| } finally { | |||
| @@ -60,19 +60,19 @@ import com.jcraft.jsch.UserInfo; | |||
| * @author rhanderson | |||
| */ | |||
| public class SSHUserInfo implements UserInfo { | |||
| private String name; | |||
| private String password = null; | |||
| private String keyfile; | |||
| private String passphrase = null; | |||
| private boolean firstTime = true; | |||
| private boolean trustAllCertificates; | |||
| public SSHUserInfo() { | |||
| super(); | |||
| this.trustAllCertificates = true; | |||
| super(); | |||
| this.trustAllCertificates = true; | |||
| } | |||
| public SSHUserInfo(String password, boolean trustAllCertificates) { | |||
| super(); | |||
| this.password = password; | |||
| @@ -85,21 +85,21 @@ public class SSHUserInfo implements UserInfo { | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| /** | |||
| * @see com.jcraft.jsch.UserInfo#getPassphrase(String) | |||
| */ | |||
| public String getPassphrase(String message) { | |||
| return passphrase; | |||
| } | |||
| /** | |||
| * @see com.jcraft.jsch.UserInfo#getPassword() | |||
| */ | |||
| public String getPassword() { | |||
| return password; | |||
| } | |||
| /** | |||
| * @see com.jcraft.jsch.UserInfo#prompt(String) | |||
| */ | |||
| @@ -140,7 +140,7 @@ public class SSHUserInfo implements UserInfo { | |||
| /** | |||
| * Sets the trust. | |||
| * @param boolean | |||
| * @param trust whether to trust or not. | |||
| */ | |||
| public void setTrust(boolean trust) { | |||
| this.trustAllCertificates = trust; | |||
| @@ -180,9 +180,9 @@ public class SSHUserInfo implements UserInfo { | |||
| /** | |||
| * @see com.jcraft.jsch.UserInfo#promptPassword(String) | |||
| */ | |||
| public boolean promptPassword( String passwordPrompt ) { | |||
| //log( passwordPrompt, Project.MSG_DEBUG ); | |||
| if( firstTime ) { | |||
| public boolean promptPassword(String passwordPrompt) { | |||
| //log(passwordPrompt, Project.MSG_DEBUG); | |||
| if (firstTime) { | |||
| firstTime = false; | |||
| return true; | |||
| } | |||
| @@ -193,7 +193,7 @@ public class SSHUserInfo implements UserInfo { | |||
| * @see com.jcraft.jsch.UserInfo#promptYesNo(String) | |||
| */ | |||
| public boolean promptYesNo(String message) { | |||
| //log( prompt, Project.MSG_DEBUG ); | |||
| //log(prompt, Project.MSG_DEBUG); | |||
| return trustAllCertificates; | |||
| } | |||
| @@ -201,7 +201,7 @@ public class SSHUserInfo implements UserInfo { | |||
| * @see com.jcraft.jsch.UserInfo#showMessage(String) | |||
| */ | |||
| public void showMessage(String message) { | |||
| //log( message, Project.MSG_DEBUG ); | |||
| //log(message, Project.MSG_DEBUG); | |||
| } | |||
| } | |||
| @@ -54,9 +54,12 @@ | |||
| package org.apache.tools.ant.taskdefs.optional.ssh; | |||
| import com.jcraft.jsch.*; | |||
| import com.jcraft.jsch.JSchException; | |||
| import com.jcraft.jsch.Session; | |||
| import java.io.IOException; | |||
| import java.io.File; | |||
| import java.io.*; | |||
| import java.util.List; | |||
| import java.util.LinkedList; | |||
| import java.util.Iterator; | |||
| @@ -113,11 +116,11 @@ public class Scp extends SSHBase { | |||
| * | |||
| * @param set FileSet to send to remote host. | |||
| */ | |||
| public void addFileset( FileSet set ) { | |||
| if( fileSets == null ) { | |||
| public void addFileset(FileSet set) { | |||
| if (fileSets == null) { | |||
| fileSets = new LinkedList(); | |||
| } | |||
| fileSets.add( set ); | |||
| fileSets.add(set); | |||
| } | |||
| public void init() throws BuildException { | |||
| @@ -132,34 +135,34 @@ public class Scp extends SSHBase { | |||
| throw new BuildException("The 'todir' attribute is required."); | |||
| } | |||
| if ( fromUri == null && fileSets == null ) { | |||
| throw new BuildException("Either the 'file' attribute or one " + | |||
| "FileSet is required."); | |||
| if (fromUri == null && fileSets == null) { | |||
| throw new BuildException("Either the 'file' attribute or one " | |||
| + "FileSet is required."); | |||
| } | |||
| boolean isFromRemote = false; | |||
| if( fromUri != null ) { | |||
| if (fromUri != null) { | |||
| isFromRemote = isRemoteUri(fromUri); | |||
| } | |||
| boolean isToRemote = isRemoteUri(toUri); | |||
| try { | |||
| if (isFromRemote && !isToRemote) { | |||
| download( fromUri, toUri ); | |||
| download(fromUri, toUri); | |||
| } else if (!isFromRemote && isToRemote) { | |||
| if( fileSets != null ) { | |||
| upload( fileSets, toUri ); | |||
| if (fileSets != null) { | |||
| upload(fileSets, toUri); | |||
| } else { | |||
| upload( fromUri, toUri ); | |||
| upload(fromUri, toUri); | |||
| } | |||
| } else if (isFromRemote && isToRemote) { | |||
| // not implemented yet. | |||
| } else { | |||
| throw new BuildException("'todir' and 'file' attributes " + | |||
| "must have syntax like the following: " + | |||
| "user:password@host:/path"); | |||
| throw new BuildException("'todir' and 'file' attributes " | |||
| + "must have syntax like the following: " | |||
| + "user:password@host:/path"); | |||
| } | |||
| } catch (Exception e) { | |||
| if(getFailonerror()) { | |||
| if (getFailonerror()) { | |||
| throw new BuildException(e); | |||
| } else { | |||
| log("Caught exception: " + e.getMessage(), Project.MSG_ERR); | |||
| @@ -167,64 +170,67 @@ public class Scp extends SSHBase { | |||
| } | |||
| } | |||
| private void download( String fromSshUri, String toPath ) | |||
| private void download(String fromSshUri, String toPath) | |||
| throws JSchException, IOException { | |||
| String file = parseUri(fromSshUri); | |||
| Session session = null; | |||
| try { | |||
| session = openSession(); | |||
| ScpFromMessage message = new ScpFromMessage( session, | |||
| ScpFromMessage message = new ScpFromMessage(session, | |||
| file, | |||
| new File( toPath ), | |||
| fromSshUri.endsWith("*") ); | |||
| log("Receiving file: " + file ); | |||
| message.setLogListener( this ); | |||
| new File(toPath), | |||
| fromSshUri.endsWith("*")); | |||
| log("Receiving file: " + file); | |||
| message.setLogListener(this); | |||
| message.execute(); | |||
| } finally { | |||
| if( session != null ) | |||
| if (session != null) { | |||
| session.disconnect(); | |||
| } | |||
| } | |||
| } | |||
| private void upload( List fileSet, String toSshUri ) | |||
| private void upload(List fileSet, String toSshUri) | |||
| throws IOException, JSchException { | |||
| String file = parseUri(toSshUri); | |||
| Session session = null; | |||
| try { | |||
| session = openSession(); | |||
| List list = new ArrayList( fileSet.size() ); | |||
| for( Iterator i = fileSet.iterator(); i.hasNext(); ) { | |||
| List list = new ArrayList(fileSet.size()); | |||
| for (Iterator i = fileSet.iterator(); i.hasNext();) { | |||
| FileSet set = (FileSet) i.next(); | |||
| list.add( createDirectory( set ) ); | |||
| list.add(createDirectory(set)); | |||
| } | |||
| ScpToMessage message = new ScpToMessage( session, | |||
| ScpToMessage message = new ScpToMessage(session, | |||
| list, | |||
| file); | |||
| message.setLogListener( this ); | |||
| message.setLogListener(this); | |||
| message.execute(); | |||
| } finally { | |||
| if( session != null ) | |||
| if (session != null) { | |||
| session.disconnect(); | |||
| } | |||
| } | |||
| } | |||
| private void upload( String fromPath, String toSshUri ) | |||
| private void upload(String fromPath, String toSshUri) | |||
| throws IOException, JSchException { | |||
| String file = parseUri(toSshUri); | |||
| Session session = null; | |||
| try { | |||
| session = openSession(); | |||
| ScpToMessage message = new ScpToMessage( session, | |||
| new File( fromPath ), | |||
| file ); | |||
| message.setLogListener( this ); | |||
| ScpToMessage message = new ScpToMessage(session, | |||
| new File(fromPath), | |||
| file); | |||
| message.setLogListener(this); | |||
| message.execute(); | |||
| } finally { | |||
| if( session != null ) | |||
| if (session != null) { | |||
| session.disconnect(); | |||
| } | |||
| } | |||
| } | |||
| @@ -251,7 +257,7 @@ public class Scp extends SSHBase { | |||
| if (indexOfPath == -1) { | |||
| throw new BuildException("no remote path in " + uri); | |||
| } | |||
| setHost(uri.substring(indexOfAt + 1, indexOfPath)); | |||
| return uri.substring(indexOfPath + 1); | |||
| } | |||
| @@ -265,22 +271,22 @@ public class Scp extends SSHBase { | |||
| return isRemote; | |||
| } | |||
| private Directory createDirectory( FileSet set ) { | |||
| DirectoryScanner scanner = set.getDirectoryScanner( getProject() ); | |||
| Directory root = new Directory( scanner.getBasedir() ); | |||
| private Directory createDirectory(FileSet set) { | |||
| DirectoryScanner scanner = set.getDirectoryScanner(getProject()); | |||
| Directory root = new Directory(scanner.getBasedir()); | |||
| String[] files = scanner.getIncludedFiles(); | |||
| for (int j = 0; j < files.length; j++) { | |||
| String[] path = Directory.getPath( files[j] ); | |||
| String[] path = Directory.getPath(files[j]); | |||
| Directory current = root; | |||
| File currentParent = scanner.getBasedir(); | |||
| for( int i = 0; i < path.length; i++ ) { | |||
| File file = new File( currentParent, path[i] ); | |||
| if( file.isDirectory() ) { | |||
| current.addDirectory( new Directory( file ) ); | |||
| current = current.getChild( file ); | |||
| for (int i = 0; i < path.length; i++) { | |||
| File file = new File(currentParent, path[i]); | |||
| if (file.isDirectory()) { | |||
| current.addDirectory(new Directory(file)); | |||
| current = current.getChild(file); | |||
| currentParent = current.getDirectory(); | |||
| } else if( file.isFile() ) { | |||
| current.addFile( file ); | |||
| } else if (file.isFile()) { | |||
| current.addFile(file); | |||
| } | |||
| } | |||
| } | |||
| @@ -54,21 +54,31 @@ | |||
| package org.apache.tools.ant.taskdefs.optional.ssh; | |||
| import com.jcraft.jsch.*; | |||
| import java.io.*; | |||
| import java.util.StringTokenizer; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.EOFException; | |||
| import java.io.InputStream; | |||
| import java.io.OutputStream; | |||
| import java.io.FileOutputStream; | |||
| import java.io.ByteArrayOutputStream; | |||
| import com.jcraft.jsch.JSchException; | |||
| import com.jcraft.jsch.Session; | |||
| import com.jcraft.jsch.Channel; | |||
| public class ScpFromMessage extends AbstractSshMessage { | |||
| private final byte LINE_FEED = 0x0a; | |||
| private final int BUFFER_SIZE = 1024; | |||
| private String remoteFile; | |||
| private File localFile; | |||
| private boolean isRecursive = false; | |||
| public ScpFromMessage( Session session, | |||
| public ScpFromMessage(Session session, | |||
| String aRemoteFile, | |||
| File aLocalFile, | |||
| boolean recursive ) { | |||
| boolean recursive) { | |||
| super(session); | |||
| this.remoteFile = aRemoteFile; | |||
| this.localFile = aLocalFile; | |||
| @@ -77,10 +87,11 @@ public class ScpFromMessage extends AbstractSshMessage { | |||
| public void execute() throws IOException, JSchException { | |||
| String command = "scp -f "; | |||
| if( isRecursive ) | |||
| if (isRecursive) { | |||
| command += "-r "; | |||
| } | |||
| command += remoteFile; | |||
| Channel channel = openExecChannel( command ); | |||
| Channel channel = openExecChannel(command); | |||
| try { | |||
| // get I/O streams for remote scp | |||
| OutputStream out = channel.getOutputStream(); | |||
| @@ -89,12 +100,13 @@ public class ScpFromMessage extends AbstractSshMessage { | |||
| channel.connect(); | |||
| sendAck(out); | |||
| startRemoteCpProtocol( in, out, localFile); | |||
| startRemoteCpProtocol(in, out, localFile); | |||
| } finally { | |||
| if( channel != null ) | |||
| if (channel != null) { | |||
| channel.disconnect(); | |||
| } | |||
| } | |||
| log( "done\n" ); | |||
| log("done\n"); | |||
| } | |||
| private void startRemoteCpProtocol(InputStream in, | |||
| @@ -106,38 +118,42 @@ public class ScpFromMessage extends AbstractSshMessage { | |||
| // T time 0 time 0\n - present if perserve time. | |||
| // D directory - this is the header for a directory. | |||
| ByteArrayOutputStream stream = new ByteArrayOutputStream(); | |||
| while( true ) { | |||
| while (true) { | |||
| int read = in.read(); | |||
| if( read < 0 ) return; | |||
| if( (byte)read == (byte)0x0a ) break; | |||
| stream.write( read ); | |||
| if (read < 0) { | |||
| return; | |||
| } | |||
| if ((byte) read == LINE_FEED) { | |||
| break; | |||
| } | |||
| stream.write(read); | |||
| } | |||
| String serverResponse = stream.toString("UTF-8"); | |||
| if( serverResponse.charAt(0) == 'C' ) { | |||
| parseAndFetchFile( serverResponse, startFile, out, in ); | |||
| } else if( serverResponse.charAt( 0 ) == 'D' ) { | |||
| startFile = parseAndCreateDirectory( serverResponse, | |||
| startFile ); | |||
| sendAck( out ); | |||
| } else if( serverResponse.charAt(0) == 'E' ) { | |||
| if (serverResponse.charAt(0) == 'C') { | |||
| parseAndFetchFile(serverResponse, startFile, out, in); | |||
| } else if (serverResponse.charAt(0) == 'D') { | |||
| startFile = parseAndCreateDirectory(serverResponse, | |||
| startFile); | |||
| sendAck(out); | |||
| } else if (serverResponse.charAt(0) == 'E') { | |||
| startFile = startFile.getParentFile(); | |||
| sendAck( out ); | |||
| } else if( serverResponse.charAt( 0 ) == '\01' | |||
| || serverResponse.charAt( 0 ) == '\02' ) { | |||
| sendAck(out); | |||
| } else if (serverResponse.charAt(0) == '\01' | |||
| || serverResponse.charAt(0) == '\02') { | |||
| // this indicates an error. | |||
| throw new IOException( serverResponse.substring(1) ); | |||
| throw new IOException(serverResponse.substring(1)); | |||
| } | |||
| } | |||
| } | |||
| private File parseAndCreateDirectory(String serverResponse, | |||
| File localFile) { | |||
| StringTokenizer token = new StringTokenizer( serverResponse ); | |||
| StringTokenizer token = new StringTokenizer(serverResponse); | |||
| String command = token.nextToken(); | |||
| token.nextToken(); // appears that this is not used and it's zero. | |||
| String directoryName = token.nextToken(); | |||
| if( localFile.isDirectory() ) { | |||
| File dir = new File( localFile, directoryName ); | |||
| if (localFile.isDirectory()) { | |||
| File dir = new File(localFile, directoryName); | |||
| dir.mkdir(); | |||
| return dir; | |||
| @@ -149,45 +165,48 @@ public class ScpFromMessage extends AbstractSshMessage { | |||
| File localFile, | |||
| OutputStream out, | |||
| InputStream in) throws IOException { | |||
| StringTokenizer token = new StringTokenizer( serverResponse ); | |||
| StringTokenizer token = new StringTokenizer(serverResponse); | |||
| String command = token.nextToken(); | |||
| int filesize = Integer.parseInt( token.nextToken() ); | |||
| int filesize = Integer.parseInt(token.nextToken()); | |||
| String filename = token.nextToken(); | |||
| log( "Receiving: " + filename + " : " + filesize); | |||
| File transferFile = ( localFile.isDirectory() ) | |||
| ? new File( localFile, filename ) | |||
| log("Receiving: " + filename + " : " + filesize); | |||
| File transferFile = (localFile.isDirectory()) | |||
| ? new File(localFile, filename) | |||
| : localFile; | |||
| fetchFile( transferFile, filesize, out, in); | |||
| fetchFile(transferFile, filesize, out, in); | |||
| waitForAck(in); | |||
| sendAck(out); | |||
| } | |||
| private void fetchFile( File localFile, | |||
| private void fetchFile(File localFile, | |||
| int filesize, | |||
| OutputStream out, | |||
| InputStream in) throws IOException { | |||
| byte[] buf = new byte[1024]; | |||
| byte[] buf = new byte[BUFFER_SIZE]; | |||
| sendAck(out); | |||
| // read a content of lfile | |||
| FileOutputStream fos = new FileOutputStream( localFile ); | |||
| FileOutputStream fos = new FileOutputStream(localFile); | |||
| int length; | |||
| int totalLength = 0; | |||
| long startTime = System.currentTimeMillis(); | |||
| try { | |||
| while (true) { | |||
| length = in.read( buf, 0, | |||
| (buf.length < filesize) ? buf.length : filesize ); | |||
| if( length < 0 ) | |||
| length = in.read(buf, 0, | |||
| (buf.length < filesize) ? buf.length : filesize); | |||
| if (length < 0) { | |||
| throw new EOFException("Unexpected end of stream."); | |||
| fos.write( buf, 0, length ); | |||
| } | |||
| fos.write(buf, 0, length); | |||
| filesize -= length; | |||
| totalLength += length; | |||
| if (filesize == 0) break; | |||
| if (filesize == 0) { | |||
| break; | |||
| } | |||
| } | |||
| } finally { | |||
| long endTime = System.currentTimeMillis(); | |||
| logStats( startTime, endTime, totalLength ); | |||
| logStats(startTime, endTime, totalLength); | |||
| fos.flush(); | |||
| fos.close(); | |||
| } | |||
| @@ -57,39 +57,45 @@ package org.apache.tools.ant.taskdefs.optional.ssh; | |||
| import com.jcraft.jsch.Channel; | |||
| import com.jcraft.jsch.Session; | |||
| import com.jcraft.jsch.JSchException; | |||
| import java.io.*; | |||
| import java.util.*; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.FileInputStream; | |||
| import java.io.OutputStream; | |||
| import java.util.List; | |||
| import java.util.Iterator; | |||
| public class ScpToMessage extends AbstractSshMessage { | |||
| private final int BUFFER_SIZE = 1024; | |||
| private File localFile; | |||
| private String remotePath; | |||
| private List directoryList; | |||
| public ScpToMessage(Session session, | |||
| File aLocalFile, | |||
| String aRemotePath ) { | |||
| String aRemotePath) { | |||
| super(session); | |||
| this.localFile = aLocalFile; | |||
| this.remotePath = aRemotePath; | |||
| } | |||
| public ScpToMessage( Session session, | |||
| public ScpToMessage(Session session, | |||
| List aDirectoryList, | |||
| String aRemotePath ) { | |||
| super( session ); | |||
| String aRemotePath) { | |||
| super(session); | |||
| this.directoryList = aDirectoryList; | |||
| this.remotePath = aRemotePath; | |||
| } | |||
| public void execute() throws IOException, JSchException { | |||
| if( directoryList != null ) { | |||
| if (directoryList != null) { | |||
| doMultipleTransfer(); | |||
| } | |||
| if( localFile != null ) { | |||
| if (localFile != null) { | |||
| doSingleTransfer(); | |||
| } | |||
| log("done.\n"); | |||
| @@ -97,7 +103,7 @@ public class ScpToMessage extends AbstractSshMessage { | |||
| private void doSingleTransfer() throws IOException, JSchException { | |||
| String cmd = "scp -t " + remotePath; | |||
| Channel channel = openExecChannel( cmd ); | |||
| Channel channel = openExecChannel(cmd); | |||
| try { | |||
| OutputStream out = channel.getOutputStream(); | |||
| @@ -109,13 +115,14 @@ public class ScpToMessage extends AbstractSshMessage { | |||
| sendFileToRemote(localFile, in, out); | |||
| waitForAck(in); | |||
| } finally { | |||
| if( channel != null ) | |||
| if (channel != null) { | |||
| channel.disconnect(); | |||
| } | |||
| } | |||
| } | |||
| private void doMultipleTransfer() throws IOException, JSchException { | |||
| Channel channel = openExecChannel( "scp -d -t " + remotePath ); | |||
| Channel channel = openExecChannel("scp -d -t " + remotePath); | |||
| try { | |||
| OutputStream out = channel.getOutputStream(); | |||
| InputStream in = channel.getInputStream(); | |||
| @@ -123,69 +130,71 @@ public class ScpToMessage extends AbstractSshMessage { | |||
| channel.connect(); | |||
| waitForAck(in); | |||
| for( Iterator i = directoryList.iterator(); i.hasNext(); ) { | |||
| Directory current = (Directory)i.next(); | |||
| sendDirectory( current, in, out ); | |||
| for (Iterator i = directoryList.iterator(); i.hasNext();) { | |||
| Directory current = (Directory) i.next(); | |||
| sendDirectory(current, in, out); | |||
| } | |||
| waitForAck(in); | |||
| } finally { | |||
| if( channel != null ) | |||
| if (channel != null) { | |||
| channel.disconnect(); | |||
| } | |||
| } | |||
| } | |||
| private void sendDirectory(Directory current, | |||
| InputStream in, | |||
| OutputStream out) throws IOException { | |||
| for( Iterator fileIt = current.filesIterator(); fileIt.hasNext(); ) { | |||
| sendFileToRemote( (File)fileIt.next(), in, out ); | |||
| for (Iterator fileIt = current.filesIterator(); fileIt.hasNext();) { | |||
| sendFileToRemote((File) fileIt.next(), in, out); | |||
| } | |||
| for( Iterator dirIt = current.directoryIterator(); dirIt.hasNext(); ) { | |||
| for (Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) { | |||
| Directory dir = (Directory) dirIt.next(); | |||
| sendDirectoryToRemote( dir, in ,out ); | |||
| sendDirectoryToRemote(dir, in, out); | |||
| } | |||
| } | |||
| private void sendDirectoryToRemote( Directory directory, | |||
| private void sendDirectoryToRemote(Directory directory, | |||
| InputStream in, | |||
| OutputStream out ) throws IOException { | |||
| OutputStream out) throws IOException { | |||
| String command = "D0755 0 "; | |||
| command += directory.getDirectory().getName(); | |||
| command += "\n"; | |||
| out.write( command.getBytes() ); | |||
| out.write(command.getBytes()); | |||
| out.flush(); | |||
| waitForAck(in); | |||
| sendDirectory( directory, in, out ); | |||
| out.write( "E\n".getBytes() ); | |||
| sendDirectory(directory, in, out); | |||
| out.write("E\n".getBytes()); | |||
| } | |||
| private void sendFileToRemote( File localFile, | |||
| private void sendFileToRemote(File localFile, | |||
| InputStream in, | |||
| OutputStream out ) throws IOException { | |||
| OutputStream out) throws IOException { | |||
| // send "C0644 filesize filename", where filename should not include '/' | |||
| int filesize = (int) localFile.length(); | |||
| String command = "C0644 " + filesize + " "; | |||
| command += localFile.getName(); | |||
| command += "\n"; | |||
| out.write( command.getBytes() ); | |||
| out.write(command.getBytes()); | |||
| out.flush(); | |||
| waitForAck(in); | |||
| // send a content of lfile | |||
| FileInputStream fis = new FileInputStream(localFile); | |||
| byte[] buf = new byte[1024]; | |||
| byte[] buf = new byte[BUFFER_SIZE]; | |||
| long startTime = System.currentTimeMillis(); | |||
| int totalLength = 0; | |||
| try { | |||
| log( "Sending: " + localFile.getName() + " : " + | |||
| localFile.length()); | |||
| log("Sending: " + localFile.getName() + " : " + localFile.length()); | |||
| while (true) { | |||
| int len = fis.read(buf, 0, buf.length); | |||
| if (len <= 0) break; | |||
| if (len <= 0) { | |||
| break; | |||
| } | |||
| out.write(buf, 0, len); | |||
| totalLength += len; | |||
| } | |||
| @@ -193,7 +202,7 @@ public class ScpToMessage extends AbstractSshMessage { | |||
| sendAck(out); | |||
| } finally { | |||
| long endTime = System.currentTimeMillis(); | |||
| logStats( startTime, endTime, totalLength ); | |||
| logStats(startTime, endTime, totalLength); | |||
| fis.close(); | |||
| } | |||
| } | |||