From cd372b2d5feb20f0c24f05bda874802a5a5f6f48 Mon Sep 17 00:00:00 2001 From: michal Date: Wed, 25 Jun 2003 12:33:11 +0000 Subject: [PATCH] Added SCP deloyer. git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@113537 13f79535-47bb-0310-9956-ffa450edef68 --- .../artifact/deployer/MavenDeployRequest.java | 48 ++-- .../org/apache/maven/deploy/DeployTool.java | 7 +- .../deploy/deployers/GenericSshDeployer.java | 232 +++++++++++++++ .../maven/deploy/deployers/SFtpDeployer.java | 173 +++-------- .../maven/deploy/deployers/ScpDeployer.java | 269 ++++++++++++++++++ 5 files changed, 568 insertions(+), 161 deletions(-) create mode 100644 artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java create mode 100644 artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java diff --git a/artifact/src/main/org/apache/maven/artifact/deployer/MavenDeployRequest.java b/artifact/src/main/org/apache/maven/artifact/deployer/MavenDeployRequest.java index c0c19ecd..a9bf2e17 100644 --- a/artifact/src/main/org/apache/maven/artifact/deployer/MavenDeployRequest.java +++ b/artifact/src/main/org/apache/maven/artifact/deployer/MavenDeployRequest.java @@ -64,7 +64,7 @@ import org.apache.maven.project.Project; * The Bean which serves as Proxy for Jelly scripts To Artifact Deployement API * * @author Michal Maczka - * @version $Id: MavenDeployRequest.java,v 1.5 2003/06/24 22:22:55 michal Exp $ + * @version $Id: MavenDeployRequest.java,v 1.6 2003/06/25 12:33:11 michal Exp $ */ public class MavenDeployRequest extends DeployRequest { @@ -95,13 +95,11 @@ public class MavenDeployRequest extends DeployRequest String username = (String) project.getContext().getVariable( "maven.repo." + repository + ".username"); - + String password = (String) project.getContext().getVariable( "maven.repo." + repository + ".password"); - System.out.println(repository + " password: '" + password + "'"); - String passphrase = (String) project.getContext().getVariable( "maven.repo." + repository + ".passphrase"); @@ -120,7 +118,7 @@ public class MavenDeployRequest extends DeployRequest String remoteGroup = (String) project.getContext().getVariable( - "maven.repo." + repository + ".remote.group"); + "maven.repo." + repository + ".group"); String proxyHost = (String) project.getContext().getVariable( @@ -142,26 +140,32 @@ public class MavenDeployRequest extends DeployRequest setPassphrase(passphrase); setPrivateKey(privateKey); setGroup(remoteGroup); - setUrl(url.trim()); + setUrl(url); + setProxyHost(proxyHost); + setProxyUser(proxyUser); + setProxyPass(proxyPassword); + if (port != null) + { + try + { - try - { - setPort(Integer.parseInt(port)); + setPort(Integer.parseInt(port)); + } + catch (Exception e) + { + //throw new DeployException("maven.repo." + repository + ".port should be an integer"); + } } - catch (Exception e) + if (proxyPort != null) { - - setProxyHost(proxyHost); - setProxyUser(proxyUser); - setProxyPass(proxyPassword); - } - try - { - setProxyPort(Integer.parseInt(proxyPort.trim())); - } - catch (Exception e) - { - + try + { + setProxyPort(Integer.parseInt(proxyPort.trim())); + } + catch (Exception e) + { + //throw new DeployException("maven.repo." + repository + ".proxy.port should be an integer"); + } } setInputFile(inputFile); diff --git a/artifact/src/main/org/apache/maven/deploy/DeployTool.java b/artifact/src/main/org/apache/maven/deploy/DeployTool.java index 76759da8..04a168c6 100644 --- a/artifact/src/main/org/apache/maven/deploy/DeployTool.java +++ b/artifact/src/main/org/apache/maven/deploy/DeployTool.java @@ -61,13 +61,14 @@ import org.apache.maven.deploy.deployers.FileDeployer; import org.apache.maven.deploy.deployers.FtpDeployer; import org.apache.maven.deploy.deployers.HttpDeployer; import org.apache.maven.deploy.deployers.SFtpDeployer; +import org.apache.maven.deploy.deployers.ScpDeployer; import org.apache.maven.deploy.exceptions.DeployException; import org.apache.maven.deploy.exceptions.UnsupportedProtocolDeployException; /** * * @author Michal Maczka - * @version $Id: DeployTool.java,v 1.3 2003/06/24 22:22:55 michal Exp $ + * @version $Id: DeployTool.java,v 1.4 2003/06/25 12:33:11 michal Exp $ */ public class DeployTool { @@ -100,6 +101,10 @@ public class DeployTool { deployer = new SFtpDeployer(); } + if (url.startsWith(ScpDeployer.PROTOCOL)) + { + deployer = new ScpDeployer(); + } if (deployer == null) { throw new UnsupportedProtocolDeployException(url); diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java new file mode 100644 index 00000000..616be894 --- /dev/null +++ b/artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java @@ -0,0 +1,232 @@ +package org.apache.maven.deploy.deployers; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 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 acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache MavenSession" 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", + * "Apache MavenSession", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * 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 + * . + * + * ==================================================================== + */ + +import java.io.File; + +import org.apache.maven.deploy.DeployRequest; +import org.apache.maven.deploy.exceptions.DeployException; + +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Proxy; +import com.jcraft.jsch.ProxyHTTP; +import com.jcraft.jsch.ProxySOCKS5; +import com.jcraft.jsch.Session; +import com.jcraft.jsch.UserInfo; + +/** + * An ssh2 deployer that uses the JSch library and the JCE. + * + * This class deals with authetification stage of the process. + * + * We will first try to + * use public keys for authentication and if that doesn't work then we fall back + * to using the login and password of the user in question. NOTE: We are + * assuming the standard port of 22. + * + * + * @version $Id: GenericSshDeployer.java,v 1.1 2003/06/25 12:33:11 michal Exp $ + * @todo still have to account for differing setups for people deploying to + * their own sites and to the central repository. + */ +public abstract class GenericSshDeployer extends AbstractDeployer +{ + + public final static int DEFAULT_SSH_PORT = 22; + public final static int SOCKS5_PROXY_PORT = 1080; + + + /** + * @see Deployer#project + * + * @todo better way of guessing what kind of proxy server is used + * by user + */ + public Session getSession(DeployRequest request) throws DeployException + { + + try + { + JSch jsch = new JSch(); + + int port = request.getPort(); + if (port == DeployRequest.UNKNOWN_PORT) + { + port = DEFAULT_SSH_PORT; + } + String host = request.getHost(); + Session session = jsch.getSession(request.getUser(), host, port); + + String proxyHost = request.getProxyHost(); + + if (proxyHost != null) + { + Proxy proxy = null; + int proxyPort = request.getProxyPort(); + //if port == 1080 we will use SOCKS5 Proxy + // otherwise will use HTTP Proxy + + if (proxyPort == SOCKS5_PROXY_PORT) + { + proxy = new ProxySOCKS5(proxyHost); + ((ProxySOCKS5) proxy).setUserPasswd( + request.getProxyUser(), + request.getProxyPass()); + } + else + { + proxy = new ProxyHTTP(proxyHost, proxyPort); + ((ProxyHTTP) proxy).setUserPasswd( + request.getProxyUser(), + request.getProxyPass()); + } + proxy.connect(session, host, port); + + } + + // Look for the private key and use it if available. + if (request.getPrivateKey() != null) + { + File privateKey = new File(request.getPrivateKey()); + + if (privateKey.exists()) + { + System.out.println("Using private key: " + privateKey); + jsch.addIdentity( + privateKey.getAbsolutePath(), + request.getPassphrase()); + } + } + // username and password will be given via UserInfo interface. + UserInfo ui = new MavenUserInfo(request); + session.setUserInfo(ui); + session.connect(); + return session; + + } + catch (Exception e) + { + e.printStackTrace(); + throw new DeployException( + "Cannot connect. Reason: " + e.getMessage(), + e); + } + } + + /** + * MavenUserInfo class which returns the necessary name and password from + * the POM to secure an ssh connection. + */ + public class MavenUserInfo implements UserInfo + { + + DeployRequest request; + + MavenUserInfo(DeployRequest request) + { + this.request = request; + } + + public String getPassphrase() + { + return request.getPassphrase(); + } + + /* (non-Javadoc) + * @see com.jcraft.jsch.UserInfo#getPassword() + */ + public String getPassword() + { + return request.getPass(); + } + + /* (non-Javadoc) + * @see com.jcraft.jsch.UserInfo#promptPassphrase(java.lang.String) + */ + public boolean promptPassphrase(String arg0) + { + return true; + } + + /* (non-Javadoc) + * @see com.jcraft.jsch.UserInfo#promptPassword(java.lang.String) + */ + public boolean promptPassword(String arg0) + { + return true; + } + + /** + * @see com.jcraft.jsch.UserInfo#promptYesNo(java.lang.String) + */ + public boolean promptYesNo(String arg0) + { + return true; + } + + /* (non-Javadoc) + * @see com.jcraft.jsch.UserInfo#showMessage(java.lang.String) + */ + public void showMessage(String message) + { + System.out.println(message); + + } + + } + +} diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java index 9616dce5..85cb3874 100644 --- a/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java +++ b/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java @@ -56,41 +56,28 @@ package org.apache.maven.deploy.deployers; * ==================================================================== */ -import java.io.File; - import org.apache.commons.lang.StringUtils; import org.apache.maven.deploy.DeployRequest; import org.apache.maven.deploy.exceptions.DeployException; import com.jcraft.jsch.ChannelSftp; -import com.jcraft.jsch.JSch; -import com.jcraft.jsch.Proxy; -import com.jcraft.jsch.ProxyHTTP; -import com.jcraft.jsch.ProxySOCKS5; +import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpATTRS; -import com.jcraft.jsch.UserInfo; +import com.jcraft.jsch.SftpException; /** - * An ssh2 deployer that uses the JSch library and the JCE. We will first try to - * use public keys for authentication and if that doesn't work then we fall back - * to using the login and password of the user in question. NOTE: We are - * assuming the standard port of 22. - * - * @author Jason van Zyl - * @version $Id: SFtpDeployer.java,v 1.1 2003/06/24 22:22:54 michal Exp $ - * @todo still have to account for differing setups for people deploying to - * their own sites and to the central repository. + * An SSH2 SFTP deployer + * + * @author Michal Maczka + * @version $Revision: 1.2 $ $Date: 2003/06/25 12:33:11 $ */ -public class SFtpDeployer extends AbstractDeployer +public class SFtpDeployer extends GenericSshDeployer { public final static String PROTOCOL = "sftp://"; - public final static String SFTP_CHANNEL = "sftp"; - public final static int DEFAULT_SSH_PORT = 22; - public final static int SOCKS5_PROXY_PORT = 1080; - public final static int S_IFDIR = 0x4000; + /** * @see Deployer#project @@ -111,65 +98,12 @@ public class SFtpDeployer extends AbstractDeployer { throw new DeployException("For sftp protocol remote group should be an integer"); } + + Session session = getSession(request); + ChannelSftp channel = null; try { - JSch jsch = new JSch(); - - int port = request.getPort(); - if (port == DeployRequest.UNKNOWN_PORT) - { - port = DEFAULT_SSH_PORT; - } - String host = request.getHost(); - Session session = jsch.getSession(request.getUser(), host, port); - - String proxyHost = request.getProxyHost(); - - if (proxyHost != null) - { - Proxy proxy = null; - int proxyPort = request.getProxyPort(); - //if port == 1080 we will use SOCKS5 Proxy - // otherwise will use HTTP Proxy - - if (proxyPort == SOCKS5_PROXY_PORT) - { - proxy = new ProxySOCKS5(proxyHost); - ((ProxySOCKS5) proxy).setUserPasswd( - request.getProxyUser(), - request.getProxyPass()); - } - else - { - proxy = new ProxyHTTP(proxyHost, proxyPort); - ((ProxyHTTP) proxy).setUserPasswd( - request.getProxyUser(), - request.getProxyPass()); - } - proxy.connect(session, host, port); - - } - - // Look for the private key and use it if available. - if (request.getPrivateKey() != null) - { - File privateKey = new File(request.getPrivateKey()); - - if (privateKey.exists()) - { - System.out.println("Using private key: " + privateKey); - jsch.addIdentity( - privateKey.getAbsolutePath(), - request.getPassphrase()); - } - } - // username and password will be given via UserInfo interface. - UserInfo ui = new MavenUserInfo(request); - session.setUserInfo(ui); - session.connect(); - - ChannelSftp channel = - (ChannelSftp) session.openChannel(SFTP_CHANNEL); + channel = (ChannelSftp) session.openChannel(SFTP_CHANNEL); channel.connect(); // iterate over all directories in the path. try to create // directory @@ -195,7 +129,7 @@ public class SFtpDeployer extends AbstractDeployer } catch (Exception e) { - // file does not exists + // file most probably does not exists channel.mkdir(dirs[i]); channel.cd(dirs[i]); } @@ -210,75 +144,38 @@ public class SFtpDeployer extends AbstractDeployer } } - catch (Exception e) + catch (SftpException e) { - e.printStackTrace(); throw new DeployException( "Cannot deploy. Reason: " + e.getMessage(), e); } - } - /** - * MavenUserInfo class which returns the necessary name and password from - * the POM to secure an ssh connection. - */ - public class MavenUserInfo implements UserInfo - { - - DeployRequest request; - - MavenUserInfo(DeployRequest request) + catch (JSchException e) { - this.request = request; + throw new DeployException( + "Cannot deploy. Reason: " + e.getMessage(), + e); } - - public String getPassphrase() + finally { - return request.getPassphrase(); + try + { + channel.disconnect(); + } + catch (Exception e) + { + //just ignore. + } + try + { + session.disconnect(); + } + catch (Exception e) + { + // just ignore. + } } - - /* (non-Javadoc) - * @see com.jcraft.jsch.UserInfo#getPassword() - */ - public String getPassword() - { - return request.getPass(); - } - - /* (non-Javadoc) - * @see com.jcraft.jsch.UserInfo#promptPassphrase(java.lang.String) - */ - public boolean promptPassphrase(String arg0) - { - return true; - } - - /* (non-Javadoc) - * @see com.jcraft.jsch.UserInfo#promptPassword(java.lang.String) - */ - public boolean promptPassword(String arg0) - { - return true; - } - - /** - * @see com.jcraft.jsch.UserInfo#promptYesNo(java.lang.String) - */ - public boolean promptYesNo(String arg0) - { - return true; - } - - /* (non-Javadoc) - * @see com.jcraft.jsch.UserInfo#showMessage(java.lang.String) - */ - public void showMessage(String message) - { - System.out.println(message); - - } - } } diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java new file mode 100644 index 00000000..ac210234 --- /dev/null +++ b/artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java @@ -0,0 +1,269 @@ +package org.apache.maven.deploy.deployers; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 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 acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache MavenSession" 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", + * "Apache MavenSession", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * 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 + * . + * + * ==================================================================== + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.maven.deploy.DeployRequest; +import org.apache.maven.deploy.exceptions.DeployException; + +import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; + +/** + * An SSH2 SFTP deployer + * + * @author Michal Maczka + * @version $Revision: 1.1 $ $Date: 2003/06/25 12:33:11 $ + */ +public class ScpDeployer extends GenericSshDeployer +{ + + public final static String PROTOCOL = "scp://"; + + public final static String EXEC_CHANNEL = "exec"; + + /** + * @see Deployer#project + * + * @todo better way of guessing what king of proxy server is used + */ + public void deploy(DeployRequest request) throws DeployException + { + + Session session = getSession(request); + try + { + + //String scpCmd = "scp -t " + request.getOutputFile() + "\n"; + executeSimpleCommand( + session, + "mkdir -p " + request.getOutputDir() + "\n"); + + doCopy(session, request); + if (request.getGroup() != null) + { + executeSimpleCommand( + session, + "chgrp " + + request.getGroup() + + " " + + request.getOutputFile() + + "\n"); + } + + } + finally + { + try + { + session.disconnect(); + } + catch (Exception e) + { + // just ignore. + } + } + } + + /** + * Execute simple command + */ + private void executeSimpleCommand(Session session, String command) + throws DeployException + { + + System.out.println("Executing command: " + command); + ChannelExec channel = null; + try + { + channel = (ChannelExec) session.openChannel(EXEC_CHANNEL); + channel.setCommand(command); + OutputStream out = channel.getOutputStream(); + InputStream in = channel.getInputStream(); + channel.connect(); + } + catch (Exception e) + { + throw new DeployException( + "Cannot execute remote command: " + command); + } + finally + { + //when channel cannot be closed it is still ok. this "local" + //failure is not global failure + if (channel != null) + { + try + { + channel.disconnect(); + } + catch (Exception e) + { + //ignore + } + } + } + } + + /** + * Copy artifact file using streams (pipes) + */ + private void doCopy(Session session, DeployRequest request) + throws DeployException + { + + try + { + String inputFile = request.getInputFile(); + String outputFile = request.getOutputFile(); + String outputDir = request.getOutputDir(); + // exec 'scp -t rfile' remotely + String command = "scp -t " + outputDir + "/" + outputFile; + System.out.println("Executing command: " + command); + ChannelExec channel = + (ChannelExec) session.openChannel(EXEC_CHANNEL); + channel.setCommand(command); + // get I/O streams for remote scp + OutputStream out = channel.getOutputStream(); + InputStream in = channel.getInputStream(); + channel.connect(); + + byte[] tmp = new byte[1]; + + // wait for '\0' + do + { + in.read(tmp, 0, 1); + } + while (tmp[0] != 0); + + // send "C0644 filesize filename", where filename should not include '/' + int filesize = (int) (new File(inputFile)).length(); + command = "C0644 " + filesize + " "; + if (inputFile.lastIndexOf('/') > 0) + { + command += inputFile.substring(inputFile.lastIndexOf('/') + 1); + } + else + { + command += inputFile; + } + command += "\n"; + + out.write(command.getBytes()); + out.flush(); + + // wait for '\0' + do + { + in.read(tmp, 0, 1); + } + while (tmp[0] != 0); + + // send a content of inputFile + FileInputStream fis = new FileInputStream(inputFile); + byte[] buf = new byte[1024]; + while (true) + { + int len = fis.read(buf, 0, buf.length); + if (len <= 0) + break; + out.write(buf, 0, len); + out.flush(); + } + + // send '\0' + buf[0] = 0; + out.write(buf, 0, 1); + out.flush(); + + // wait for '\0' + do + { + in.read(tmp, 0, 1); + } + while (tmp[0] != 0); + } + catch (FileNotFoundException e) + { + + throw new DeployException( + "Input file was not found: " + request.getInputFile(), + e); + } + catch (IOException e) + { + throw new DeployException( + "IO error while sending file: " + request.getInputFile(), + e); + } + catch (JSchException e) + { + throw new DeployException( + "Error occured while copying file to remote host", + e); + } + } + +}