001package org.crsh.ssh.term.inline;
002
003import org.apache.sshd.server.Environment;
004import org.crsh.plugin.PluginContext;
005import org.crsh.shell.Shell;
006import org.crsh.shell.ShellFactory;
007import org.crsh.shell.ShellProcess;
008import org.crsh.shell.ShellResponse;
009import org.crsh.ssh.term.AbstractCommand;
010import org.crsh.ssh.term.SSHContext;
011import org.crsh.ssh.term.SSHLifeCycle;
012
013import java.io.IOException;
014import java.io.PrintStream;
015import java.security.Principal;
016import java.util.logging.Level;
017import java.util.logging.Logger;
018
019/** SSH inline command */
020public class SSHInlineCommand extends AbstractCommand implements Runnable {
021
022  /** . */
023  protected static final Logger log = Logger.getLogger(SSHInlineCommand.class.getName());
024
025  /** . */
026  protected static final int OK = 0;
027
028  /** . */
029  protected static final int ERROR = 2;
030
031  /** . */
032  private Thread thread;
033
034  /** . */
035  private String command;
036
037  /** . */
038  private PluginContext pluginContext;
039
040  /** . */
041  private Environment env;
042
043  public SSHInlineCommand(String command, PluginContext pluginContext) {
044    this.command = command;
045    this.pluginContext = pluginContext;
046  }
047
048  public void start(Environment environment) throws IOException {
049    this.env = environment;
050    thread = new Thread(this, "CRaSH");
051    thread.start();
052  }
053
054  public void destroy() {
055    thread.interrupt();
056  }
057
058  public void run() {
059
060    // get principal
061    PrintStream err = new PrintStream(this.err);
062    PrintStream out = new PrintStream(this.out);
063    final String userName = session.getAttribute(SSHLifeCycle.USERNAME);
064    Principal user = new Principal() {
065      public String getName() {
066        return userName;
067      }
068    };
069    Shell shell = pluginContext.getPlugin(ShellFactory.class).create(user);
070    ShellProcess shellProcess = shell.createProcess(command);
071
072    //
073    SSHInlineShellProcessContext context = new SSHInlineShellProcessContext(new SSHContext(env), shellProcess, out, err);
074    int exitStatus = OK;
075    String exitMsg = null;
076
077    //
078    try {
079      shellProcess.execute(context);
080    }
081    catch (Exception e) {
082      log.log(Level.SEVERE, "Error during command execution", e);
083      exitMsg = e.getMessage();
084      exitStatus = ERROR;
085    }
086    finally {
087      // get command output
088      ShellResponse response = context.getResponse();
089      if (response instanceof ShellResponse.Ok) {
090        // Ok
091      }
092      else {
093        String errorMsg;
094
095        // Set the exit status to Error
096        exitStatus = ERROR;
097
098        if (response != null) {
099          errorMsg = "Error during command execution : " + response.getMessage();
100        }
101        else {
102          errorMsg = "Error during command execution";
103        }
104        err.println(errorMsg);
105        if (response instanceof ShellResponse.Error) {
106          ShellResponse.Error error = (ShellResponse.Error)response;
107          log.log(Level.SEVERE, errorMsg, error.getThrowable());
108        } else {
109          log.log(Level.SEVERE, errorMsg);
110        }
111      }
112
113      // Say we are done
114      if (callback != null) {
115        callback.onExit(exitStatus, exitMsg);
116      }
117    }
118  }
119}