Rename JavaSystemCaller to ExecUtil. Make thread-safe / non-static

This commit is contained in:
adam-m 2013-05-20 12:49:29 -04:00
parent af77304fb0
commit c40b7ef986
4 changed files with 105 additions and 91 deletions

View File

@ -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() { }
}

View File

@ -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();

View File

@ -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

View File

@ -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;