From 8eb42d64ad9ca5f74493220ec2a6c244827a6f7e Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 24 Jul 2017 03:37:32 +0300 Subject: [PATCH] =?UTF-8?q?Zond:=20=D1=83=D0=B1=D0=B8=D0=B9=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D0=BE=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81=D1=81=D0=B0?= =?UTF-8?q?=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20=D1=81=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B5=D0=BC=D0=BD=D1=8B=D0=B9=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zond/build.gradle | 2 + zond/src/main/java/asys/zond/PingMonitor.java | 11 +++- .../java/asys/zond/ZondCommandHandler.java | 7 +- .../java/asys/zond/ZondExecuteWatchdog.java | 54 ++++++++++++++- .../main/java/asys/zond/win32/Kernel32.java | 15 +++++ .../src/main/java/asys/zond/win32/W32API.java | 65 +++++++++++++++++++ .../main/java/asys/zond/win32/W32Errors.java | 23 +++++++ zond/src/main/resources/zond.properties | 4 +- 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 zond/src/main/java/asys/zond/win32/Kernel32.java create mode 100644 zond/src/main/java/asys/zond/win32/W32API.java create mode 100644 zond/src/main/java/asys/zond/win32/W32Errors.java diff --git a/zond/build.gradle b/zond/build.gradle index d2434bd..8efcb3e 100644 --- a/zond/build.gradle +++ b/zond/build.gradle @@ -45,4 +45,6 @@ dependencies { includedEx group: 'org.apache.commons', name: 'commons-exec', version: '1.3' included group: 'io.netty', name: 'netty-codec', version: nettyVersion included group: 'com.google.guava', name: 'guava', version: '21.0' + included group: 'com.sun.jna', name: 'jna', version: '3.0.9' + } diff --git a/zond/src/main/java/asys/zond/PingMonitor.java b/zond/src/main/java/asys/zond/PingMonitor.java index 64999ea..dfde0c7 100644 --- a/zond/src/main/java/asys/zond/PingMonitor.java +++ b/zond/src/main/java/asys/zond/PingMonitor.java @@ -1,5 +1,7 @@ package asys.zond; +import asys.zond.shell.Shell; + public class PingMonitor { private static final long STEP_PING = 5000; private final long delayStart; @@ -22,10 +24,17 @@ public class PingMonitor { while (!Thread.currentThread().isInterrupted()) { long currentTimeMillis = System.currentTimeMillis(); - if ((currentTimeMillis - lastPingTime) >= (2*STEP_PING)) { // если пропущено два пинга + if ((currentTimeMillis - lastPingTime) >= (1*STEP_PING)) { + Shell.getInstance().getOutput().println("[D] lost one ping...."); + } + else if ((currentTimeMillis - lastPingTime) >= (2*STEP_PING)) { // если пропущено два пинга + Shell.getInstance().getOutput().println("[D] lost two ping...."); callback.run(); // запускаем код завершения процесса return; // завершаем поток } + else { + Shell.getInstance().getOutput().println("[D] check ping"); + } try { Thread.sleep(STEP_PING); diff --git a/zond/src/main/java/asys/zond/ZondCommandHandler.java b/zond/src/main/java/asys/zond/ZondCommandHandler.java index a3013d4..b9bc009 100644 --- a/zond/src/main/java/asys/zond/ZondCommandHandler.java +++ b/zond/src/main/java/asys/zond/ZondCommandHandler.java @@ -74,7 +74,12 @@ public class ZondCommandHandler implements CommandHandler { private void startProcess() { if (watchdog == null || !watchdog.isWatching()) { if (watchdog == null) { - watchdog = new ZondExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT, proxyStdIn); + watchdog = new ZondExecuteWatchdog( + ExecuteWatchdog.INFINITE_TIMEOUT, + proxyStdIn, + Config.getInstance().getString("cmdkiller") + ); + executor.setWatchdog(watchdog); } final long delay = Config.getInstance().getLong("pingmonitor.delay"); diff --git a/zond/src/main/java/asys/zond/ZondExecuteWatchdog.java b/zond/src/main/java/asys/zond/ZondExecuteWatchdog.java index fa9d687..5b45216 100644 --- a/zond/src/main/java/asys/zond/ZondExecuteWatchdog.java +++ b/zond/src/main/java/asys/zond/ZondExecuteWatchdog.java @@ -4,19 +4,56 @@ */ package asys.zond; +import asys.zond.shell.Shell; +import asys.zond.win32.Kernel32; +import asys.zond.win32.W32API; +import com.sun.jna.Pointer; import org.apache.commons.exec.ExecuteWatchdog; +import java.io.IOException; +import java.lang.reflect.Field; + public class ZondExecuteWatchdog extends ExecuteWatchdog { private final PipeInputStream inputStream; + private long pid; + private String cmdkiller; - public ZondExecuteWatchdog(long timeout, PipeInputStream inputStream) { + public ZondExecuteWatchdog(long timeout, PipeInputStream inputStream, String cmdkiller) { super(timeout); this.inputStream = inputStream; + this.cmdkiller = cmdkiller.trim(); + } + + private long get_pid(Process process) { + if (process.getClass().getName().equals("java.lang.Win32Process") || + process.getClass().getName().equals("java.lang.ProcessImpl")) { + try { + Field f = process.getClass().getDeclaredField("handle"); + f.setAccessible(true); + long handl = f.getLong(process); + + Kernel32 kernel32 = Kernel32.INSTANCE; + W32API.HANDLE handle = new W32API.HANDLE(); + handle.setPointer(Pointer.createConstant(handl)); + return kernel32.GetProcessId(handle); //pid + } catch (Throwable ignore) { + } + } else if (process.getClass().getName().equals("java.lang.UNIXProcess")) { + try { + Field f = process.getClass().getDeclaredField("pid"); + f.setAccessible(true); + return f.getLong(process); //pid + } catch (Throwable ignore) { + } + } + + return -1; } @Override public synchronized void start(Process processToMonitor) { super.start(processToMonitor); + pid = get_pid(processToMonitor); inputStream.open(); } @@ -25,4 +62,19 @@ public class ZondExecuteWatchdog extends ExecuteWatchdog { super.stop(); inputStream.close(); } + + @Override + public synchronized void destroyProcess() { + super.destroyProcess(); + if (pid != -1 && cmdkiller != null && !cmdkiller.isEmpty()) { + try { + String cmd = cmdkiller.replace("%PID", String.valueOf(pid)); + Shell.getInstance().getOutput().println("CMDKILL: '" + cmd + "'"); + Runtime.getRuntime().exec(cmd); + } catch (IOException ignore) { + } + } else { + Shell.getInstance().getOutput().println("PID = -1"); + } + } } diff --git a/zond/src/main/java/asys/zond/win32/Kernel32.java b/zond/src/main/java/asys/zond/win32/Kernel32.java new file mode 100644 index 0000000..e3dafbe --- /dev/null +++ b/zond/src/main/java/asys/zond/win32/Kernel32.java @@ -0,0 +1,15 @@ +/* + * DmitriyMX + * 2017-07-24 + */ +package asys.zond.win32; + +import com.sun.jna.Native; +/* https://jna.dev.java.net/ */ +public interface Kernel32 extends W32API { + Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, DEFAULT_OPTIONS); + /* http://msdn.microsoft.com/en-us/library/ms683179(VS.85).aspx */ + HANDLE GetCurrentProcess(); + /* http://msdn.microsoft.com/en-us/library/ms683215.aspx */ + int GetProcessId(HANDLE Process); +} diff --git a/zond/src/main/java/asys/zond/win32/W32API.java b/zond/src/main/java/asys/zond/win32/W32API.java new file mode 100644 index 0000000..ad72ea5 --- /dev/null +++ b/zond/src/main/java/asys/zond/win32/W32API.java @@ -0,0 +1,65 @@ +/* Copyright (c) 2007 Timothy Wall, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package asys.zond.win32; + +import java.util.HashMap; +import java.util.Map; + +import com.sun.jna.*; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIFunctionMapper; +import com.sun.jna.win32.W32APITypeMapper; + +/** Base type for most W32 API libraries. Provides standard options + * for unicode/ASCII mappings. Set the system property w32.ascii + * to true to default to the ASCII mappings. + */ +public interface W32API extends StdCallLibrary, W32Errors { + + /** Standard options to use the unicode version of a w32 API. */ + Map UNICODE_OPTIONS = new HashMap() { + { + put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE); + put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE); + } + }; + + /** Standard options to use the ASCII/MBCS version of a w32 API. */ + Map ASCII_OPTIONS = new HashMap() { + { + put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII); + put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII); + } + }; + + Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS; + + class HANDLE extends PointerType { + @Override + public Object fromNative(Object nativeValue, FromNativeContext context) { + Object o = super.fromNative(nativeValue, context); + if (INVALID_HANDLE_VALUE.equals(o)) + return INVALID_HANDLE_VALUE; + return o; + } + } + + /** Constant value representing an invalid HANDLE. */ + HANDLE INVALID_HANDLE_VALUE = new HANDLE() { + { super.setPointer(Pointer.createConstant(-1)); } + @Override + public void setPointer(Pointer p) { + throw new UnsupportedOperationException("Immutable reference"); + } + }; +} diff --git a/zond/src/main/java/asys/zond/win32/W32Errors.java b/zond/src/main/java/asys/zond/win32/W32Errors.java new file mode 100644 index 0000000..ed20a36 --- /dev/null +++ b/zond/src/main/java/asys/zond/win32/W32Errors.java @@ -0,0 +1,23 @@ +/* Copyright (c) 2007 Timothy Wall, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package asys.zond.win32; + +public interface W32Errors { + + int NO_ERROR = 0; + int ERROR_INVALID_FUNCTION = 1; + int ERROR_FILE_NOT_FOUND = 2; + int ERROR_PATH_NOT_FOUND = 3; + +} diff --git a/zond/src/main/resources/zond.properties b/zond/src/main/resources/zond.properties index ce34e16..5a55b66 100644 --- a/zond/src/main/resources/zond.properties +++ b/zond/src/main/resources/zond.properties @@ -3,4 +3,6 @@ host = 127.0.0.1 port = 8779 passcode = testpassphrase bridge.port = 8710 -pingmonitor.delay = 2100 \ No newline at end of file +pingmonitor.delay = 2100 +#cmdkiller = taskkill /F /PID %PID +cmdkiller = kill -KILL %PID \ No newline at end of file