/* This file is part of VoltDB.
 * Copyright (C) 2008-2013 VoltDB Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.voltdb.processtools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.atomic.AtomicBoolean;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class ProcessData {
    private final Session m_ssh_session;
    private final Channel m_channel;
    private final StreamWatcher m_out;
    private final StreamWatcher m_err;
    private Thread m_sshThread;

    public enum Stream { STDERR, STDOUT; }

    public static class OutputLine {
        public OutputLine(String processName, Stream stream, String value) {
            this.processName = processName;
            this.stream = stream;
            this.message = value;
        }

        public final String processName;
        public final Stream stream;
        public final String message;
    }

    class StreamWatcher extends Thread {
        final BufferedReader m_reader;
        final String m_processName;
        final Stream m_stream;
        final OutputHandler m_handler;
        final AtomicBoolean m_expectDeath = new AtomicBoolean(false);

        StreamWatcher(BufferedReader reader, String processName, Stream stream,
                      OutputHandler handler) {
            assert(reader != null);
            m_reader = reader;
            m_processName = processName;
            m_stream = stream;
            m_handler = handler;
        }

        void setExpectDeath(boolean expectDeath) {
            m_expectDeath.set(expectDeath);
        }

        @Override
        public void run() {
            while (true) {
                String line = null;
                try {
                    line = m_reader.readLine();
                } catch (IOException e) {
                    if (!m_expectDeath.get()) {
                        e.printStackTrace();
                        System.err.print("Err Stream monitoring thread exiting.");
                        System.err.flush();
                    }
                    return;
                }
                if (line != null) {
                    OutputLine ol = new OutputLine(m_processName, m_stream, line);
                    if (m_handler != null) {
                        m_handler.update(ol);
                    } else {
                        final long now = (System.currentTimeMillis() / 1000) - 1256158053;
                        System.out.println("(" + now + ")" + m_processName + ": " + line);
                    }
                } else {
                    return;
                }
            }
        }
    }

    ProcessData(String processName, OutputHandler handler, Session ssh_session, final String command) throws JSchException, IOException {
        m_ssh_session = ssh_session;
        m_channel=ssh_session.openChannel("exec");
        ((ChannelExec)m_channel).setCommand(command);

        // Set up the i/o streams
        m_channel.setInputStream(null);
        BufferedReader out = new BufferedReader(new InputStreamReader(m_channel.getInputStream()));
        BufferedReader err = new BufferedReader(new InputStreamReader(((ChannelExec) m_channel).getErrStream()));
        m_out = new StreamWatcher(out, processName, Stream.STDOUT, handler);
        m_err = new StreamWatcher(err, processName, Stream.STDERR, handler);

        /*
         * Execute the command non-blocking.
         */
        m_sshThread = new Thread() {
            @Override
            public void run() {
                try {
                    m_channel.connect();
                    m_out.start();
                    m_err.start();
                } catch (Exception e) {
                    e.printStackTrace();
                    System.err.print("Err SSH long-running execution thread exiting.");
                    System.err.flush();
                }
            }
        };
        m_sshThread.start();
    }

    public int kill() {
        m_out.m_expectDeath.set(true);
        m_err.m_expectDeath.set(true);
        int retval = -255;
        synchronized(m_channel) {
            /*
            try { m_channel.sendSignal("HUP"); }
            catch (Exception e) {
                System.err.print("WARN: Caught exception while terminating remote server\n");
                e.printStackTrace();
            }
            */
            m_channel.disconnect();
            m_ssh_session.disconnect();
        }
        m_sshThread.interrupt();
        return retval;
    }

    public boolean isAlive() {
        synchronized(m_channel) {
            return (m_ssh_session.isConnected() && m_channel.getExitStatus() == -1);
        }
    }
}

@@ -4866,266 +4866,8 @@
 ) %7B%0A
-            /*%0A            try %7B m_channel.sendSignal(%22HUP%22); %7D%0A            catch (Exception e) %7B%0A                System.err.print(%22WARN: Caught exception while terminating remote server%5Cn%22);%0A                e.printStackTrace();%0A            %7D%0A            */%0A
     

remove commented code