package jetbrains.buildServer.deployer.agent.ssh;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import jetbrains.buildServer.RunBuildException;
import jetbrains.buildServer.agent.BuildProgressLogger;
import jetbrains.buildServer.deployer.agent.SyncBuildProcessAdapter;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedReader;
import java.io.InputStreamReader;


class SSHExecProcessAdapter extends SyncBuildProcessAdapter {

    private final String myCommands;
    private final SSHSessionProvider myProvider;


    public SSHExecProcessAdapter(@NotNull final SSHSessionProvider provider,
                                 @NotNull final String commands,
                                 @NotNull final BuildProgressLogger buildLogger) {
        super(buildLogger);
        myProvider = provider;
        myCommands = commands;
    }


    @Override
    public void runProcess() throws RunBuildException {

        final Session session = myProvider.getSession();

        try {
            executeCommand(session, myCommands);
        } catch (RunBuildException e) {
            throw e;
        } catch (Exception e) {
            throw new RunBuildException(e);
        } finally {
            if (session != null) {
                session.disconnect();
            }
        }
    }

    private void executeCommand(Session session, String command) throws Exception {
        ChannelExec channel = null;
        myLogger.message("Executing commands:\n" + command + "\non host [" + session.getHost() + "]");
        try {
            channel = (ChannelExec)session.openChannel("exec");
            channel.setCommand(command);

            final BufferedReader reader = new BufferedReader(new InputStreamReader(channel.getInputStream()));
            channel.connect();

            final StringBuilder result = new StringBuilder();
            while (true) {
                final String str = reader.readLine();
                if (str != null) {
                    result.append(str).append('\n');
                } else {
                    break;
                }
            }
            myLogger.message("Exec output:\n" + result.toString());
        } finally {
            if (channel != null) {
                channel.disconnect();
                int exitCode = channel.getExitStatus();
                if (exitCode > 0) {
                    throw new RunBuildException("Non-zero exit code from ssh exec: [" + exitCode + "]");
                }
                myLogger.message("ssh exit-code: " + exitCode);
            }
        }

    }
}

@@ -84,37 +84,8 @@
 ec;%0A
-import com.jcraft.jsch.JSch;%0A
 impo
@@ -355,24 +355,52 @@
 eredReader;%0A
+import java.io.InputStream;%0A
 import java.
@@ -1715,56 +1715,21 @@
 nal 
-BufferedReader reader = new BufferedReader(new I
+InputStream i
 nput
@@ -1738,15 +1738,11 @@
 ream
-Reader(
+ = 
 chan
@@ -1765,43 +1765,9 @@
 am()
-));%0A            channel.connect();%0A
+;
 %0A   
@@ -1841,77 +1841,223 @@
     
-while (true) %7B%0A                final String str = reader.readLine();%0A
+byte%5B%5D buf = new byte%5B8192%5D;%0A%0A            channel.connect();%0A            while (!isInterrupted()) %7B%0A                if (inputStream.available() %3E 0) %7B%0A                    int i = inputStream.read(buf, 0, 8192);%0A    
     
@@ -2076,19 +2076,13 @@
 if (
-str != null
+i %3C 0
 ) %7B%0A
@@ -2105,63 +2105,156 @@
     
-result.append(str).append('%5Cn');%0A                %7D else
+    break;%0A                    %7D%0A                    result.append(new String(buf, 0, i));%0A                %7D%0A                if (channel.isClosed())
  %7B%0A 
@@ -2303,32 +2303,33 @@
 %7D%0A            %7D%0A
+%0A
             myLo
@@ -2376,24 +2376,124 @@
 oString());%0A
+            if (isInterrupted()) %7B%0A                myLogger.message(%22Interrupted.%22);%0A            %7D%0A%0A
         %7D fi
@@ -2625,24 +2625,88 @@
 itStatus();%0A
+                myLogger.message(%22ssh exit-code: %22 + exitCode);%0A
             
@@ -2856,72 +2856,8 @@
   %7D%0A
-                myLogger.message(%22ssh exit-code: %22 + exitCode);%0A
     

make ssh exec interruptible