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.Screenable;
008import org.crsh.text.Style;
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  @Override
097  public Appendable append(char c) throws IOException {
098    return append(Character.toString(c));
099  }
100
101  @Override
102  public Appendable append(CharSequence s) throws IOException {
103    return append(s, 0, s.length());
104  }
105
106  @Override
107  public Appendable append(CharSequence csq, int start, int end) throws IOException {
108    while (start < end) {
109      // This is not perfect but it will be OK for now
110      // ideally we should reuse the IO / ConsoleTerm stuff
111      // but for now we don't have the time to do it properly
112      char c = csq.charAt(start++);
113      if (c == '\r') {
114        //
115      } else if (c == '\n') {
116        out.print("\r\n");
117      } else {
118        out.print(c);
119      }
120    }
121    return this;
122  }
123
124  @Override
125  public Screenable append(Style style) throws IOException {
126    return null;
127  }
128
129  @Override
130  public Screenable cls() throws IOException {
131    return null;
132  }
133
134  public void flush() throws IOException {
135    out.flush();
136  }
137
138  public void end(ShellResponse response) {
139    this.response = response;
140    this.latch.countDown();
141  }
142
143  ShellResponse getResponse() {
144    try {
145      latch.await();
146      return response;
147    }
148    catch (InterruptedException e) {
149      throw new RuntimeException(e);
150    }
151  }
152
153}