mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 09:47:42 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into 7500-prefetchChanges
This commit is contained in:
commit
83c2537ff2
@ -244,7 +244,7 @@
|
|||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
|
||||||
<Component id="memFieldValidationLabel" min="-2" pref="478" max="-2" attributes="0"/>
|
<Component id="memFieldValidationLabel" min="-2" pref="478" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace pref="12" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
@ -255,7 +255,24 @@
|
|||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="restartNecessaryWarning" alignment="0" min="-2" pref="615" max="-2" attributes="0"/>
|
<Group type="102" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="restartNecessaryWarning" alignment="0" min="-2" pref="615" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="heapFileLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="heapFieldValidationLabel" min="-2" pref="478" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="heapDumpFileField" min="-2" pref="415" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="heapDumpBrowseButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
@ -293,7 +310,15 @@
|
|||||||
<Component id="maxLogFileCount" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="maxLogFileCount" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="logFileCount" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="logFileCount" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="heapFileLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="heapDumpFileField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="heapDumpBrowseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="heapFieldValidationLabel" min="-2" pref="16" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="restartNecessaryWarning" min="-2" max="-2" attributes="0"/>
|
<Component id="restartNecessaryWarning" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
@ -414,6 +439,40 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="heapFileLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.heapFileLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextField" name="heapDumpFileField">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.heapDumpFileField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="heapDumpBrowseButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.heapDumpBrowseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="heapDumpBrowseButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="heapFieldValidationLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||||
|
<Color blue="0" green="0" red="ff" type="rgb"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.heapFieldValidationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
<Container class="javax.swing.JPanel" name="tempDirectoryPanel">
|
<Container class="javax.swing.JPanel" name="tempDirectoryPanel">
|
||||||
@ -462,7 +521,7 @@
|
|||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace pref="158" max="32767" attributes="0"/>
|
<EmptySpace pref="164" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
|
@ -29,8 +29,11 @@ import java.nio.file.Path;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.StringJoiner;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
@ -38,7 +41,9 @@ import javax.swing.JOptionPane;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
import javax.swing.event.DocumentListener;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.tools.ant.types.Commandline;
|
||||||
import org.netbeans.spi.options.OptionsPanelController;
|
import org.netbeans.spi.options.OptionsPanelController;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -76,6 +81,7 @@ import org.sleuthkit.autopsy.report.ReportBranding;
|
|||||||
final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final String DEFAULT_HEAP_DUMP_FILE_FIELD = "";
|
||||||
private final JFileChooser logoFileChooser;
|
private final JFileChooser logoFileChooser;
|
||||||
private final JFileChooser tempDirChooser;
|
private final JFileChooser tempDirChooser;
|
||||||
private static final String ETC_FOLDER_NAME = "etc";
|
private static final String ETC_FOLDER_NAME = "etc";
|
||||||
@ -88,6 +94,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
private String initialMemValue = Long.toString(Runtime.getRuntime().maxMemory() / ONE_BILLION);
|
private String initialMemValue = Long.toString(Runtime.getRuntime().maxMemory() / ONE_BILLION);
|
||||||
|
|
||||||
private final ReportBranding reportBranding;
|
private final ReportBranding reportBranding;
|
||||||
|
private final JFileChooser heapFileChooser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the Autopsy options panel.
|
* Instantiate the Autopsy options panel.
|
||||||
@ -103,13 +110,19 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
tempDirChooser = new JFileChooser();
|
tempDirChooser = new JFileChooser();
|
||||||
tempDirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
tempDirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
tempDirChooser.setMultiSelectionEnabled(false);
|
tempDirChooser.setMultiSelectionEnabled(false);
|
||||||
|
|
||||||
|
heapFileChooser = new JFileChooser();
|
||||||
|
heapFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
|
heapFileChooser.setMultiSelectionEnabled(false);
|
||||||
|
|
||||||
if (!PlatformUtil.is64BitJVM() || Version.getBuildType() == Version.Type.DEVELOPMENT) {
|
if (!isJVMHeapSettingsCapable()) {
|
||||||
//32 bit JVM has a max heap size of 1.4 gb to 4 gb depending on OS
|
//32 bit JVM has a max heap size of 1.4 gb to 4 gb depending on OS
|
||||||
//So disabling the setting of heap size when the JVM is not 64 bit
|
//So disabling the setting of heap size when the JVM is not 64 bit
|
||||||
//Is the safest course of action
|
//Is the safest course of action
|
||||||
//And the file won't exist in the install folder when running through netbeans
|
//And the file won't exist in the install folder when running through netbeans
|
||||||
memField.setEnabled(false);
|
memField.setEnabled(false);
|
||||||
|
heapDumpFileField.setEnabled(false);
|
||||||
|
heapDumpBrowseButton.setEnabled(false);
|
||||||
solrMaxHeapSpinner.setEnabled(false);
|
solrMaxHeapSpinner.setEnabled(false);
|
||||||
}
|
}
|
||||||
systemMemoryTotal.setText(Long.toString(getSystemMemoryInGB()));
|
systemMemoryTotal.setText(Long.toString(getSystemMemoryInGB()));
|
||||||
@ -118,13 +131,21 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
solrMaxHeapSpinner.setModel(new javax.swing.SpinnerNumberModel(UserPreferences.getMaxSolrVMSize(),
|
solrMaxHeapSpinner.setModel(new javax.swing.SpinnerNumberModel(UserPreferences.getMaxSolrVMSize(),
|
||||||
JVM_MEMORY_STEP_SIZE_MB, ((int) getSystemMemoryInGB()) * MEGA_IN_GIGA, JVM_MEMORY_STEP_SIZE_MB));
|
JVM_MEMORY_STEP_SIZE_MB, ((int) getSystemMemoryInGB()) * MEGA_IN_GIGA, JVM_MEMORY_STEP_SIZE_MB));
|
||||||
|
|
||||||
TextFieldListener textFieldListener = new TextFieldListener();
|
agencyLogoPathField.getDocument().addDocumentListener(new TextFieldListener(null));
|
||||||
agencyLogoPathField.getDocument().addDocumentListener(textFieldListener);
|
heapDumpFileField.getDocument().addDocumentListener(new TextFieldListener(this::isHeapPathValid));
|
||||||
tempCustomField.getDocument().addDocumentListener(new TempCustomTextListener());
|
tempCustomField.getDocument().addDocumentListener(new TextFieldListener(this::evaluateTempDirState));
|
||||||
logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount()));
|
logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount()));
|
||||||
|
|
||||||
reportBranding = new ReportBranding();
|
reportBranding = new ReportBranding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the jvm runtime heap settings can effectively be changed.
|
||||||
|
* @return Whether or not the jvm runtime heap settings can effectively be changed.
|
||||||
|
*/
|
||||||
|
private static boolean isJVMHeapSettingsCapable() {
|
||||||
|
return PlatformUtil.is64BitJVM() && Version.getBuildType() != Version.Type.DEVELOPMENT;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the total system memory in gigabytes which exists on the machine
|
* Get the total system memory in gigabytes which exists on the machine
|
||||||
@ -140,18 +161,23 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the currently saved max java heap space in gigabytes.
|
* Gets the currently saved max java heap space in gigabytes.
|
||||||
|
* @param The conf file memory value (i.e. 4G).
|
||||||
*
|
*
|
||||||
* @return @throws IOException when unable to get a valid setting
|
* @return The value in gigabytes.
|
||||||
|
* @throws IOException when unable to get a valid setting
|
||||||
*/
|
*/
|
||||||
private long getCurrentJvmMaxMemoryInGB() throws IOException {
|
private long getCurrentJvmMaxMemoryInGB(String confFileMemValue) throws IOException {
|
||||||
String currentXmx = getCurrentXmxValue();
|
|
||||||
char units = '-';
|
char units = '-';
|
||||||
Long value = 0L;
|
Long value = 0L;
|
||||||
if (currentXmx.length() > 1) {
|
if (confFileMemValue.length() > 1) {
|
||||||
units = currentXmx.charAt(currentXmx.length() - 1);
|
units = confFileMemValue.charAt(confFileMemValue.length() - 1);
|
||||||
value = Long.parseLong(currentXmx.substring(0, currentXmx.length() - 1));
|
try {
|
||||||
|
value = Long.parseLong(confFileMemValue.substring(0, confFileMemValue.length() - 1));
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new IOException("Unable to properly parse memory number.", ex);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("No memory setting found in String: " + currentXmx);
|
throw new IOException("No memory setting found in String: " + confFileMemValue);
|
||||||
}
|
}
|
||||||
//some older .conf files might have the units as megabytes instead of gigabytes
|
//some older .conf files might have the units as megabytes instead of gigabytes
|
||||||
switch (units) {
|
switch (units) {
|
||||||
@ -166,33 +192,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The value currently saved in the conf file as the max java heap space
|
|
||||||
* available to this application. Form will be an integer followed by a
|
|
||||||
* character indicating units. Helper method for
|
|
||||||
* getCurrentJvmMaxMemoryInGB()
|
|
||||||
*
|
|
||||||
* @return the saved value for the max java heap space
|
|
||||||
*
|
|
||||||
* @throws IOException if the conf file does not exist in either the user
|
|
||||||
* directory or the install directory
|
|
||||||
*/
|
|
||||||
private String getCurrentXmxValue() throws IOException {
|
|
||||||
String[] settings;
|
|
||||||
String currentSetting = "";
|
|
||||||
File userConfFile = getUserFolderConfFile();
|
|
||||||
if (!userConfFile.exists()) {
|
|
||||||
settings = getDefaultsFromFileContents(readConfFile(getInstallFolderConfFile()));
|
|
||||||
} else {
|
|
||||||
settings = getDefaultsFromFileContents(readConfFile(userConfFile));
|
|
||||||
}
|
|
||||||
for (String option : settings) {
|
|
||||||
if (option.startsWith("-J-Xmx")) {
|
|
||||||
currentSetting = option.replace("-J-Xmx", "").trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currentSetting;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the conf file from the install directory which stores the default
|
* Get the conf file from the install directory which stores the default
|
||||||
@ -229,7 +228,61 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
return new File(userEtcFolder, confFileName);
|
return new File(userEtcFolder, confFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String JVM_SETTINGS_REGEX_PARAM = "options";
|
||||||
|
private static final String JVM_SETTINGS_REGEX_STR = "^\\s*default_options\\s*=\\s*\"?(?<" + JVM_SETTINGS_REGEX_PARAM + ">.+?)\"?\\s*$";
|
||||||
|
private static final Pattern JVM_SETTINGS_REGEX = Pattern.compile(JVM_SETTINGS_REGEX_STR);
|
||||||
|
private static final String XMX_REGEX_PARAM = "mem";
|
||||||
|
private static final String XMX_REGEX_STR = "^\\s*\\-J\\-Xmx(?<" + XMX_REGEX_PARAM + ">.+?)\\s*$";
|
||||||
|
private static final Pattern XMX_REGEX = Pattern.compile(XMX_REGEX_STR);
|
||||||
|
private static final String HEAP_DUMP_REGEX_PARAM = "path";
|
||||||
|
private static final String HEAP_DUMP_REGEX_STR = "^\\s*\\-J\\-XX:HeapDumpPath=(\\\")?\\s*(?<" + HEAP_DUMP_REGEX_PARAM + ">.+?)\\s*(\\\")?$";
|
||||||
|
private static final Pattern HEAP_DUMP_REGEX = Pattern.compile(HEAP_DUMP_REGEX_STR);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the autopsy conf file line. If the line is the default_options line,
|
||||||
|
* then replaces with current memory and heap path value. Otherwise, returns
|
||||||
|
* the line provided as parameter.
|
||||||
|
*
|
||||||
|
* @param line The line.
|
||||||
|
* @param memText The text to add as an argument to be used as memory with -J-Xmx.
|
||||||
|
* @param heapText The text to add as an argument to be used as the heap dump path with
|
||||||
|
* -J-XX:HeapDumpPath.
|
||||||
|
* @return The line modified to contain memory and heap arguments.
|
||||||
|
*/
|
||||||
|
private static String updateConfLine(String line, String memText, String heapText) {
|
||||||
|
Matcher match = JVM_SETTINGS_REGEX.matcher(line);
|
||||||
|
if (match.find()) {
|
||||||
|
// split on command line arguments
|
||||||
|
String[] parsedArgs = Commandline.translateCommandline(match.group(JVM_SETTINGS_REGEX_PARAM));
|
||||||
|
|
||||||
|
String memString = "-J-Xmx" + memText.replaceAll("[^\\d]", "") + "g";
|
||||||
|
|
||||||
|
// only add in heap path argument if a heap path is specified
|
||||||
|
String heapString = null;
|
||||||
|
if (StringUtils.isNotBlank(heapText)) {
|
||||||
|
while (heapText.endsWith("\\") && heapText.length() > 0) {
|
||||||
|
heapText = heapText.substring(0, heapText.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
heapString = String.format("-J-XX:HeapDumpPath=\"%s\"", heapText);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<String> argsNoMemHeap = Stream.of(parsedArgs)
|
||||||
|
// remove saved version of memory and heap dump path
|
||||||
|
.filter(s -> !s.matches(XMX_REGEX_STR) && !s.matches(HEAP_DUMP_REGEX_STR));
|
||||||
|
|
||||||
|
String newArgs = Stream.concat(argsNoMemHeap, Stream.of(memString, heapString))
|
||||||
|
.filter(s -> s != null)
|
||||||
|
.collect(Collectors.joining(" "));
|
||||||
|
|
||||||
|
return String.format("default_options=\"%s\"", newArgs);
|
||||||
|
};
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take the conf file in the install directory and save a copy of it to the
|
* Take the conf file in the install directory and save a copy of it to the
|
||||||
* user directory. The copy will be modified to include the current memory
|
* user directory. The copy will be modified to include the current memory
|
||||||
@ -239,25 +292,124 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
* install folders conf file
|
* install folders conf file
|
||||||
*/
|
*/
|
||||||
private void writeEtcConfFile() throws IOException {
|
private void writeEtcConfFile() throws IOException {
|
||||||
StringBuilder content = new StringBuilder();
|
String fileText = readConfFile(getInstallFolderConfFile()).stream()
|
||||||
List<String> confFile = readConfFile(getInstallFolderConfFile());
|
.map((line) -> updateConfLine(line, memField.getText(), heapDumpFileField.getText()))
|
||||||
for (String line : confFile) {
|
.collect(Collectors.joining("\n"));
|
||||||
if (line.contains("-J-Xmx")) {
|
|
||||||
String[] splitLine = line.split(" ");
|
FileUtils.writeStringToFile(getUserFolderConfFile(), fileText, "UTF-8");
|
||||||
StringJoiner modifiedLine = new StringJoiner(" ");
|
}
|
||||||
for (String piece : splitLine) {
|
|
||||||
if (piece.contains("-J-Xmx")) {
|
|
||||||
piece = "-J-Xmx" + memField.getText() + "g";
|
/**
|
||||||
}
|
* Values for configuration located in the /etc/*.conf file.
|
||||||
modifiedLine.add(piece);
|
*/
|
||||||
}
|
private static class ConfValues {
|
||||||
content.append(modifiedLine.toString());
|
private final String XmxVal;
|
||||||
} else {
|
private final String heapDumpPath;
|
||||||
content.append(line);
|
|
||||||
}
|
/**
|
||||||
content.append("\n");
|
* Main constructor.
|
||||||
|
* @param XmxVal The heap memory size.
|
||||||
|
* @param heapDumpPath The heap dump path.
|
||||||
|
*/
|
||||||
|
ConfValues(String XmxVal, String heapDumpPath) {
|
||||||
|
this.XmxVal = XmxVal;
|
||||||
|
this.heapDumpPath = heapDumpPath;
|
||||||
}
|
}
|
||||||
Files.write(getUserFolderConfFile().toPath(), content.toString().getBytes());
|
|
||||||
|
/**
|
||||||
|
* Returns the heap memory value specified in the conf file.
|
||||||
|
* @return The heap memory value specified in the conf file.
|
||||||
|
*/
|
||||||
|
String getXmxVal() {
|
||||||
|
return XmxVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns path to the heap dump specified in the conf file.
|
||||||
|
* @return Path to the heap dump specified in the conf file.
|
||||||
|
*/
|
||||||
|
String getHeapDumpPath() {
|
||||||
|
return heapDumpPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the /etc/*.conf file values pertinent to settings.
|
||||||
|
* @return The conf file values.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private ConfValues getEtcConfValues() throws IOException {
|
||||||
|
File userConfFile = getUserFolderConfFile();
|
||||||
|
String[] args = userConfFile.exists() ?
|
||||||
|
getDefaultsFromFileContents(readConfFile(userConfFile)) :
|
||||||
|
getDefaultsFromFileContents(readConfFile(getInstallFolderConfFile()));
|
||||||
|
|
||||||
|
String heapFile = "";
|
||||||
|
String memSize = "";
|
||||||
|
|
||||||
|
for (String arg : args) {
|
||||||
|
Matcher memMatch = XMX_REGEX.matcher(arg);
|
||||||
|
if (memMatch.find()) {
|
||||||
|
memSize = memMatch.group(XMX_REGEX_PARAM);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher heapFileMatch = HEAP_DUMP_REGEX.matcher(arg);
|
||||||
|
if (heapFileMatch.find()) {
|
||||||
|
heapFile = heapFileMatch.group(HEAP_DUMP_REGEX_PARAM);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConfValues(memSize, heapFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks current heap path value to see if it is valid, and displays an error message if invalid.
|
||||||
|
* @return True if the heap path is valid.
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"AutopsyOptionsPanel_isHeapPathValid_selectValidDirectory=Please select an existing directory.",
|
||||||
|
"AutopsyOptionsPanel_isHeapPathValid_developerMode=Cannot change heap dump path while in developer mode.",
|
||||||
|
"AutopsyOptionsPanel_isHeapPathValid_not64BitMachine=Changing heap dump path settings only enabled for 64 bit version.",
|
||||||
|
"AutopsyOPtionsPanel_isHeapPathValid_illegalCharacters=Please select a path with no quotes."
|
||||||
|
})
|
||||||
|
private boolean isHeapPathValid() {
|
||||||
|
if (Version.getBuildType() == Version.Type.DEVELOPMENT) {
|
||||||
|
heapFieldValidationLabel.setVisible(true);
|
||||||
|
heapFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_isHeapPathValid_developerMode());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PlatformUtil.is64BitJVM()) {
|
||||||
|
heapFieldValidationLabel.setVisible(true);
|
||||||
|
heapFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_isHeapPathValid_not64BitMachine());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//allow blank field as the default will be used
|
||||||
|
if (StringUtils.isNotBlank(heapDumpFileField.getText())) {
|
||||||
|
String heapText = heapDumpFileField.getText().trim();
|
||||||
|
if (heapText.contains("\"") || heapText.contains("'")) {
|
||||||
|
heapFieldValidationLabel.setVisible(true);
|
||||||
|
heapFieldValidationLabel.setText(Bundle.AutopsyOPtionsPanel_isHeapPathValid_illegalCharacters());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File curHeapFile = new File(heapText);
|
||||||
|
if (!curHeapFile.exists() || !curHeapFile.isDirectory()) {
|
||||||
|
heapFieldValidationLabel.setVisible(true);
|
||||||
|
heapFieldValidationLabel.setText(Bundle.AutopsyOptionsPanel_isHeapPathValid_selectValidDirectory());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heapFieldValidationLabel.setVisible(false);
|
||||||
|
heapFieldValidationLabel.setText("");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,11 +447,17 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
* options is not present.
|
* options is not present.
|
||||||
*/
|
*/
|
||||||
private static String[] getDefaultsFromFileContents(List<String> list) {
|
private static String[] getDefaultsFromFileContents(List<String> list) {
|
||||||
Optional<String> defaultSettings = list.stream().filter(line -> line.startsWith("default_options=")).findFirst();
|
Optional<String> defaultSettings = list.stream()
|
||||||
|
.filter(line -> line.matches(JVM_SETTINGS_REGEX_STR))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
if (defaultSettings.isPresent()) {
|
if (defaultSettings.isPresent()) {
|
||||||
return defaultSettings.get().replace("default_options=", "").replaceAll("\"", "").split(" ");
|
Matcher match = JVM_SETTINGS_REGEX.matcher(defaultSettings.get());
|
||||||
|
if (match.find()) {
|
||||||
|
return Commandline.translateCommandline(match.group(JVM_SETTINGS_REGEX_PARAM));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String[]{};
|
return new String[]{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,15 +505,25 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex);
|
logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex);
|
||||||
}
|
}
|
||||||
if (memField.isEnabled()) {
|
|
||||||
|
boolean confLoaded = false;
|
||||||
|
if (isJVMHeapSettingsCapable()) {
|
||||||
try {
|
try {
|
||||||
initialMemValue = Long.toString(getCurrentJvmMaxMemoryInGB());
|
ConfValues confValues = getEtcConfValues();
|
||||||
|
heapDumpFileField.setText(confValues.getHeapDumpPath());
|
||||||
|
initialMemValue = Long.toString(getCurrentJvmMaxMemoryInGB(confValues.getXmxVal()));
|
||||||
|
confLoaded = true;
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.SEVERE, "Can't read current Jvm max memory setting from file", ex);
|
logger.log(Level.SEVERE, "Can't read current Jvm max memory setting from file", ex);
|
||||||
memField.setEnabled(false);
|
memField.setEnabled(false);
|
||||||
|
heapDumpFileField.setText(DEFAULT_HEAP_DUMP_FILE_FIELD);
|
||||||
}
|
}
|
||||||
memField.setText(initialMemValue);
|
memField.setText(initialMemValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
heapDumpBrowseButton.setEnabled(confLoaded);
|
||||||
|
heapDumpFileField.setEnabled(confLoaded);
|
||||||
|
|
||||||
setTempDirEnabled();
|
setTempDirEnabled();
|
||||||
valid(); //ensure the error messages are up to date
|
valid(); //ensure the error messages are up to date
|
||||||
}
|
}
|
||||||
@ -459,7 +627,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
reportBranding.setAgencyLogoPath("");
|
reportBranding.setAgencyLogoPath("");
|
||||||
}
|
}
|
||||||
UserPreferences.setMaxSolrVMSize((int) solrMaxHeapSpinner.getValue());
|
UserPreferences.setMaxSolrVMSize((int) solrMaxHeapSpinner.getValue());
|
||||||
if (memField.isEnabled()) { //if the field could of been changed we need to try and save it
|
if (isJVMHeapSettingsCapable()) { //if the field could of been changed we need to try and save it
|
||||||
try {
|
try {
|
||||||
writeEtcConfFile();
|
writeEtcConfFile();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@ -474,18 +642,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
* @return True if valid; false otherwise.
|
* @return True if valid; false otherwise.
|
||||||
*/
|
*/
|
||||||
boolean valid() {
|
boolean valid() {
|
||||||
boolean valid = true;
|
boolean agencyValid = isAgencyLogoPathValid();
|
||||||
if (!isAgencyLogoPathValid()) {
|
boolean memFieldValid = isMemFieldValid();
|
||||||
valid = false;
|
boolean logNumValid = isLogNumFieldValid();
|
||||||
}
|
boolean heapPathValid = isHeapPathValid();
|
||||||
if (!isMemFieldValid()) {
|
|
||||||
valid = false;
|
return agencyValid && memFieldValid && logNumValid && heapPathValid;
|
||||||
}
|
|
||||||
if (!isLogNumFieldValid()) {
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -589,47 +751,41 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens for registered text fields that have changed and fires a
|
* Listens for registered text fields that have changed and fires a
|
||||||
* PropertyChangeEvent accordingly.
|
* PropertyChangeEvent accordingly as well as firing an optional additional listener.
|
||||||
*/
|
*/
|
||||||
private class TextFieldListener implements DocumentListener {
|
private class TextFieldListener implements DocumentListener {
|
||||||
|
private final Runnable onChange;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void insertUpdate(DocumentEvent e) {
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
* @param onChange Additional listener for change events.
|
||||||
|
*/
|
||||||
|
TextFieldListener(Runnable onChange) {
|
||||||
|
this.onChange = onChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void baseOnChange() {
|
||||||
|
if (onChange != null) {
|
||||||
|
onChange.run();
|
||||||
|
}
|
||||||
|
|
||||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
baseOnChange();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUpdate(DocumentEvent e) {
|
public void removeUpdate(DocumentEvent e) {
|
||||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
baseOnChange();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changedUpdate(DocumentEvent e) {
|
|
||||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for changes in the temp directory custom directory text field.
|
|
||||||
*/
|
|
||||||
private class TempCustomTextListener extends TextFieldListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changedUpdate(DocumentEvent e) {
|
|
||||||
evaluateTempDirState();
|
|
||||||
super.changedUpdate(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeUpdate(DocumentEvent e) {
|
|
||||||
evaluateTempDirState();
|
|
||||||
super.changedUpdate(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void insertUpdate(DocumentEvent e) {
|
public void insertUpdate(DocumentEvent e) {
|
||||||
evaluateTempDirState();
|
baseOnChange();
|
||||||
super.changedUpdate(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -673,6 +829,10 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
maxMemoryUnitsLabel2 = new javax.swing.JLabel();
|
maxMemoryUnitsLabel2 = new javax.swing.JLabel();
|
||||||
solrMaxHeapSpinner = new javax.swing.JSpinner();
|
solrMaxHeapSpinner = new javax.swing.JSpinner();
|
||||||
solrJVMHeapWarning = new javax.swing.JLabel();
|
solrJVMHeapWarning = new javax.swing.JLabel();
|
||||||
|
heapFileLabel = new javax.swing.JLabel();
|
||||||
|
heapDumpFileField = new javax.swing.JTextField();
|
||||||
|
heapDumpBrowseButton = new javax.swing.JButton();
|
||||||
|
heapFieldValidationLabel = new javax.swing.JLabel();
|
||||||
tempDirectoryPanel = new javax.swing.JPanel();
|
tempDirectoryPanel = new javax.swing.JPanel();
|
||||||
tempCustomField = new javax.swing.JTextField();
|
tempCustomField = new javax.swing.JTextField();
|
||||||
tempDirectoryBrowseButton = new javax.swing.JButton();
|
tempDirectoryBrowseButton = new javax.swing.JButton();
|
||||||
@ -823,6 +983,20 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(solrJVMHeapWarning, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.solrJVMHeapWarning.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(solrJVMHeapWarning, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.solrJVMHeapWarning.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(heapFileLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.heapFileLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
heapDumpFileField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.heapDumpFileField.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(heapDumpBrowseButton, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.heapDumpBrowseButton.text")); // NOI18N
|
||||||
|
heapDumpBrowseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
heapDumpBrowseButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
heapFieldValidationLabel.setForeground(new java.awt.Color(255, 0, 0));
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(heapFieldValidationLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.heapFieldValidationLabel.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout runtimePanelLayout = new javax.swing.GroupLayout(runtimePanel);
|
javax.swing.GroupLayout runtimePanelLayout = new javax.swing.GroupLayout(runtimePanel);
|
||||||
runtimePanel.setLayout(runtimePanelLayout);
|
runtimePanel.setLayout(runtimePanelLayout);
|
||||||
runtimePanelLayout.setHorizontalGroup(
|
runtimePanelLayout.setHorizontalGroup(
|
||||||
@ -851,14 +1025,26 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
.addGroup(runtimePanelLayout.createSequentialGroup()
|
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||||
.addGap(23, 23, 23)
|
.addGap(23, 23, 23)
|
||||||
.addComponent(memFieldValidationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 478, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(memFieldValidationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 478, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addContainerGap(12, Short.MAX_VALUE))
|
||||||
.addGroup(runtimePanelLayout.createSequentialGroup()
|
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||||
.addGap(18, 18, 18)
|
.addGap(18, 18, 18)
|
||||||
.addComponent(solrJVMHeapWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 331, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(solrJVMHeapWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 331, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGap(44, 44, 44)
|
.addGap(44, 44, 44)
|
||||||
.addComponent(logNumAlert)
|
.addComponent(logNumAlert)
|
||||||
.addContainerGap())))
|
.addContainerGap())))
|
||||||
.addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 615, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||||
|
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 615, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||||
|
.addComponent(heapFileLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(heapFieldValidationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 478, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||||
|
.addComponent(heapDumpFileField, javax.swing.GroupLayout.PREFERRED_SIZE, 415, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(heapDumpBrowseButton)))))
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE))))
|
||||||
);
|
);
|
||||||
|
|
||||||
runtimePanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {maxLogFileCount, maxMemoryLabel, totalMemoryLabel});
|
runtimePanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {maxLogFileCount, maxMemoryLabel, totalMemoryLabel});
|
||||||
@ -892,7 +1078,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(maxLogFileCount)
|
.addComponent(maxLogFileCount)
|
||||||
.addComponent(logFileCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(logFileCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(heapFileLabel)
|
||||||
|
.addComponent(heapDumpFileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(heapDumpBrowseButton))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(heapFieldValidationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(restartNecessaryWarning)
|
.addComponent(restartNecessaryWarning)
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
@ -965,7 +1158,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
.addComponent(tempCustomField, javax.swing.GroupLayout.PREFERRED_SIZE, 459, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(tempCustomField, javax.swing.GroupLayout.PREFERRED_SIZE, 459, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(tempDirectoryBrowseButton)))))
|
.addComponent(tempDirectoryBrowseButton)))))
|
||||||
.addContainerGap(158, Short.MAX_VALUE))
|
.addContainerGap(164, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
tempDirectoryPanelLayout.setVerticalGroup(
|
tempDirectoryPanelLayout.setVerticalGroup(
|
||||||
tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
tempDirectoryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -1162,6 +1355,24 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
evaluateTempDirState();
|
evaluateTempDirState();
|
||||||
}//GEN-LAST:event_tempCustomRadioActionPerformed
|
}//GEN-LAST:event_tempCustomRadioActionPerformed
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"AutopsyOptionsPanel_heapDumpBrowseButtonActionPerformed_fileAlreadyExistsTitle=File Already Exists",
|
||||||
|
"AutopsyOptionsPanel_heapDumpBrowseButtonActionPerformed_fileAlreadyExistsMessage=File already exists. Please select a new location."
|
||||||
|
})
|
||||||
|
private void heapDumpBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_heapDumpBrowseButtonActionPerformed
|
||||||
|
String oldHeapPath = heapDumpFileField.getText();
|
||||||
|
if (!StringUtils.isBlank(oldHeapPath)) {
|
||||||
|
heapFileChooser.setCurrentDirectory(new File(oldHeapPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
int returnState = heapFileChooser.showOpenDialog(this);
|
||||||
|
if (returnState == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File selectedDirectory = heapFileChooser.getSelectedFile();
|
||||||
|
heapDumpFileField.setText(selectedDirectory.getAbsolutePath());
|
||||||
|
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_heapDumpBrowseButtonActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JTextField agencyLogoPathField;
|
private javax.swing.JTextField agencyLogoPathField;
|
||||||
private javax.swing.JLabel agencyLogoPathFieldValidationLabel;
|
private javax.swing.JLabel agencyLogoPathFieldValidationLabel;
|
||||||
@ -1170,6 +1381,10 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
|||||||
private javax.swing.JRadioButton defaultLogoRB;
|
private javax.swing.JRadioButton defaultLogoRB;
|
||||||
private javax.swing.ButtonGroup displayTimesButtonGroup;
|
private javax.swing.ButtonGroup displayTimesButtonGroup;
|
||||||
private javax.swing.ButtonGroup fileSelectionButtonGroup;
|
private javax.swing.ButtonGroup fileSelectionButtonGroup;
|
||||||
|
private javax.swing.JButton heapDumpBrowseButton;
|
||||||
|
private javax.swing.JTextField heapDumpFileField;
|
||||||
|
private javax.swing.JLabel heapFieldValidationLabel;
|
||||||
|
private javax.swing.JLabel heapFileLabel;
|
||||||
private javax.swing.JScrollPane jScrollPane1;
|
private javax.swing.JScrollPane jScrollPane1;
|
||||||
private javax.swing.JTextField logFileCount;
|
private javax.swing.JTextField logFileCount;
|
||||||
private javax.swing.JTextField logNumAlert;
|
private javax.swing.JTextField logNumAlert;
|
||||||
|
@ -251,3 +251,7 @@ AutopsyOptionsPanel.tempCaseRadio.text=Temp folder in case directory
|
|||||||
AutopsyOptionsPanel.tempCustomRadio.text=Custom
|
AutopsyOptionsPanel.tempCustomRadio.text=Custom
|
||||||
AutopsyOptionsPanel.tempCustomField.text=
|
AutopsyOptionsPanel.tempCustomField.text=
|
||||||
AutopsyOptionsPanel.tempOnCustomNoPath.text=Please select a path for the custom root temp directory.
|
AutopsyOptionsPanel.tempOnCustomNoPath.text=Please select a path for the custom root temp directory.
|
||||||
|
AutopsyOptionsPanel.heapDumpFileField.text=
|
||||||
|
AutopsyOptionsPanel.heapDumpBrowseButton.text=Browse
|
||||||
|
AutopsyOptionsPanel.heapFileLabel.text=Custom Heap Dump Location:
|
||||||
|
AutopsyOptionsPanel.heapFieldValidationLabel.text=
|
||||||
|
@ -12,6 +12,12 @@ AutopsyOptionsPanel.memFieldValidationLabel.noValueEntered.text=No value entered
|
|||||||
AutopsyOptionsPanel.memFieldValidationLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB
|
AutopsyOptionsPanel.memFieldValidationLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB
|
||||||
# {0} - minimumMemory
|
# {0} - minimumMemory
|
||||||
AutopsyOptionsPanel.memFieldValidationLabel.underMinMemory.text=Value must be at least {0}GB
|
AutopsyOptionsPanel.memFieldValidationLabel.underMinMemory.text=Value must be at least {0}GB
|
||||||
|
AutopsyOptionsPanel_heapDumpBrowseButtonActionPerformed_fileAlreadyExistsMessage=File already exists. Please select a new location.
|
||||||
|
AutopsyOptionsPanel_heapDumpBrowseButtonActionPerformed_fileAlreadyExistsTitle=File Already Exists
|
||||||
|
AutopsyOptionsPanel_isHeapPathValid_developerMode=Cannot change heap dump path while in developer mode.
|
||||||
|
AutopsyOPtionsPanel_isHeapPathValid_illegalCharacters=Please select a path with no quotes.
|
||||||
|
AutopsyOptionsPanel_isHeapPathValid_not64BitMachine=Changing heap dump path settings only enabled for 64 bit version.
|
||||||
|
AutopsyOptionsPanel_isHeapPathValid_selectValidDirectory=Please select an existing directory.
|
||||||
AutopsyOptionsPanel_storeTempDir_onChoiceError_description=There was an error updating temporary directory choice selection.
|
AutopsyOptionsPanel_storeTempDir_onChoiceError_description=There was an error updating temporary directory choice selection.
|
||||||
AutopsyOptionsPanel_storeTempDir_onChoiceError_title=Error Saving Temporary Directory Choice
|
AutopsyOptionsPanel_storeTempDir_onChoiceError_title=Error Saving Temporary Directory Choice
|
||||||
# {0} - path
|
# {0} - path
|
||||||
@ -311,3 +317,7 @@ AutopsyOptionsPanel.tempCaseRadio.text=Temp folder in case directory
|
|||||||
AutopsyOptionsPanel.tempCustomRadio.text=Custom
|
AutopsyOptionsPanel.tempCustomRadio.text=Custom
|
||||||
AutopsyOptionsPanel.tempCustomField.text=
|
AutopsyOptionsPanel.tempCustomField.text=
|
||||||
AutopsyOptionsPanel.tempOnCustomNoPath.text=Please select a path for the custom root temp directory.
|
AutopsyOptionsPanel.tempOnCustomNoPath.text=Please select a path for the custom root temp directory.
|
||||||
|
AutopsyOptionsPanel.heapDumpFileField.text=
|
||||||
|
AutopsyOptionsPanel.heapDumpBrowseButton.text=Browse
|
||||||
|
AutopsyOptionsPanel.heapFileLabel.text=Custom Heap Dump Location:
|
||||||
|
AutopsyOptionsPanel.heapFieldValidationLabel.text=
|
||||||
|
@ -78,13 +78,16 @@ public class HostNode extends DisplayableItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener for handling DATA_SOURCE_ADDED events.
|
* Listener for handling DATA_SOURCE_ADDED / HOST_DELETED events.
|
||||||
|
* A host may have been deleted as part of a merge, which means its data sources could
|
||||||
|
* have moved to a different host requiring a refresh.
|
||||||
*/
|
*/
|
||||||
private final PropertyChangeListener dataSourceAddedPcl = new PropertyChangeListener() {
|
private final PropertyChangeListener dataSourceAddedPcl = new PropertyChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
String eventType = evt.getPropertyName();
|
String eventType = evt.getPropertyName();
|
||||||
if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
|
if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())
|
||||||
|
|| eventType.equals(Case.Events.HOSTS_DELETED.toString())) {
|
||||||
refresh(true);
|
refresh(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,12 +95,12 @@ public class HostNode extends DisplayableItemNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addNotify() {
|
protected void addNotify() {
|
||||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), dataSourceAddedPcl);
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), dataSourceAddedPcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void removeNotify() {
|
protected void removeNotify() {
|
||||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), dataSourceAddedPcl);
|
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.HOSTS_DELETED), dataSourceAddedPcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.machinesettings;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -30,12 +31,15 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
|||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides case-specific settings like the user-specified temp folder.
|
* Provides case-specific settings like the user-specified temp folder.
|
||||||
*/
|
*/
|
||||||
public final class UserMachinePreferences {
|
public final class UserMachinePreferences {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(UserMachinePreferences.class.getName());
|
||||||
private static final Preferences preferences = NbPreferences.forModule(UserMachinePreferences.class);
|
private static final Preferences preferences = NbPreferences.forModule(UserMachinePreferences.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,6 +85,17 @@ public final class UserMachinePreferences {
|
|||||||
|
|
||||||
private static final TempDirChoice DEFAULT_CHOICE = TempDirChoice.SYSTEM;
|
private static final TempDirChoice DEFAULT_CHOICE = TempDirChoice.SYSTEM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this computer's host name to be used as a directory
|
||||||
|
* in some instances.
|
||||||
|
*
|
||||||
|
* @return The name of this computer's host name to be used as a directory
|
||||||
|
* in some instances.
|
||||||
|
*/
|
||||||
|
private static String getHostName() {
|
||||||
|
return NetworkUtils.getLocalHostName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A subdirectory of java.io.tmpdir.
|
* @return A subdirectory of java.io.tmpdir.
|
||||||
*/
|
*/
|
||||||
@ -94,8 +109,16 @@ public final class UserMachinePreferences {
|
|||||||
*/
|
*/
|
||||||
private static File getCaseTempDirFile() {
|
private static File getCaseTempDirFile() {
|
||||||
try {
|
try {
|
||||||
String caseDirStr = Case.getCurrentCaseThrows().getCaseDirectory();
|
Case autCase = Case.getCurrentCaseThrows();
|
||||||
return Paths.get(caseDirStr, CASE_SUBDIR).toFile();
|
String caseDirStr = autCase.getCaseDirectory();
|
||||||
|
switch (autCase.getCaseType()) {
|
||||||
|
case MULTI_USER_CASE: return Paths.get(caseDirStr, getHostName(), CASE_SUBDIR).toFile();
|
||||||
|
case SINGLE_USER_CASE: return Paths.get(caseDirStr, CASE_SUBDIR).toFile();
|
||||||
|
default:
|
||||||
|
logger.log(Level.SEVERE, "Unknown case type: " + autCase.getCaseType());
|
||||||
|
return getSystemTempDirFile();
|
||||||
|
}
|
||||||
|
|
||||||
} catch (NoCurrentCaseException ex) {
|
} catch (NoCurrentCaseException ex) {
|
||||||
return getSystemTempDirFile();
|
return getSystemTempDirFile();
|
||||||
}
|
}
|
||||||
@ -111,7 +134,7 @@ public final class UserMachinePreferences {
|
|||||||
private static File getCustomTempDirFile() {
|
private static File getCustomTempDirFile() {
|
||||||
String customDirectory = getCustomTempDirectory();
|
String customDirectory = getCustomTempDirectory();
|
||||||
return (StringUtils.isBlank(customDirectory))
|
return (StringUtils.isBlank(customDirectory))
|
||||||
? getSystemTempDirFile() : Paths.get(customDirectory, AUTOPSY_SUBDIR).toFile();
|
? getSystemTempDirFile() : Paths.get(customDirectory, AUTOPSY_SUBDIR, getHostName()).toFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,8 +237,9 @@ public final class UserMachinePreferences {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the temp directory choice (i.e. system, case, custom).
|
* Sets the temp directory choice (i.e. system, case, custom).
|
||||||
|
*
|
||||||
* @param tempDirChoice The choice (must be non-null).
|
* @param tempDirChoice The choice (must be non-null).
|
||||||
* @throws UserMachinePreferencesException
|
* @throws UserMachinePreferencesException
|
||||||
*/
|
*/
|
||||||
public static void setTempDirChoice(TempDirChoice tempDirChoice) throws UserMachinePreferencesException {
|
public static void setTempDirChoice(TempDirChoice tempDirChoice) throws UserMachinePreferencesException {
|
||||||
if (tempDirChoice == null) {
|
if (tempDirChoice == null) {
|
||||||
|
@ -120,23 +120,21 @@ public class CentralRepoAccountsTest extends TestCase {
|
|||||||
public void testRejectionOfDeviceAccountType() {
|
public void testRejectionOfDeviceAccountType() {
|
||||||
try {
|
try {
|
||||||
Account.Type deviceAccount = Account.Type.DEVICE;
|
Account.Type deviceAccount = Account.Type.DEVICE;
|
||||||
CentralRepository.getInstance()
|
Optional<CentralRepoAccountType> optType = CentralRepository.getInstance()
|
||||||
.getAccountTypeByName(deviceAccount.getTypeName());
|
.getAccountTypeByName(deviceAccount.getTypeName());
|
||||||
Assert.fail("Expected an exception from getAccountTypeByName() when"
|
Assert.assertFalse(optType.isPresent());
|
||||||
+ " querying the device account type");
|
|
||||||
} catch (CentralRepoException ex) {
|
} catch (CentralRepoException ex) {
|
||||||
// Pass
|
Assert.fail("Didn't expect an exception here. Exception: " + ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNonExistentAccountType() {
|
public void testNonExistentAccountType() {
|
||||||
try {
|
try {
|
||||||
CentralRepository.getInstance()
|
Optional<CentralRepoAccountType> optType = CentralRepository.getInstance()
|
||||||
.getAccountTypeByName("NotARealAccountType");
|
.getAccountTypeByName("NotARealAccountType");
|
||||||
Assert.fail("Expected an exception from getAccountTypeByName()"
|
Assert.assertFalse(optType.isPresent());
|
||||||
+ " when querying a non-existent account type");
|
|
||||||
} catch (CentralRepoException ex) {
|
} catch (CentralRepoException ex) {
|
||||||
// Pass
|
Assert.fail("Didn't expect an exception here. Exception: " + ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user