From c40b7ef986e26b961dc51aeb4fa8bc9e168d0517 Mon Sep 17 00:00:00 2001 From: adam-m Date: Mon, 20 May 2013 12:49:29 -0400 Subject: [PATCH] Rename JavaSystemCaller to ExecUtil. Make thread-safe / non-static --- .../{JavaSystemCaller.java => ExecUtil.java} | 170 +++++++++--------- .../autopsy/recentactivity/ExtractIE.java | 11 +- .../recentactivity/ExtractRegistry.java | 10 +- .../sleuthkit/autopsy/timeline/Timeline.java | 5 +- 4 files changed, 105 insertions(+), 91 deletions(-) rename RecentActivity/src/org/sleuthkit/autopsy/recentactivity/{JavaSystemCaller.java => ExecUtil.java} (65%) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/JavaSystemCaller.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExecUtil.java similarity index 65% rename from RecentActivity/src/org/sleuthkit/autopsy/recentactivity/JavaSystemCaller.java rename to RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExecUtil.java index 8f6e970281..87199e83b6 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/JavaSystemCaller.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExecUtil.java @@ -30,7 +30,93 @@ import org.sleuthkit.autopsy.coreutils.Logger; * Takes of forking a process and reading output / error streams to either a * string buffer or directly to a file writer */ -public final class JavaSystemCaller { +public final class ExecUtil { + + private static final Logger logger = Logger.getLogger(ExecUtil.class.getName()); + private Process proc = null; + private String command = null; + private ExecUtil.StreamToStringRedirect errorRedirect = null; + private ExecUtil.StreamToStringRedirect outputRedirect = null; + + /** + * Execute a process. Redirect asynchronously stdout to a string and stderr + * to nowhere. + * + * @param aCommand command to be executed + * @param params parameters of the command + * @return string buffer with captured stdout + */ + public synchronized String execute(final String aCommand, final String... params) throws IOException, InterruptedException { + String output = ""; + + // build command array + String[] arrayCommand = new String[params.length + 1]; + arrayCommand[0] = aCommand; + + StringBuilder arrayCommandToLog = new StringBuilder(); + arrayCommandToLog.append(aCommand).append(" "); + + for (int i = 1; i < arrayCommand.length; i++) { + arrayCommand[i] = params[i - 1]; + arrayCommandToLog.append(arrayCommand[i]).append(" "); + } + + final Runtime rt = Runtime.getRuntime(); + logger.log(Level.INFO, "Executing " + arrayCommandToLog.toString()); + + proc = rt.exec(arrayCommand); + try { + //give time to fully start the process + Thread.sleep(2000); + } catch (InterruptedException ex) { + logger.log(Level.WARNING, "Pause interrupted", ex); + } + + //stderr redirect + errorRedirect = new ExecUtil.StreamToStringRedirect(proc.getErrorStream(), "ERROR"); + //stdout redirect + outputRedirect = new ExecUtil.StreamToStringRedirect(proc.getInputStream(), "OUTPUT"); + + //start redurectors + errorRedirect.start(); + outputRedirect.start(); + + //wait for process to complete and capture error core + final int exitVal = proc.waitFor(); + logger.log(Level.INFO, aCommand + " exit value: " + exitVal); + + errorRedirect.stopRun(); + errorRedirect = null; + + outputRedirect.stopRun(); + output = outputRedirect.getOutput(); + + outputRedirect = null; + + //gc process with its streams + proc = null; + + return output; + } + + public synchronized void stop() { + logger.log(Level.INFO, "Stopping Execution of: " + command); + + if (errorRedirect != null) { + errorRedirect.stopRun(); + errorRedirect = null; + } + + if (outputRedirect != null) { + outputRedirect.stopRun(); + outputRedirect = null; + } + + if (proc != null) { + proc.destroy(); + proc = null; + } + } /** * Asynchronously read the output of a given input stream and write to a @@ -146,86 +232,4 @@ public final class JavaSystemCaller { doRun = false; } } - - - - public static final class Exec { - - private static final Logger logger = Logger.getLogger(Exec.class.getName()); - private static Process proc = null; - private static String command = null; - - /** - * Execute a process. Redirect asynchronously stdout to a string and - * stderr to nowhere. - * - * @param aCommand command to be executed - * @param params parameters of the command - * @return string buffer with captured stdout - */ - public static String execute(final String aCommand, final String... params) throws IOException, InterruptedException { - String output = ""; - - // build command array - String[] arrayCommand = new String[params.length + 1]; - arrayCommand[0] = aCommand; - - StringBuilder arrayCommandToLog = new StringBuilder(); - arrayCommandToLog.append(aCommand).append(" "); - - for (int i = 1; i < arrayCommand.length; i++) { - arrayCommand[i] = params[i - 1]; - arrayCommandToLog.append(arrayCommand[i]).append(" "); - } - - final Runtime rt = Runtime.getRuntime(); - logger.log(Level.INFO, "Executing " + arrayCommandToLog.toString()); - - proc = rt.exec(arrayCommand); - try { - //give time to fully start the process - Thread.sleep(2000); - } catch (InterruptedException ex) { - logger.log(Level.WARNING, "Pause interrupted", ex); - } - - //stderr redirect - final JavaSystemCaller.StreamToStringRedirect errorRedirect = new JavaSystemCaller.StreamToStringRedirect(proc.getErrorStream(), "ERROR"); - //stdout redirect - final JavaSystemCaller.StreamToStringRedirect outputRedirect = new JavaSystemCaller.StreamToStringRedirect(proc.getInputStream(), "OUTPUT"); - - //start redurectors - errorRedirect.start(); - outputRedirect.start(); - - //wait for process to complete and capture error core - final int exitVal = proc.waitFor(); - logger.log(Level.INFO, aCommand + " exit value: " + exitVal); - - errorRedirect.stopRun(); - outputRedirect.stopRun(); - - output = outputRedirect.getOutput(); - - //gc process with its streams - proc = null; - - return output; - } - - public static synchronized void stop() { - logger.log(Level.INFO, "Stopping Execution of: " + command); - - if (proc != null) { - proc.destroy(); - proc = null; - } - } - - public static Process getProcess() { - return proc; - } - } - - private JavaSystemCaller() { } } \ No newline at end of file diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java index 3da9b20e00..446f4a3cc0 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java @@ -95,6 +95,8 @@ public class ExtractIE extends Extract implements IngestModuleImage { final public static String MODULE_VERSION = "1.0"; private String args; private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + + private ExecUtil execPasco; //hide public constructor to prevent from instantiation by ingest module loader ExtractIE() { @@ -401,7 +403,8 @@ public class ExtractIE extends Extract implements IngestModuleImage { command.append(" > \"").append(PASCO_RESULTS_PATH).append("\\" + filename + "\""); // command.add(" > " + "\"" + PASCO_RESULTS_PATH + File.separator + Long.toString(bbId) + "\""); String cmd = command.toString(); - JavaSystemCaller.Exec.execute("\"" + JAVA_PATH + " " + cmd + "\""); + execPasco = new ExecUtil(); + execPasco.execute("\"" + JAVA_PATH + " " + cmd + "\""); } catch (IOException ex) { success = false; @@ -571,9 +574,11 @@ public class ExtractIE extends Extract implements IngestModuleImage { @Override public void stop() { - if (JavaSystemCaller.Exec.getProcess() != null) { - JavaSystemCaller.Exec.stop(); + if (execPasco != null) { + execPasco.stop(); + execPasco = null; } + //call regular cleanup from complete() method complete(); diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 8edf598105..175e4e4df0 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -66,6 +66,7 @@ public class ExtractRegistry extends Extract implements IngestModuleImage { private IngestServices services; final public static String MODULE_VERSION = "1.0"; private String args; + private ExecUtil execRR; //hide public constructor to prevent from instantiation by ingest module loader ExtractRegistry() { @@ -184,7 +185,8 @@ public class ExtractRegistry extends Extract implements IngestModuleImage { type = "1security"; } String command = "\"" + RR_PATH + "\" -r \"" + regFilePath + "\" -f " + type + " > \"" + txtPath + "\" 2> NUL"; - JavaSystemCaller.Exec.execute("\"" + command + "\""); + execRR = new ExecUtil(); + execRR.execute("\"" + command + "\""); } catch (IOException ex) { logger.log(Level.SEVERE, "Unable to RegRipper and process parse some registry files.", ex); @@ -405,9 +407,11 @@ public class ExtractRegistry extends Extract implements IngestModuleImage { @Override public void stop() { - if (JavaSystemCaller.Exec.getProcess() != null) { - JavaSystemCaller.Exec.stop(); + if (execRR != null) { + execRR.stop(); + execRR = null; } + } @Override diff --git a/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java b/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java index 783569664b..7e8c25fb5e 100644 --- a/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java +++ b/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java @@ -96,7 +96,7 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.ingest.IngestManager; -import org.sleuthkit.autopsy.recentactivity.JavaSystemCaller; +import org.sleuthkit.autopsy.recentactivity.ExecUtil; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.File; @@ -1019,9 +1019,10 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar, String[] mactimeArgs = new String[]{"-b", pathToBodyFile, "-d", "-y"}; String output = ""; + ExecUtil execUtil = new ExecUtil(); try { //JavaSystemCaller.Exec.execute("\"" + command + "\""); - output = JavaSystemCaller.Exec.execute(macpath, mactimeArgs); + output = execUtil.execute(macpath, mactimeArgs); } catch (InterruptedException ie) { logger.log(Level.WARNING, "Mactime process was interrupted by user", ie); return null;