/* * Copyright (c) 2008 Massimiliano Ziccardi * * Licensed 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 it.jnrpe.server; import it.jnrpe.commands.CCommandInvoker; import it.jnrpe.net.BadCRCException; import it.jnrpe.net.CJNRPERequest; import it.jnrpe.net.CJNRPEResponse; import it.jnrpe.net.IJNRPEConstants; import it.jnrpe.plugins.CReturnValue; import it.jnrpe.utils.CStreamManager; import java.net.*; import java.io.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Thread used to server client request * * @author Massimiliano Ziccardi */ class JNRPEServerThread extends Thread { private Log m_Logger = LogFactory.getLog(JNRPEServerThread.class); private Socket socket = null; private Boolean m_bStopped = Boolean.FALSE; public JNRPEServerThread(Socket socket) { super("JNRPEServerThread"); this.socket = socket; } public CJNRPEResponse handleRequest (CJNRPERequest req) { // extracting command name and params String[] vParts = req.getStringMessage().split("!"); String sCommandName = vParts[0]; String[] vArgs = new String[vParts.length - 1]; System.arraycopy(vParts, 1, vArgs, 0, vArgs.length); CReturnValue ret = CCommandInvoker.invoke(sCommandName, vArgs); CJNRPEResponse res = new CJNRPEResponse(); res.setPacketVersion(IJNRPEConstants.NRPE_PACKET_VERSION_2); res.setResultCode(ret.getReturnCode()); res.setMessage(ret.getMessage()); res.updateCRC(); return res; } public void run() { CStreamManager streamMgr = new CStreamManager(); try { InputStream in = streamMgr.handle(socket.getInputStream()); CJNRPEResponse res = null; CJNRPERequest req = null; try { req = new CJNRPERequest(in); switch (req.getPacketType()) { case IJNRPEConstants.QUERY_PACKET: res = handleRequest(req); break; default: m_Logger.error("UNKNOWN PACKET TYPE " + req.getPacketType()); res = new CJNRPEResponse(); res.setPacketVersion(req.getPacketVersion()); res.setResultCode(IJNRPEConstants.STATE_UNKNOWN); res.setMessage("Invalid Packet Type"); res.updateCRC(); } } catch (BadCRCException e) { m_Logger.error("BAD REQUEST CRC"); res = new CJNRPEResponse(); res.setPacketVersion(IJNRPEConstants.NRPE_PACKET_VERSION_2); res.setResultCode(IJNRPEConstants.STATE_UNKNOWN); res.setMessage("BAD REQUEST CRC"); res.updateCRC(); } synchronized(m_bStopped) { if (!m_bStopped.booleanValue()) { OutputStream out = streamMgr.handle(socket.getOutputStream()); out.write(res.toByteArray()); } } } catch (IOException e) { if (!m_bStopped.booleanValue()) m_Logger.error("ERROR DURING SOCKET OPERATION.", e); } finally { try { if (socket != null && !socket.isClosed()) socket.close(); } catch (IOException e) { m_Logger.error("ERROR CLOSING SOCKET", e); } streamMgr.closeAll(); } } public void stopNow() { CStreamManager streamMgr = new CStreamManager(); try { synchronized (m_bStopped) { // If the socket is closed, the thread has finished... if (!socket.isClosed()) { m_bStopped = Boolean.TRUE; try { CJNRPEResponse res = new CJNRPEResponse(); res.setPacketVersion(IJNRPEConstants.NRPE_PACKET_VERSION_2); res.setResultCode(IJNRPEConstants.STATE_UNKNOWN); res.setMessage("Command execution timeout"); res.updateCRC(); OutputStream out = streamMgr.handle(socket.getOutputStream()); out.write(res.toByteArray()); // This is just to stop any socket operations... socket.close(); } catch (IOException e) { // TODO Auto-generated catch block } // Let's try to interrupt all other operations... if (this.isAlive()) this.interrupt(); // We can exit now.. } } } catch (Exception e) { } finally { streamMgr.closeAll(); } } }