Skip to content

Commit

Permalink
Fix ssh attributes transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet committed Dec 22, 2023
1 parent 4cedcb9 commit 32d2af1
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,59 +110,50 @@ public void start(final ChannelSession session, final Environment env) throws IO

public void run(ChannelSession session, Environment env) throws Exception {
try {
Terminal terminal = TerminalBuilder.builder()
.name("JLine SSH")
.type(env.getEnv().get("TERM"))
.system(false)
.streams(in, out)
.build();
terminal.setSize(new Size(
Integer.parseInt(env.getEnv().get("COLUMNS")),
Integer.parseInt(env.getEnv().get("LINES"))));
Attributes attr = terminal.getAttributes();
Attributes attributes = new Attributes();
for (Map.Entry<PtyMode, Integer> e : env.getPtyModes().entrySet()) {
switch (e.getKey()) {
case VINTR:
attr.setControlChar(ControlChar.VINTR, e.getValue());
attributes.setControlChar(ControlChar.VINTR, e.getValue());
break;
case VQUIT:
attr.setControlChar(ControlChar.VQUIT, e.getValue());
attributes.setControlChar(ControlChar.VQUIT, e.getValue());
break;
case VERASE:
attr.setControlChar(ControlChar.VERASE, e.getValue());
attributes.setControlChar(ControlChar.VERASE, e.getValue());
break;
case VKILL:
attr.setControlChar(ControlChar.VKILL, e.getValue());
attributes.setControlChar(ControlChar.VKILL, e.getValue());
break;
case VEOF:
attr.setControlChar(ControlChar.VEOF, e.getValue());
attributes.setControlChar(ControlChar.VEOF, e.getValue());
break;
case VEOL:
attr.setControlChar(ControlChar.VEOL, e.getValue());
attributes.setControlChar(ControlChar.VEOL, e.getValue());
break;
case VEOL2:
attr.setControlChar(ControlChar.VEOL2, e.getValue());
attributes.setControlChar(ControlChar.VEOL2, e.getValue());
break;
case VSTART:
attr.setControlChar(ControlChar.VSTART, e.getValue());
attributes.setControlChar(ControlChar.VSTART, e.getValue());
break;
case VSTOP:
attr.setControlChar(ControlChar.VSTOP, e.getValue());
attributes.setControlChar(ControlChar.VSTOP, e.getValue());
break;
case VSUSP:
attr.setControlChar(ControlChar.VSUSP, e.getValue());
attributes.setControlChar(ControlChar.VSUSP, e.getValue());
break;
case VDSUSP:
attr.setControlChar(ControlChar.VDSUSP, e.getValue());
attributes.setControlChar(ControlChar.VDSUSP, e.getValue());
break;
case VREPRINT:
attr.setControlChar(ControlChar.VREPRINT, e.getValue());
attributes.setControlChar(ControlChar.VREPRINT, e.getValue());
break;
case VWERASE:
attr.setControlChar(ControlChar.VWERASE, e.getValue());
attributes.setControlChar(ControlChar.VWERASE, e.getValue());
break;
case VLNEXT:
attr.setControlChar(ControlChar.VLNEXT, e.getValue());
attributes.setControlChar(ControlChar.VLNEXT, e.getValue());
break;
/*
case VFLUSH:
Expand All @@ -173,44 +164,53 @@ public void run(ChannelSession session, Environment env) throws Exception {
break;
*/
case VSTATUS:
attr.setControlChar(ControlChar.VSTATUS, e.getValue());
attributes.setControlChar(ControlChar.VSTATUS, e.getValue());
break;
case VDISCARD:
attr.setControlChar(ControlChar.VDISCARD, e.getValue());
attributes.setControlChar(ControlChar.VDISCARD, e.getValue());
break;
case ECHO:
attr.setLocalFlag(LocalFlag.ECHO, e.getValue() != 0);
attributes.setLocalFlag(LocalFlag.ECHO, e.getValue() != 0);
break;
case ICANON:
attr.setLocalFlag(LocalFlag.ICANON, e.getValue() != 0);
attributes.setLocalFlag(LocalFlag.ICANON, e.getValue() != 0);
break;
case ISIG:
attr.setLocalFlag(LocalFlag.ISIG, e.getValue() != 0);
attributes.setLocalFlag(LocalFlag.ISIG, e.getValue() != 0);
break;
case ICRNL:
attr.setInputFlag(InputFlag.ICRNL, e.getValue() != 0);
attributes.setInputFlag(InputFlag.ICRNL, e.getValue() != 0);
break;
case INLCR:
attr.setInputFlag(InputFlag.INLCR, e.getValue() != 0);
attributes.setInputFlag(InputFlag.INLCR, e.getValue() != 0);
break;
case IGNCR:
attr.setInputFlag(InputFlag.IGNCR, e.getValue() != 0);
attributes.setInputFlag(InputFlag.IGNCR, e.getValue() != 0);
break;
case OCRNL:
attr.setOutputFlag(OutputFlag.OCRNL, e.getValue() != 0);
attributes.setOutputFlag(OutputFlag.OCRNL, e.getValue() != 0);
break;
case ONLCR:
attr.setOutputFlag(OutputFlag.ONLCR, e.getValue() != 0);
attributes.setOutputFlag(OutputFlag.ONLCR, e.getValue() != 0);
break;
case ONLRET:
attr.setOutputFlag(OutputFlag.ONLRET, e.getValue() != 0);
attributes.setOutputFlag(OutputFlag.ONLRET, e.getValue() != 0);
break;
case OPOST:
attr.setOutputFlag(OutputFlag.OPOST, e.getValue() != 0);
attributes.setOutputFlag(OutputFlag.OPOST, e.getValue() != 0);
break;
}
}
terminal.setAttributes(attr);
Terminal terminal = TerminalBuilder.builder()
.name("JLine SSH")
.type(env.getEnv().get("TERM"))
.system(false)
.streams(in, out)
.attributes(attributes)
.size(new Size(
Integer.parseInt(env.getEnv().get("COLUMNS")),
Integer.parseInt(env.getEnv().get("LINES"))))
.build();
env.addSignalListener(
(channel, signals) -> {
terminal.setSize(new Size(
Expand Down
86 changes: 46 additions & 40 deletions remote-ssh/src/main/java/org/jline/builtins/ssh/Ssh.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,49 +203,49 @@ public void ssh(
try {
Map<PtyMode, Integer> modes = new HashMap<>();
// Control chars
modes.put(PtyMode.VINTR, attributes.getControlChar(Attributes.ControlChar.VINTR));
modes.put(PtyMode.VQUIT, attributes.getControlChar(Attributes.ControlChar.VQUIT));
modes.put(PtyMode.VERASE, attributes.getControlChar(Attributes.ControlChar.VERASE));
modes.put(PtyMode.VKILL, attributes.getControlChar(Attributes.ControlChar.VKILL));
modes.put(PtyMode.VEOF, attributes.getControlChar(Attributes.ControlChar.VEOF));
modes.put(PtyMode.VEOL, attributes.getControlChar(Attributes.ControlChar.VEOL));
modes.put(PtyMode.VEOL2, attributes.getControlChar(Attributes.ControlChar.VEOL2));
modes.put(PtyMode.VSTART, attributes.getControlChar(Attributes.ControlChar.VSTART));
modes.put(PtyMode.VSTOP, attributes.getControlChar(Attributes.ControlChar.VSTOP));
modes.put(PtyMode.VSUSP, attributes.getControlChar(Attributes.ControlChar.VSUSP));
modes.put(PtyMode.VDSUSP, attributes.getControlChar(Attributes.ControlChar.VDSUSP));
modes.put(PtyMode.VREPRINT, attributes.getControlChar(Attributes.ControlChar.VREPRINT));
modes.put(PtyMode.VWERASE, attributes.getControlChar(Attributes.ControlChar.VWERASE));
modes.put(PtyMode.VLNEXT, attributes.getControlChar(Attributes.ControlChar.VLNEXT));
modes.put(PtyMode.VSTATUS, attributes.getControlChar(Attributes.ControlChar.VSTATUS));
modes.put(PtyMode.VDISCARD, attributes.getControlChar(Attributes.ControlChar.VDISCARD));
setMode(modes, PtyMode.VINTR, attributes.getControlChar(Attributes.ControlChar.VINTR));
setMode(modes, PtyMode.VQUIT, attributes.getControlChar(Attributes.ControlChar.VQUIT));
setMode(modes, PtyMode.VERASE, attributes.getControlChar(Attributes.ControlChar.VERASE));
setMode(modes, PtyMode.VKILL, attributes.getControlChar(Attributes.ControlChar.VKILL));
setMode(modes, PtyMode.VEOF, attributes.getControlChar(Attributes.ControlChar.VEOF));
setMode(modes, PtyMode.VEOL, attributes.getControlChar(Attributes.ControlChar.VEOL));
setMode(modes, PtyMode.VEOL2, attributes.getControlChar(Attributes.ControlChar.VEOL2));
setMode(modes, PtyMode.VSTART, attributes.getControlChar(Attributes.ControlChar.VSTART));
setMode(modes, PtyMode.VSTOP, attributes.getControlChar(Attributes.ControlChar.VSTOP));
setMode(modes, PtyMode.VSUSP, attributes.getControlChar(Attributes.ControlChar.VSUSP));
setMode(modes, PtyMode.VDSUSP, attributes.getControlChar(Attributes.ControlChar.VDSUSP));
setMode(modes, PtyMode.VREPRINT, attributes.getControlChar(Attributes.ControlChar.VREPRINT));
setMode(modes, PtyMode.VWERASE, attributes.getControlChar(Attributes.ControlChar.VWERASE));
setMode(modes, PtyMode.VLNEXT, attributes.getControlChar(Attributes.ControlChar.VLNEXT));
setMode(modes, PtyMode.VSTATUS, attributes.getControlChar(Attributes.ControlChar.VSTATUS));
setMode(modes, PtyMode.VDISCARD, attributes.getControlChar(Attributes.ControlChar.VDISCARD));
// Input flags
modes.put(PtyMode.IGNPAR, getFlag(attributes, Attributes.InputFlag.IGNPAR));
modes.put(PtyMode.PARMRK, getFlag(attributes, Attributes.InputFlag.PARMRK));
modes.put(PtyMode.INPCK, getFlag(attributes, Attributes.InputFlag.INPCK));
modes.put(PtyMode.ISTRIP, getFlag(attributes, Attributes.InputFlag.ISTRIP));
modes.put(PtyMode.INLCR, getFlag(attributes, Attributes.InputFlag.INLCR));
modes.put(PtyMode.IGNCR, getFlag(attributes, Attributes.InputFlag.IGNCR));
modes.put(PtyMode.ICRNL, getFlag(attributes, Attributes.InputFlag.ICRNL));
modes.put(PtyMode.IXON, getFlag(attributes, Attributes.InputFlag.IXON));
modes.put(PtyMode.IXANY, getFlag(attributes, Attributes.InputFlag.IXANY));
modes.put(PtyMode.IXOFF, getFlag(attributes, Attributes.InputFlag.IXOFF));
setMode(modes, PtyMode.IGNPAR, getFlag(attributes, Attributes.InputFlag.IGNPAR));
setMode(modes, PtyMode.PARMRK, getFlag(attributes, Attributes.InputFlag.PARMRK));
setMode(modes, PtyMode.INPCK, getFlag(attributes, Attributes.InputFlag.INPCK));
setMode(modes, PtyMode.ISTRIP, getFlag(attributes, Attributes.InputFlag.ISTRIP));
setMode(modes, PtyMode.INLCR, getFlag(attributes, Attributes.InputFlag.INLCR));
setMode(modes, PtyMode.IGNCR, getFlag(attributes, Attributes.InputFlag.IGNCR));
setMode(modes, PtyMode.ICRNL, getFlag(attributes, Attributes.InputFlag.ICRNL));
setMode(modes, PtyMode.IXON, getFlag(attributes, Attributes.InputFlag.IXON));
setMode(modes, PtyMode.IXANY, getFlag(attributes, Attributes.InputFlag.IXANY));
setMode(modes, PtyMode.IXOFF, getFlag(attributes, Attributes.InputFlag.IXOFF));
// Local flags
modes.put(PtyMode.ISIG, getFlag(attributes, Attributes.LocalFlag.ISIG));
modes.put(PtyMode.ICANON, getFlag(attributes, Attributes.LocalFlag.ICANON));
modes.put(PtyMode.ECHO, getFlag(attributes, Attributes.LocalFlag.ECHO));
modes.put(PtyMode.ECHOE, getFlag(attributes, Attributes.LocalFlag.ECHOE));
modes.put(PtyMode.ECHOK, getFlag(attributes, Attributes.LocalFlag.ECHOK));
modes.put(PtyMode.ECHONL, getFlag(attributes, Attributes.LocalFlag.ECHONL));
modes.put(PtyMode.NOFLSH, getFlag(attributes, Attributes.LocalFlag.NOFLSH));
modes.put(PtyMode.TOSTOP, getFlag(attributes, Attributes.LocalFlag.TOSTOP));
modes.put(PtyMode.IEXTEN, getFlag(attributes, Attributes.LocalFlag.IEXTEN));
setMode(modes, PtyMode.ISIG, getFlag(attributes, Attributes.LocalFlag.ISIG));
setMode(modes, PtyMode.ICANON, getFlag(attributes, Attributes.LocalFlag.ICANON));
setMode(modes, PtyMode.ECHO, getFlag(attributes, Attributes.LocalFlag.ECHO));
setMode(modes, PtyMode.ECHOE, getFlag(attributes, Attributes.LocalFlag.ECHOE));
setMode(modes, PtyMode.ECHOK, getFlag(attributes, Attributes.LocalFlag.ECHOK));
setMode(modes, PtyMode.ECHONL, getFlag(attributes, Attributes.LocalFlag.ECHONL));
setMode(modes, PtyMode.NOFLSH, getFlag(attributes, Attributes.LocalFlag.NOFLSH));
setMode(modes, PtyMode.TOSTOP, getFlag(attributes, Attributes.LocalFlag.TOSTOP));
setMode(modes, PtyMode.IEXTEN, getFlag(attributes, Attributes.LocalFlag.IEXTEN));
// Output flags
modes.put(PtyMode.OPOST, getFlag(attributes, Attributes.OutputFlag.OPOST));
modes.put(PtyMode.ONLCR, getFlag(attributes, Attributes.OutputFlag.ONLCR));
modes.put(PtyMode.OCRNL, getFlag(attributes, Attributes.OutputFlag.OCRNL));
modes.put(PtyMode.ONOCR, getFlag(attributes, Attributes.OutputFlag.ONOCR));
modes.put(PtyMode.ONLRET, getFlag(attributes, Attributes.OutputFlag.ONLRET));
setMode(modes, PtyMode.OPOST, getFlag(attributes, Attributes.OutputFlag.OPOST));
setMode(modes, PtyMode.ONLCR, getFlag(attributes, Attributes.OutputFlag.ONLCR));
setMode(modes, PtyMode.OCRNL, getFlag(attributes, Attributes.OutputFlag.OCRNL));
setMode(modes, PtyMode.ONOCR, getFlag(attributes, Attributes.OutputFlag.ONOCR));
setMode(modes, PtyMode.ONLRET, getFlag(attributes, Attributes.OutputFlag.ONLRET));
channel.setPtyModes(modes);
channel.setPtyColumns(terminal.getWidth());
channel.setPtyLines(terminal.getHeight());
Expand Down Expand Up @@ -304,6 +304,12 @@ public void ssh(
}
}

private static void setMode(Map<PtyMode, Integer> modes, PtyMode vintr, int attributes) {
if (attributes >= 0) {
modes.put(vintr, attributes);
}
}

private static int getFlag(Attributes attributes, Attributes.InputFlag flag) {
return attributes.getInputFlag(flag) ? 1 : 0;
}
Expand Down

0 comments on commit 32d2af1

Please # to comment.