001package org.crsh.ssh.term.inline;
002
003import org.crsh.shell.ShellProcess;
004import org.crsh.shell.ShellProcessContext;
005import org.crsh.shell.ShellResponse;
006import org.crsh.ssh.term.SSHContext;
007import org.crsh.text.Chunk;
008import org.crsh.text.Text;
009
010import java.io.IOException;
011import java.io.PrintStream;
012import java.util.concurrent.CountDownLatch;
013
014/** ShellProcessContext for SSH inline commands */
015public class SSHInlineShellProcessContext implements ShellProcessContext {
016
017  /** . */
018  private static final String MSG = "Cannot determine tty width : you should force pseudo-tty allocation (-t option)";
019
020  /** . */
021  private boolean msgDone;
022
023  /** . */
024  private ShellResponse response;
025
026  /** . */
027  private final CountDownLatch latch;
028
029  /** . */
030  private final SSHContext context;
031
032  /** . */
033  private final ShellProcess process;
034
035  /** . */
036  private final PrintStream out;
037
038  /** . */
039  private final PrintStream err;
040
041  SSHInlineShellProcessContext(SSHContext context, ShellProcess process, PrintStream out, PrintStream err) {
042    this.out = out;
043    this.context = context;
044    this.process = process;
045    this.latch = new CountDownLatch(1);
046    this.response = null;
047    this.err = err;
048    this.msgDone = false;
049  }
050
051  public SSHInlineShellProcessContext execute() {
052    process.execute(this);
053    return this;
054  }
055
056  public boolean takeAlternateBuffer() {
057    return false;
058  }
059
060  public boolean releaseAlternateBuffer() {
061    return false;
062  }
063
064  public int getWidth() {
065    int width = context.getWidth();
066    if (width == -1) {
067      if (!msgDone) {
068        msgDone = true;
069        out.print(MSG);
070        out.flush();
071      }
072    }
073    return width;
074  }
075
076  public int getHeight() {
077    int height = context.getHeight();
078    if (height == -1) {
079      if (!msgDone) {
080        msgDone = true;
081        out.print(MSG);
082        out.flush();
083        }
084    }
085    return height;
086  }
087
088  public String getProperty(String name) {
089    return context.getProperty(name);
090  }
091
092  public String readLine(String msg, boolean echo) {
093    return null;
094  }
095
096  public void write(Chunk element) throws IOException {
097    if (element instanceof Text) {
098      CharSequence seq = ((Text)element).getText();
099      int length = seq.length();
100      if (length > 0) {
101        for (int i = 0;i < length;i++) {
102          // This is not perfect but it will be OK for now
103          // ideally we should reuse the IO / ConsoleTerm stuff
104          // but for now we don't have the time to do it properly
105          char c = seq.charAt(i);
106          if (c == '\r') {
107            //
108          } else if (c == '\n') {
109            out.print("\r\n");
110          } else {
111            out.print(c);
112          }
113        }
114      }
115    }
116  }
117
118  public void flush() throws IOException {
119    out.flush();
120  }
121
122  public void end(ShellResponse response) {
123    this.response = response;
124    this.latch.countDown();
125  }
126
127  ShellResponse getResponse() {
128    try {
129      latch.await();
130      return response;
131    }
132    catch (InterruptedException e) {
133      throw new RuntimeException(e);
134    }
135  }
136
137}