package org.dcache.services.ssh2;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.fusesource.jansi.Ansi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import diskCacheV111.admin.UserAdminShell;
import dmg.cells.nucleus.NoRouteToCellException;
import dmg.cells.nucleus.SerializationException;
import dmg.util.CommandAclException;
import dmg.util.CommandEvaluationException;
import dmg.util.CommandException;
import dmg.util.CommandExitException;
import dmg.util.CommandPanicException;
import dmg.util.CommandSyntaxException;
import org.dcache.util.Strings;
public class NoTerminalCommand implements Command, Runnable
{
private static final Logger _logger =
LoggerFactory.getLogger(NoTerminalCommand.class);
private final UserAdminShell _userAdminShell;
private ExitCallback _exitCallback;
private BufferedReader _reader;
private PrintWriter _error;
private PrintWriter _writer;
private Thread _adminShellThread;
public NoTerminalCommand(UserAdminShell shell)
{
_userAdminShell = shell;
}
@Override
public void destroy() {
}
@Override
public void setErrorStream(OutputStream err) {
_error = new PrintWriter(err);
}
@Override
public void setExitCallback(ExitCallback callback) {
_exitCallback = callback;
}
@Override
public void setInputStream(InputStream in) {
_reader = new BufferedReader(new InputStreamReader(in));
}
@Override
public void setOutputStream(OutputStream out) {
_writer = new PrintWriter(out);
}
@Override
public void start(Environment env) throws IOException {
_userAdminShell.setUser(env.getEnv().get(Environment.ENV_USER));
_adminShellThread = new Thread(this);
_adminShellThread.start();
}
@Override
public void run() {
try {
repl();
} catch (IOException e) {
_logger.warn(e.getMessage());
} finally {
_exitCallback.onExit(0);
}
}
private void repl() throws IOException
{
Ansi.setEnabled(false);
while (true) {
Object error = null;
try {
String str = _reader.readLine();
try {
if (str == null) {
throw new CommandExitException();
}
Object result = _userAdminShell.executeCommand(str);
String s = Strings.toString(result);
if (!s.isEmpty()) {
_writer.println(s);
}
_writer.flush();
} catch (IllegalArgumentException e) {
error = e.toString();
} catch (SerializationException e) {
error =
"There is a bug here, please report to support@dcache.org";
_logger.error("This must be a bug, please report to support@dcache.org.", e);
} catch (CommandSyntaxException e) {
error = e;
} catch (CommandEvaluationException | CommandAclException e) {
error = e.getMessage();
} catch (CommandExitException e) {
break;
} catch (CommandPanicException e) {
error = "Command '" + str + "' triggered a bug (" + e.getTargetException() +
"); the service log file contains additional information. Please " +
"contact support@dcache.org.";
} catch (CommandException e) {
error = e.getMessage();
} catch (NoRouteToCellException e) {
error =
"Cell name does not exist or cell is not started: "
+ e.getMessage();
_logger.warn("The cell the command was sent to is no "
+ "longer there: {}", e.getMessage());
} catch (RuntimeException e) {
error = String.format("Command '%s' triggered a bug (%s); please" +
" locate this message in the log file of the admin service and" +
" send an email to support@dcache.org with this line and the" +
" following stack-trace", str, e);
_logger.error((String) error, e);
}
} catch (InterruptedException e) {
error = null;
} catch (IOException e) {
throw e;
} catch (Exception e) {
error = e.getMessage();
if (error == null) {
error = e.getClass().getSimpleName() + ": (null)";
}
}
if (error != null) {
if (error instanceof CommandSyntaxException) {
CommandSyntaxException e = (CommandSyntaxException) error;
_error.append("Syntax error: ").println(e.getMessage());
} else {
_error.println(error);
}
_error.flush();
}
}
}
}