org.apache.sshd.common.channel.PtyMode Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including
all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and
JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sshd.common.channel;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.MapEntryUtils;
/**
* A enum describing the tty modes according to RFC 4254 -
* section 8.
*
* @author Apache MINA SSHD Project
*/
public enum PtyMode {
/////////////////////////////// Chars ////////////////////////////////////
/**
* Interrupt character; 255 if none. Similarly for the other characters. Not all of these characters are supported
* on all systems.
*/
VINTR(1),
/**
* The quit character (sends SIGQUIT signal on POSIX systems).
*/
VQUIT(2),
/**
* Erase the character to left of the cursor.
*/
VERASE(3),
/**
* Kill the current input line.
*/
VKILL(4),
/**
* End-of-file character (sends EOF from the terminal).
*/
VEOF(5),
/**
* End-of-line character in addition to carriage return and/or line-feed.
*/
VEOL(6),
/**
* Additional end-of-line character.
*/
VEOL2(7),
/**
* Continues paused output (normally control-Q).
*/
VSTART(8),
/**
* Pauses output (normally control-S).
*/
VSTOP(9),
/**
* Suspends the current program.
*/
VSUSP(10),
/**
* Another suspend character.
*/
VDSUSP(11),
/**
* Reprints the current input line.
*/
VREPRINT(12),
/**
* Erases a word left of cursor.
*/
VWERASE(13),
/**
* Enter the next character typed literally, even if it is a special character
*/
VLNEXT(14),
/**
* Character to flush output.
*/
VFLUSH(15),
/**
* Switch to a different shell layer.
*/
VSWTCH(16),
/**
* Prints system status line (load, command, pid, etc).
*/
VSTATUS(17),
/**
* Toggles the flushing of terminal output.
*/
VDISCARD(18),
///////////////////////////////// I-flags ////////////////////////////////
/**
* The ignore parity flag. The parameter SHOULD be 0 if this flag is FALSE, and 1 if it is TRUE.
*/
IGNPAR(30),
/**
* Mark parity and framing errors.
*/
PARMRK(31),
/**
* Enable checking of parity errors.
*/
INPCK(32),
/**
* Strip 8th bit off characters.
*/
ISTRIP(33),
/**
* Map NL into CR on input.
*/
INLCR(34),
/**
* Ignore CR on input.
*/
IGNCR(35),
/**
* Map CR to NL on input.
*/
ICRNL(36),
/**
* Translate uppercase characters to lowercase.
*/
IUCLC(37),
/**
* Enable output flow control.
*/
IXON(38),
/**
* Any char will restart after stop.
*/
IXANY(39),
/**
* Enable input flow control.
*/
IXOFF(40),
/**
* Ring bell on input queue full.
*/
IMAXBEL(41),
/**
* @see IUTF8 Terminal Mode in Secure Shell
*/
IUTF8(42),
/////////////////////////////// L-flags //////////////////////////////////
/**
* Enable signals INTR, QUIT, [D]SUSP.
*/
ISIG(50),
/**
* Canonicalize input lines.
*/
ICANON(51),
/**
* Enable input and output of uppercase characters by preceding their lowercase equivalents with "\".
*/
XCASE(52),
/**
* Enable echoing.
*/
ECHO(53),
/**
* Visually erase chars.
*/
ECHOE(54),
/**
* Kill character discards current line.
*/
ECHOK(55),
/**
* Echo NL even if ECHO is off.
*/
ECHONL(56),
/**
* Don't flush after interrupt.
*/
NOFLSH(57),
/**
* Stop background jobs from output.
*/
TOSTOP(58),
/**
* Enable extensions.
*/
IEXTEN(59),
/**
* Echo control characters as ^(Char).
*/
ECHOCTL(60),
/**
* Visual erase for line kill.
*/
ECHOKE(61),
/**
* Retype pending input.
*/
PENDIN(62),
/////////////////////////// O-flags //////////////////////////////////////
/**
* Enable output processing.
*/
OPOST(70),
/**
* Convert lowercase to uppercase.
*/
OLCUC(71),
/**
* Map NL to CR-NL.
*/
ONLCR(72),
/**
* Translate carriage return to newline (output).
*/
OCRNL(73),
/**
* Translate newline to carriage return-newline (output).
*/
ONOCR(74),
/**
* Newline performs a carriage return (output).
*/
ONLRET(75),
//////////////////////////////// C-flags /////////////////////////////////
/**
* 7 bit mode.
*/
CS7(90),
/**
* 8 bit mode.
*/
CS8(91),
/**
* Parity enable.
*/
PARENB(92),
/**
* Odd parity, else even.
*/
PARODD(93),
/////////////////////////// Speed(s) /////////////////////////////////////
/**
* Specifies the input baud rate in bits per second.
*/
TTY_OP_ISPEED(128),
/**
* Specifies the output baud rate in bits per second.
*/
TTY_OP_OSPEED(129);
public static final byte TTY_OP_END = 0x00;
// objects that can be used to set {@link PtyMode}s as {@code true} or {@code false}
public static final Integer FALSE_SETTING = 0;
public static final Integer TRUE_SETTING = 1;
/**
* An un-modifiable {@link Set} of all defined {@link PtyMode}s
*/
public static final Set MODES = Collections.unmodifiableSet(EnumSet.allOf(PtyMode.class));
public static final NavigableMap COMMANDS = Collections.unmodifiableNavigableMap(
MapEntryUtils.toSortedMap(MODES, PtyMode::toInt, Function.identity(), Comparator.naturalOrder()));
/**
* A {@code null}-safe {@link ToIntFunction} that returns the {@link PtyMode#toInt()} value and (-1) for
* {@code null}
*/
public static final ToIntFunction OPCODE_EXTRACTOR = op -> (op == null) ? -1 : op.toInt();
/**
* A {@code null}-safe {@link Comparator} of {@link PtyMode} values according to their {@link PtyMode#toInt()} value
*
* @see #OPCODE_EXTRACTOR
*/
public static final Comparator BY_OPCODE = (o1, o2) -> {
int v1 = OPCODE_EXTRACTOR.applyAsInt(o1);
int v2 = OPCODE_EXTRACTOR.applyAsInt(o2);
return Integer.compare(v1, v2);
};
private final int v;
PtyMode(int v) {
this.v = v;
}
public int toInt() {
return v;
}
/**
* @param b The numeric value of the option
* @return The matching {@link PtyMode} or {@code null} if no match found
* @see #toInt()
*/
public static PtyMode fromInt(int b) {
return COMMANDS.get(0x00FF & b);
}
public static PtyMode fromName(String name) {
if (GenericUtils.isEmpty(name)) {
return null;
}
for (PtyMode m : MODES) {
if (name.equalsIgnoreCase(m.name())) {
return m;
}
}
return null;
}
/**
* @param options The options to enable - ignored if {@code null}/empty
* @return A {@link Map} where all the specified {@link PtyMode}s have {@link #TRUE_SETTING}
*/
public static Map createEnabledOptions(PtyMode... options) {
return createEnabledOptions(GenericUtils.of(options));
}
/**
* @param options The options to enable - ignored if {@code null}/empty
* @return A {@link Map} where all the specified {@link PtyMode}s have {@link #TRUE_SETTING}
*/
public static Map createEnabledOptions(Collection options) {
if (GenericUtils.isEmpty(options)) {
return Collections.emptyMap();
}
Map modes = new EnumMap<>(PtyMode.class);
for (PtyMode m : options) {
modes.put(m, TRUE_SETTING);
}
return modes;
}
public static Set resolveEnabledOptions(Map modes, PtyMode... options) {
return resolveEnabledOptions(modes, GenericUtils.of(options));
}
/**
* @param modes The PTY settings - ignored if {@code null}/empty
* @param options The options that should be enabled
* @return A {@link Set} of all the {@link PtyMode}s that appeared in the settings and were enabled
* @see #getBooleanSettingValue(Map, PtyMode)
*/
public static Set resolveEnabledOptions(Map modes, Collection options) {
if (MapEntryUtils.isEmpty(modes) || GenericUtils.isEmpty(options)) {
return Collections.emptySet();
}
Set enabled = EnumSet.noneOf(PtyMode.class);
for (PtyMode m : options) {
if (getBooleanSettingValue(modes, m)) {
enabled.add(m);
}
}
return enabled;
}
/**
* @param modes The current modes {@link Map}-ing
* @param m The required {@link PtyMode}
* @return {@code true} if all of these conditions hold:
*
* - Modes map is not {@code null}/empty
* - Required mode setting is not {@code null}
* - The setting has a mapped value
* - The mapped value is a {@link Number}
* - The {@link Number#intValue()} is non-zero
*
* @see #getBooleanSettingValue(Object)
*/
public static boolean getBooleanSettingValue(Map modes, PtyMode m) {
if ((m == null) || MapEntryUtils.isEmpty(modes)) {
return false;
} else {
return getBooleanSettingValue(modes.get(m));
}
}
/**
* @param modes The {@link Map} of {@link PtyMode}s resolved by the "pty-req" message.
* @param enablers A {@link Collection} of enabler settings to be consulted
* @param defaultValue The default value to be used if no definite setting could be deduced
* @return {@code true} if the CR mode is enabled:
*
* - Ifmodes or enablers are {@code null}/empty then defaultValue
* is used
*
* - If any of the enablers modes are enabled then the CR mode is enabled.
*
*
* - If none of the enablers modes were specified then use
* defaultValue
*
* - Otherwise (i.e., at least one or more of the enablers modes were specified, but
* all of them said {@code no}) then {@code false}.
*
*/
public static boolean getBooleanSettingValue(
Map modes, Collection enablers, boolean defaultValue) {
if (MapEntryUtils.isEmpty(modes) || GenericUtils.isEmpty(enablers)) {
return defaultValue;
}
int settingsCount = 0;
for (PtyMode m : enablers) {
Object v = modes.get(m);
if (v == null) {
continue;
}
settingsCount++;
// if any setting says yes then use it
if (getBooleanSettingValue(v)) {
return true;
}
}
// ALL (!) settings have said NO
if (settingsCount > 0) {
return false;
} else {
return defaultValue; // none of the settings has been found - assume default
}
}
/**
* @param v The value to be tested
* @return {@code true} if all of these conditions hold:
*
* - The mapped value is a {@link Number}
* - The {@link Number#intValue()} is non-zero
*
* @see #getBooleanSettingValue(int)
*/
public static boolean getBooleanSettingValue(Object v) {
return (v instanceof Number) && getBooleanSettingValue(((Number) v).intValue());
}
/**
* @param v The setting value
* @return {@code true} if value is non-zero
*/
public static boolean getBooleanSettingValue(int v) {
return v != 0;
}
/**
* @param m The {@link PtyMode}
* @return {@code true} if not {@code null} and one of the settings that refers to a character value - name
* usually starts with {@code Vxxx}
*/
public static boolean isCharSetting(PtyMode m) {
if (m == null) {
return false;
}
String name = m.name();
char ch = name.charAt(0);
return (ch == 'v') || (ch == 'V');
}
}