protected Command prepareCommand()

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;
    }