package com.c2kernel.scripting; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.InterruptedIOException; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.StringTokenizer; import org.omg.CORBA.ORB; import org.tanukisoftware.wrapper.WrapperManager; import com.c2kernel.entity.proxy.AgentProxy; import com.c2kernel.entity.proxy.EntityProxyManager; import com.c2kernel.lookup.LDAPLookup; import com.c2kernel.persistency.TransactionManager; import com.c2kernel.process.Gateway; import com.c2kernel.utils.Logger; import com.c2kernel.utils.Resource; import com.c2kernel.utils.server.SocketHandler; import com.ibm.bsf.BSFEngine; import com.ibm.bsf.BSFException; import com.ibm.bsf.BSFManager; /************************************************************************** * * $Revision: 1.16 $ * $Date: 2005/08/31 07:20:40 $ * * Copyright (C) 2003 CERN - European Organization for Nuclear Research * All rights reserved. **************************************************************************/ public class ScriptConsole implements SocketHandler { BufferedReader input; PrintStream output; Socket socket = null; BSFManager manager; BSFEngine context; static ArrayList securityHosts = new ArrayList(); public static final short NONE = 0; public static final short ALLOW = 1; public static final short DENY = 2; static short securityMode; static { securityMode = ALLOW; String hosts = Gateway.getProperty("ItemServer.Console.allow"); if (hosts == null || hosts.equals("")) { securityMode = DENY; hosts = Gateway.getProperty("ItemServer.Console.deny"); } if (hosts == null || hosts.equals("")) { // by default only allow localhost securityMode = ALLOW; securityHosts.add("127.0.0.1"); } else { StringTokenizer tok = new StringTokenizer(hosts, ","); while(tok.hasMoreTokens()) { try { securityHosts.add(InetAddress.getByName(tok.nextToken()).getHostAddress()); } catch (UnknownHostException ex) { Logger.error("Host not found "+ex.getMessage()); } } } } public ScriptConsole() { } @Override public String getName() { return "Script Console"; } @Override public boolean isBusy() { return (socket != null); } @Override public void setSocket(Socket newSocket) { try { input = new BufferedReader(new InputStreamReader(newSocket.getInputStream())); output = new PrintStream(newSocket.getOutputStream()); newSocket.setSoTimeout(0); socket = newSocket; } catch (IOException ex) { try { newSocket.close(); } catch (IOException ex2) { } socket = null; return; } } @Override public void shutdown() { Socket closingSocket = socket; socket = null; if (closingSocket == null) return; try { Logger.removeLogStream(output); closingSocket.shutdownInput(); closingSocket.shutdownOutput(); closingSocket.close(); Logger.msg("Script console to "+closingSocket.getInetAddress()+" closed"); } catch (IOException e) { Logger.error("Script Console to " + closingSocket.getInetAddress() + " - Error closing."); Logger.error(e); } } @Override public void run() { // check permission boolean allowed = true; if (securityMode!=NONE) { if (securityHosts.contains(socket.getInetAddress().getHostAddress())) { if (securityMode==DENY) allowed = false; } else if (securityMode==ALLOW) allowed = false; } if (!allowed) { Logger.error("Host "+socket.getInetAddress()+" access denied"); output.println("Host "+socket.getInetAddress()+" access denied"); shutdown(); return; } // get system objects try { Logger.addLogStream(output, 0); try { manager = new BSFManager(); manager.declareBean("storage", Gateway.getStorage(), TransactionManager.class); manager.declareBean("db", Gateway.getStorage().getDb(), TransactionManager.class); manager.declareBean("proxy", Gateway.getProxyManager(), EntityProxyManager.class); manager.declareBean("lookup", Gateway.getLDAPLookup(), LDAPLookup.class); manager.declareBean("orb", Gateway.getORB(), ORB.class); try { manager.declareBean("system", Gateway.getProxyManager().getProxy( Gateway.getLDAPLookup().getRoleManager().getAgentPath("system")), AgentProxy.class); } catch (Exception ex) { output.println("System agent unavailable"); } context = manager.loadScriptingEngine("javascript"); } catch (BSFException ex) { output.println("Error initialising environment objects"); output.flush(); shutdown(); } StringBuffer commandBuffer = new StringBuffer(); while (socket != null) { output.println(); output.print('>'); String command = null; boolean gotCommand = false; while (!gotCommand) { try { command = input.readLine(); gotCommand = true; } catch (InterruptedIOException ex) { } } if (command == null) // disconnected shutdown(); else { if (command.equals("exit")) { shutdown(); continue; } else if(command.startsWith("log")) { try { int newLogLevel = Integer.parseInt(command.substring(4)); Logger.removeLogStream(output); Logger.addLogStream(output, newLogLevel); Logger.msg("Log level for "+socket.getInetAddress()+" set to "+newLogLevel); continue; } catch (NumberFormatException ex) { } } else if(command.equals("help")) { output.println(Resource.findTextResource("textFiles/consoleHelp.txt")); continue; } else if(command.equals("version")) { output.println("Kernel version: "+Resource.getKernelVersion()); output.println("Modules loaded: "+Gateway.getModuleManager().getModuleVersions()); continue; } try { if (command.endsWith("\\")) { commandBuffer.append(command.substring(0,command.length()-1)); continue; } commandBuffer.append(command); command = commandBuffer.toString(); commandBuffer = new StringBuffer(); Logger.msg("Console command from "+socket.getInetAddress()+": "+command); // process control if (command.equals("shutdown")) { WrapperManager.stop(0); } else { Object response = context.eval("Command", 0, 0, command); if (response instanceof org.mozilla.javascript.Undefined) output.println("Ok"); else output.println(response); } } catch (Throwable ex) { ex.printStackTrace(output); } output.flush(); } } } catch (IOException ex) { Logger.error("IO Exception reading from script console socket"); shutdown(); } } }