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    
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    }