in sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java [712:800]
protected Command prepareCommand(String requestType, Command command) throws IOException {
if (command == null) {
return null;
}
// Add the user
Session session = getSession();
addEnvVariable(Environment.ENV_USER, session.getUsername());
// If the shell wants to be aware of the session, let's do that
if (command instanceof ServerSessionAware) {
((ServerSessionAware) command).setSession((ServerSession) session);
}
if (command instanceof ChannelSessionAware) {
((ChannelSessionAware) command).setChannelSession(this);
}
// If the shell wants to be aware of the file system, let's do that too
if (command instanceof FileSystemAware) {
ServerFactoryManager manager = ((ServerSession) session).getFactoryManager();
FileSystemFactory factory = manager.getFileSystemFactory();
((FileSystemAware) command).setFileSystemFactory(factory, session);
}
// If the shell wants to use non-blocking io
if (command instanceof AsyncCommandStreamsAware) {
asyncOut = new ChannelAsyncOutputStream(
this, SshConstants.SSH_MSG_CHANNEL_DATA);
asyncErr = new ChannelAsyncOutputStream(
this, SshConstants.SSH_MSG_CHANNEL_EXTENDED_DATA);
((AsyncCommandStreamsAware) command).setIoOutputStream(asyncOut);
((AsyncCommandStreamsAware) command).setIoErrorStream(asyncErr);
} else {
RemoteWindow wRemote = getRemoteWindow();
out = new ChannelOutputStream(
this, wRemote, log, SshConstants.SSH_MSG_CHANNEL_DATA, false);
err = new ChannelOutputStream(
this, wRemote, log, SshConstants.SSH_MSG_CHANNEL_EXTENDED_DATA, false);
if (log.isTraceEnabled()) {
// Wrap in logging filters
out = new LoggingFilterOutputStream(out, "OUT(" + this + ")", log, this);
err = new LoggingFilterOutputStream(err, "ERR(" + this + ")", log, this);
}
command.setOutputStream(out);
command.setErrorStream(err);
}
if (this.receiver == null) {
// if the command hasn't installed any ChannelDataReceiver, install the default
// and give the command an InputStream
if (command instanceof AsyncCommandInputStreamAware) {
AsyncDataReceiver recv = new AsyncDataReceiver(this);
setDataReceiver(recv);
((AsyncCommandInputStreamAware) command).setIoInputStream(recv.getIn());
} else {
PipeDataReceiver recv = new PipeDataReceiver(this, getLocalWindow());
setDataReceiver(recv);
command.setInputStream(recv.getIn());
}
}
if (receiverBuffer != null) {
Buffer buffer = receiverBuffer;
receiverBuffer = null;
doWriteData(buffer.array(), buffer.rpos(), buffer.available());
}
if (extendedDataBuffer != null) {
if (extendedDataWriter == null) {
throw new UnsupportedOperationException(
"No extended data writer available though " + extendedDataBuffer.available() + " bytes accumulated");
}
Buffer buffer = extendedDataBuffer;
extendedDataBuffer = null;
doWriteExtendedData(buffer.array(), buffer.rpos(), buffer.available());
}
command.setExitCallback((exitValue, exitMessage, closeImmediately) -> {
try {
closeShell(exitValue, closeImmediately);
if (log.isDebugEnabled()) {
log.debug("onExit({}) code={} message='{}' shell closed",
ChannelSession.this, exitValue, exitMessage);
}
} catch (IOException e) {
log.warn("onExit({}) code={} message='{}' {} closing shell: {}",
ChannelSession.this, exitValue, exitMessage, e.getClass().getSimpleName(), e.getMessage());
}
});
return command;
}