001    package org.crsh.ssh.term.inline;
002    
003    import org.apache.sshd.server.Environment;
004    import org.crsh.plugin.PluginContext;
005    import org.crsh.shell.Shell;
006    import org.crsh.shell.ShellFactory;
007    import org.crsh.shell.ShellProcess;
008    import org.crsh.shell.ShellResponse;
009    import org.crsh.ssh.term.AbstractCommand;
010    import org.crsh.ssh.term.SSHContext;
011    import org.crsh.ssh.term.SSHLifeCycle;
012    
013    import java.io.IOException;
014    import java.io.PrintStream;
015    import java.security.Principal;
016    import java.util.logging.Level;
017    import java.util.logging.Logger;
018    
019    /** SSH inline command */
020    public 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              // Set the exit status to Error
095            exitStatus = ERROR;
096            if (response != null) {
097              errorMsg = "Error during command execution : " + response.getMessage();
098            }
099            else {
100              errorMsg = "Error during command execution";
101            }
102            err.println(errorMsg);
103            if (response instanceof ShellResponse.Error) {
104              ShellResponse.Error error = (ShellResponse.Error)response;
105              log.log(Level.SEVERE, errorMsg, error.getThrowable());
106            } else {
107              log.log(Level.SEVERE, errorMsg);
108            }
109          }
110    
111          // Say we are done
112          if (callback != null) {
113            callback.onExit(exitStatus, exitMsg);
114          }
115        }
116      }
117    }