mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-10-02 16:33:49 +00:00
GP-1164: Reorganizing Ghidra's user settings/cache/temp directories to support XDG
This commit is contained in:
parent
8bfcb02166
commit
3c30ada14c
|
@ -75,6 +75,9 @@ public class GhidraRun implements GhidraLaunchable {
|
||||||
|
|
||||||
log = LogManager.getLogger(GhidraRun.class);
|
log = LogManager.getLogger(GhidraRun.class);
|
||||||
log.info("User " + SystemUtilities.getUserName() + " started Ghidra.");
|
log.info("User " + SystemUtilities.getUserName() + " started Ghidra.");
|
||||||
|
log.info("User settings directory: " + Application.getUserSettingsDirectory());
|
||||||
|
log.info("User temp directory: " + Application.getUserTempDirectory());
|
||||||
|
log.info("User cache directory: " + Application.getUserCacheDirectory());
|
||||||
|
|
||||||
initializeTooltips();
|
initializeTooltips();
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ import ghidra.app.context.*;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
import ghidra.app.plugin.ProgramPlugin;
|
import ghidra.app.plugin.ProgramPlugin;
|
||||||
import ghidra.app.services.GoToService;
|
import ghidra.app.services.GoToService;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.plugintool.PluginInfo;
|
import ghidra.framework.plugintool.PluginInfo;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.plugintool.util.PluginStatus;
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
|
@ -190,7 +191,7 @@ public class ShowInstructionInfoPlugin extends ProgramPlugin {
|
||||||
private File writeWrapperFile(URL fileURL) throws IOException {
|
private File writeWrapperFile(URL fileURL) throws IOException {
|
||||||
File f;
|
File f;
|
||||||
if (manualWrapperFiles.size() < MAX_MANUAL_WRAPPER_FILE_COUNT) {
|
if (manualWrapperFiles.size() < MAX_MANUAL_WRAPPER_FILE_COUNT) {
|
||||||
f = File.createTempFile("pdfView", ".html");
|
f = Application.createTempFile("pdfView", ".html");
|
||||||
f.deleteOnExit();
|
f.deleteOnExit();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import generic.theme.GThemeDefaults.Colors;
|
||||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||||
import ghidra.app.services.DataTypeManagerService;
|
import ghidra.app.services.DataTypeManagerService;
|
||||||
import ghidra.app.util.cparser.CPP.PreProcessor;
|
import ghidra.app.util.cparser.CPP.PreProcessor;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.framework.store.LockException;
|
import ghidra.framework.store.LockException;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
@ -535,7 +536,7 @@ public class CParserUtils {
|
||||||
String fName = dtMgr.getName();
|
String fName = dtMgr.getName();
|
||||||
|
|
||||||
// make a path to tmpdir with name of data type manager
|
// make a path to tmpdir with name of data type manager
|
||||||
String path = System.getProperty("java.io.tmpdir") + File.pathSeparator + fName;
|
String path = new File(Application.getUserTempDirectory(), fName).getAbsolutePath();
|
||||||
// if file data type manager, use path to .gdt file
|
// if file data type manager, use path to .gdt file
|
||||||
if (dtMgr instanceof FileDataTypeManager) {
|
if (dtMgr instanceof FileDataTypeManager) {
|
||||||
path = ((FileDataTypeManager) dtMgr).getPath();
|
path = ((FileDataTypeManager) dtMgr).getPath();
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.util.*;
|
import ghidra.app.util.*;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.model.DomainObject;
|
import ghidra.framework.model.DomainObject;
|
||||||
import ghidra.program.database.mem.AddressSourceInfo;
|
import ghidra.program.database.mem.AddressSourceInfo;
|
||||||
import ghidra.program.database.mem.FileBytes;
|
import ghidra.program.database.mem.FileBytes;
|
||||||
|
@ -166,7 +167,7 @@ public class OriginalFileExporter extends Exporter {
|
||||||
// Write source program's file bytes to a temp file.
|
// Write source program's file bytes to a temp file.
|
||||||
// This is done to ensure a random access write failure doesn't corrupt a file the user
|
// This is done to ensure a random access write failure doesn't corrupt a file the user
|
||||||
// might be overwriting.
|
// might be overwriting.
|
||||||
File tempFile = File.createTempFile("ghidra_export_", null);
|
File tempFile = Application.createTempFile("ghidra_export_", null);
|
||||||
try (OutputStream out = new FileOutputStream(tempFile, false)) {
|
try (OutputStream out = new FileOutputStream(tempFile, false)) {
|
||||||
FileUtilities.copyStreamToStream(new FileBytesInputStream(fileBytes, true), out,
|
FileUtilities.copyStreamToStream(new FileBytesInputStream(fileBytes, true), out,
|
||||||
monitor);
|
monitor);
|
||||||
|
|
|
@ -36,6 +36,7 @@ import ghidra.app.util.bin.format.elf.extend.ElfLoadAdapter;
|
||||||
import ghidra.app.util.bin.format.elf.info.ElfInfoProducer;
|
import ghidra.app.util.bin.format.elf.info.ElfInfoProducer;
|
||||||
import ghidra.app.util.bin.format.elf.relocation.*;
|
import ghidra.app.util.bin.format.elf.relocation.*;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.framework.store.LockException;
|
import ghidra.framework.store.LockException;
|
||||||
import ghidra.program.database.mem.FileBytes;
|
import ghidra.program.database.mem.FileBytes;
|
||||||
|
@ -1606,7 +1607,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||||
Address debugDataAddr = findLoadAddress(debugDataSection, 0);
|
Address debugDataAddr = findLoadAddress(debugDataSection, 0);
|
||||||
if (debugDataAddr != null) {
|
if (debugDataAddr != null) {
|
||||||
try {
|
try {
|
||||||
File tmpFile = File.createTempFile("ghidra_gnu_debugdata", null);
|
File tmpFile = Application.createTempFile("ghidra_gnu_debugdata", null);
|
||||||
try (ByteProviderWrapper compressedDebugDataBP = new ByteProviderWrapper(
|
try (ByteProviderWrapper compressedDebugDataBP = new ByteProviderWrapper(
|
||||||
new MemoryByteProvider(memory, debugDataAddr), 0, debugDataSection.getSize());
|
new MemoryByteProvider(memory, debugDataAddr), 0, debugDataSection.getSize());
|
||||||
XZCompressorInputStream xzIS =
|
XZCompressorInputStream xzIS =
|
||||||
|
|
|
@ -25,6 +25,7 @@ import db.DBHandle;
|
||||||
import ghidra.app.util.Option;
|
import ghidra.app.util.Option;
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.model.DomainObject;
|
import ghidra.framework.model.DomainObject;
|
||||||
import ghidra.framework.model.Project;
|
import ghidra.framework.model.Project;
|
||||||
import ghidra.framework.store.db.PackedDatabase;
|
import ghidra.framework.store.db.PackedDatabase;
|
||||||
|
@ -138,7 +139,7 @@ public class GdtLoader implements Loader {
|
||||||
|
|
||||||
private static File createTmpFile(ByteProvider provider, TaskMonitor monitor)
|
private static File createTmpFile(ByteProvider provider, TaskMonitor monitor)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
File tmpFile = File.createTempFile("ghidra_gdt_loader", null);
|
File tmpFile = Application.createTempFile("ghidra_gdt_loader", null);
|
||||||
try (InputStream is = provider.getInputStream(0);
|
try (InputStream is = provider.getInputStream(0);
|
||||||
FileOutputStream fos = new FileOutputStream(tmpFile)) {
|
FileOutputStream fos = new FileOutputStream(tmpFile)) {
|
||||||
FileUtilities.copyStreamToStream(is, fos, monitor);
|
FileUtilities.copyStreamToStream(is, fos, monitor);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import db.DBHandle;
|
||||||
import ghidra.app.util.Option;
|
import ghidra.app.util.Option;
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.model.DomainObject;
|
import ghidra.framework.model.DomainObject;
|
||||||
import ghidra.framework.model.Project;
|
import ghidra.framework.model.Project;
|
||||||
import ghidra.framework.store.db.PackedDatabase;
|
import ghidra.framework.store.db.PackedDatabase;
|
||||||
|
@ -148,7 +149,7 @@ public class GzfLoader implements Loader {
|
||||||
|
|
||||||
private static File createTmpFile(ByteProvider provider, TaskMonitor monitor)
|
private static File createTmpFile(ByteProvider provider, TaskMonitor monitor)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
File tmpFile = File.createTempFile("ghidra_gzf_loader", null);
|
File tmpFile = Application.createTempFile("ghidra_gzf_loader", null);
|
||||||
try (InputStream is = provider.getInputStream(0);
|
try (InputStream is = provider.getInputStream(0);
|
||||||
FileOutputStream fos = new FileOutputStream(tmpFile)) {
|
FileOutputStream fos = new FileOutputStream(tmpFile)) {
|
||||||
FileUtilities.copyStreamToStream(is, fos, monitor);
|
FileUtilities.copyStreamToStream(is, fos, monitor);
|
||||||
|
|
|
@ -577,7 +577,7 @@ public class FileSystemService {
|
||||||
public File createPlaintextTempFile(ByteProvider provider, String filenamePrefix,
|
public File createPlaintextTempFile(ByteProvider provider, String filenamePrefix,
|
||||||
TaskMonitor monitor) throws IOException {
|
TaskMonitor monitor) throws IOException {
|
||||||
File tmpFile =
|
File tmpFile =
|
||||||
File.createTempFile(filenamePrefix, Long.toString(System.currentTimeMillis()));
|
Application.createTempFile(filenamePrefix, Long.toString(System.currentTimeMillis()));
|
||||||
monitor.setMessage("Copying " + provider.getName() + " to temp file");
|
monitor.setMessage("Copying " + provider.getName() + " to temp file");
|
||||||
monitor.initialize(provider.length());
|
monitor.initialize(provider.length());
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.CryptoException;
|
import ghidra.util.exception.CryptoException;
|
||||||
|
@ -138,7 +139,7 @@ public abstract class GFileSystemBase implements GFileSystem {
|
||||||
protected void debug(byte[] bytes, String fileName) {
|
protected void debug(byte[] bytes, String fileName) {
|
||||||
try {
|
try {
|
||||||
if (SystemUtilities.isInDevelopmentMode()) {
|
if (SystemUtilities.isInDevelopmentMode()) {
|
||||||
File file = File.createTempFile(fileName, ".ghidra.tmp");
|
File file = Application.createTempFile(fileName, ".ghidra.tmp");
|
||||||
OutputStream out = new FileOutputStream(file);
|
OutputStream out = new FileOutputStream(file);
|
||||||
try {
|
try {
|
||||||
out.write(bytes);
|
out.write(bytes);
|
||||||
|
|
|
@ -28,8 +28,7 @@ import ghidra.app.util.importer.AutoImporter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.app.util.opinion.LoadException;
|
import ghidra.app.util.opinion.LoadException;
|
||||||
import ghidra.app.util.opinion.LoadResults;
|
import ghidra.app.util.opinion.LoadResults;
|
||||||
import ghidra.framework.Application;
|
import ghidra.framework.*;
|
||||||
import ghidra.framework.HeadlessGhidraApplicationConfiguration;
|
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
|
@ -38,6 +37,7 @@ import ghidra.program.util.DefaultLanguageService;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import utility.application.ApplicationLayout;
|
import utility.application.ApplicationLayout;
|
||||||
|
import utility.application.ApplicationUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for Ghidra code to find images (and maybe other artifacts later) in a program
|
* Wrapper for Ghidra code to find images (and maybe other artifacts later) in a program
|
||||||
|
@ -122,8 +122,9 @@ public class ProgramExaminer {
|
||||||
if (!Application.isInitialized()) {
|
if (!Application.isInitialized()) {
|
||||||
ApplicationLayout layout;
|
ApplicationLayout layout;
|
||||||
try {
|
try {
|
||||||
layout =
|
layout = new GhidraTestApplicationLayout(ApplicationUtilities.getDefaultUserTempDir(
|
||||||
new GhidraTestApplicationLayout(new File(System.getProperty("java.io.tmpdir")));
|
new ApplicationProperties(ApplicationUtilities.findDefaultApplicationRootDirs())
|
||||||
|
.getApplicationName()));
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new GhidraException(e);
|
throw new GhidraException(e);
|
||||||
|
@ -184,8 +185,7 @@ public class ProgramExaminer {
|
||||||
int txID = program.startTransaction("find images");
|
int txID = program.startTransaction("find images");
|
||||||
try {
|
try {
|
||||||
EmbeddedMediaAnalyzer imageAnalyzer = new EmbeddedMediaAnalyzer();
|
EmbeddedMediaAnalyzer imageAnalyzer = new EmbeddedMediaAnalyzer();
|
||||||
imageAnalyzer.added(program, program.getMemory(), TaskMonitor.DUMMY,
|
imageAnalyzer.added(program, program.getMemory(), TaskMonitor.DUMMY, messageLog);
|
||||||
messageLog);
|
|
||||||
}
|
}
|
||||||
catch (CancelledException e) {
|
catch (CancelledException e) {
|
||||||
// using Dummy, can't happen
|
// using Dummy, can't happen
|
||||||
|
|
|
@ -428,7 +428,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
||||||
// return; // already enabled by batch test environment
|
// return; // already enabled by batch test environment
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// String tmpDir = System.getProperty("java.io.tmpdir");
|
// File tmpDir = Application.getUserTempDirectory();
|
||||||
// File cacheDir = new File(tmpDir, "EmulatorDBTestCache");
|
// File cacheDir = new File(tmpDir, "EmulatorDBTestCache");
|
||||||
// if (cacheDir.exists() && !FileUtilities.deleteDir(cacheDir)) {
|
// if (cacheDir.exists() && !FileUtilities.deleteDir(cacheDir)) {
|
||||||
// Msg.warn(ProcessorEmulatorTestAdapter.class,
|
// Msg.warn(ProcessorEmulatorTestAdapter.class,
|
||||||
|
|
|
@ -704,7 +704,7 @@ public class GhidraJarBuilder implements GhidraLaunchable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
File tempFile = File.createTempFile("jarBuilder", "treeIDX");
|
File tempFile = Application.createTempFile("jarBuilder", "treeIDX");
|
||||||
classTree.trim();
|
classTree.trim();
|
||||||
classTree.saveFile(tempFile);
|
classTree.saveFile(tempFile);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -54,6 +54,7 @@ import ghidra.app.plugin.core.datamgr.tree.DataTypeNode;
|
||||||
import ghidra.app.plugin.core.datamgr.util.DataTypeChooserDialog;
|
import ghidra.app.plugin.core.datamgr.util.DataTypeChooserDialog;
|
||||||
import ghidra.app.services.DataTypeManagerService;
|
import ghidra.app.services.DataTypeManagerService;
|
||||||
import ghidra.app.services.ProgramManager;
|
import ghidra.app.services.ProgramManager;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.database.data.ProgramDataTypeManager;
|
import ghidra.program.database.data.ProgramDataTypeManager;
|
||||||
|
@ -723,7 +724,7 @@ public class DataTypeSelectionDialogTest extends AbstractGhidraHeadedIntegration
|
||||||
DataTypeManagerHandler dataTypeManagerHandler = plugin.getDataTypeManagerHandler();
|
DataTypeManagerHandler dataTypeManagerHandler = plugin.getDataTypeManagerHandler();
|
||||||
File tempArchiveFile;
|
File tempArchiveFile;
|
||||||
try {
|
try {
|
||||||
tempArchiveFile = File.createTempFile("TestFileArchive", ".gdt");
|
tempArchiveFile = Application.createTempFile("TestFileArchive", ".gdt");
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
package db;
|
package db;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -240,7 +241,7 @@ public class DbViewer extends JFrame {
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws FileNotFoundException {
|
public static void main(String[] args) throws IOException {
|
||||||
ApplicationLayout layout = new GenericApplicationLayout("DB Viewer", "1.0");
|
ApplicationLayout layout = new GenericApplicationLayout("DB Viewer", "1.0");
|
||||||
DockingApplicationConfiguration configuration = new DockingApplicationConfiguration();
|
DockingApplicationConfiguration configuration = new DockingApplicationConfiguration();
|
||||||
configuration.setShowSplashScreen(false);
|
configuration.setShowSplashScreen(false);
|
||||||
|
|
|
@ -27,6 +27,7 @@ import ghidra.formats.gfilesystem.*;
|
||||||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||||
import ghidra.formats.gfilesystem.fileinfo.FileAttribute;
|
import ghidra.formats.gfilesystem.fileinfo.FileAttribute;
|
||||||
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import utilities.util.FileUtilities;
|
import utilities.util.FileUtilities;
|
||||||
|
@ -76,7 +77,7 @@ public class JavaClassDecompilerFileSystem implements GFileSystem {
|
||||||
throws CancelledException, IOException {
|
throws CancelledException, IOException {
|
||||||
File tempDir = null;
|
File tempDir = null;
|
||||||
try {
|
try {
|
||||||
tempDir = FileUtilities.createTempDirectory("JavaClassDecompilerFileSystem");
|
tempDir = new File(Application.getUserTempDirectory(), "JavaClassDecompilerFileSystem");
|
||||||
|
|
||||||
File tempClassFile = new File(tempDir, containerFSRL.getName());
|
File tempClassFile = new File(tempDir, containerFSRL.getName());
|
||||||
FSUtilities.copyByteProviderToFile(provider, tempClassFile, monitor);
|
FSUtilities.copyByteProviderToFile(provider, tempClassFile, monitor);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.server.remote;
|
package ghidra.server.remote;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -34,10 +33,10 @@ public class GhidraServerApplicationLayout extends ApplicationLayout {
|
||||||
/**
|
/**
|
||||||
* Constructs a new Ghidra server application layout object.
|
* Constructs a new Ghidra server application layout object.
|
||||||
*
|
*
|
||||||
* @throws FileNotFoundException if there was a problem getting a user directory.
|
* @throws IOException if there was a problem getting a user directory or the application
|
||||||
* @throws IOException if there was a problem getting the application properties.
|
* properties.
|
||||||
*/
|
*/
|
||||||
public GhidraServerApplicationLayout() throws FileNotFoundException, IOException {
|
public GhidraServerApplicationLayout() throws IOException {
|
||||||
|
|
||||||
// Application root directories
|
// Application root directories
|
||||||
applicationRootDirs = ApplicationUtilities.findDefaultApplicationRootDirs();
|
applicationRootDirs = ApplicationUtilities.findDefaultApplicationRootDirs();
|
||||||
|
@ -56,7 +55,8 @@ public class GhidraServerApplicationLayout extends ApplicationLayout {
|
||||||
extensionInstallationDirs = Collections.emptyList();
|
extensionInstallationDirs = Collections.emptyList();
|
||||||
|
|
||||||
// User directories (don't let anything use the user home directory...there may not be one)
|
// User directories (don't let anything use the user home directory...there may not be one)
|
||||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(applicationProperties);
|
userTempDir =
|
||||||
|
ApplicationUtilities.getDefaultUserTempDir(applicationProperties.getApplicationName());
|
||||||
|
|
||||||
// Modules - required to find module data files
|
// Modules - required to find module data files
|
||||||
modules = ModuleUtilities.findModules(applicationRootDirs,
|
modules = ModuleUtilities.findModules(applicationRootDirs,
|
||||||
|
|
|
@ -21,8 +21,7 @@ import java.util.*;
|
||||||
import db.DBChangeSet;
|
import db.DBChangeSet;
|
||||||
import db.DBHandle;
|
import db.DBHandle;
|
||||||
import db.buffers.LocalBufferFile.BufferFileFilter;
|
import db.buffers.LocalBufferFile.BufferFileFilter;
|
||||||
import ghidra.framework.ShutdownHookRegistry;
|
import ghidra.framework.*;
|
||||||
import ghidra.framework.ShutdownPriority;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.datastruct.ObjectArray;
|
import ghidra.util.datastruct.ObjectArray;
|
||||||
|
@ -2049,7 +2048,7 @@ public class BufferMgr {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void cleanupOldCacheFiles() {
|
public static void cleanupOldCacheFiles() {
|
||||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
File tmpDir = Application.getUserTempDirectory();
|
||||||
File[] cacheFiles =
|
File[] cacheFiles =
|
||||||
tmpDir.listFiles(new BufferFileFilter(CACHE_FILE_PREFIX, CACHE_FILE_EXT));
|
tmpDir.listFiles(new BufferFileFilter(CACHE_FILE_PREFIX, CACHE_FILE_EXT));
|
||||||
if (cacheFiles == null) {
|
if (cacheFiles == null) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package db.buffers;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.util.BigEndianDataConverter;
|
import ghidra.util.BigEndianDataConverter;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.datastruct.IntSet;
|
import ghidra.util.datastruct.IntSet;
|
||||||
|
@ -197,8 +198,7 @@ public class LocalBufferFile implements BufferFile {
|
||||||
this.blockSize = bufferSize + BUFFER_PREFIX_SIZE;
|
this.blockSize = bufferSize + BUFFER_PREFIX_SIZE;
|
||||||
this.readOnly = false;
|
this.readOnly = false;
|
||||||
this.temporary = true;
|
this.temporary = true;
|
||||||
file = File.createTempFile(tmpPrefix, tmpExtension);
|
file = Application.createTempFile(tmpPrefix, tmpExtension);
|
||||||
// file.deleteOnExit();
|
|
||||||
raf = new RandomAccessFile(file, "rw");
|
raf = new RandomAccessFile(file, "rw");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Random;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
import db.buffers.*;
|
import db.buffers.*;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -815,7 +816,7 @@ public class DBTestUtils {
|
||||||
public static DBHandle cloneDbHandle(DBHandle dbh) throws IOException {
|
public static DBHandle cloneDbHandle(DBHandle dbh) throws IOException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File tmpFile = File.createTempFile("tmp", ".db");
|
File tmpFile = Application.createTempFile("tmp", ".db");
|
||||||
tmpFile.delete();
|
tmpFile.delete();
|
||||||
|
|
||||||
LocalBufferFile bf = new LocalBufferFile(tmpFile, dbh.getBufferSize());
|
LocalBufferFile bf = new LocalBufferFile(tmpFile, dbh.getBufferSize());
|
||||||
|
|
|
@ -24,6 +24,7 @@ import db.Database;
|
||||||
import db.buffers.BufferFileManager;
|
import db.buffers.BufferFileManager;
|
||||||
import db.buffers.LocalManagedBufferFile;
|
import db.buffers.LocalManagedBufferFile;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.store.FolderItem;
|
import ghidra.framework.store.FolderItem;
|
||||||
import ghidra.framework.store.db.PackedDatabaseCache.CachedDB;
|
import ghidra.framework.store.db.PackedDatabaseCache.CachedDB;
|
||||||
import ghidra.framework.store.local.*;
|
import ghidra.framework.store.local.*;
|
||||||
|
@ -32,7 +33,6 @@ import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
|
||||||
import utilities.util.FileUtilities;
|
import utilities.util.FileUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -364,7 +364,7 @@ public class PackedDatabase extends Database {
|
||||||
*/
|
*/
|
||||||
private static File createDBDir() throws IOException {
|
private static File createDBDir() throws IOException {
|
||||||
|
|
||||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
File tmpDir = Application.getUserTempDirectory();
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
while (tries++ < 10) {
|
while (tries++ < 10) {
|
||||||
File dir = new File(tmpDir, TEMPDB_DIR_PREFIX + getRandomString() + TEMPDB_DIR_EXT);
|
File dir = new File(tmpDir, TEMPDB_DIR_PREFIX + getRandomString() + TEMPDB_DIR_EXT);
|
||||||
|
@ -620,7 +620,7 @@ public class PackedDatabase extends Database {
|
||||||
InputStream itemIn = null;
|
InputStream itemIn = null;
|
||||||
File tmpFile = null;
|
File tmpFile = null;
|
||||||
try {
|
try {
|
||||||
tmpFile = File.createTempFile("pack", ".tmp");
|
tmpFile = Application.createTempFile("pack", ".tmp");
|
||||||
tmpFile.delete();
|
tmpFile.delete();
|
||||||
dbh.saveAs(tmpFile, false, monitor);
|
dbh.saveAs(tmpFile, false, monitor);
|
||||||
itemIn = new BufferedInputStream(new FileInputStream(tmpFile));
|
itemIn = new BufferedInputStream(new FileInputStream(tmpFile));
|
||||||
|
@ -838,7 +838,7 @@ public class PackedDatabase extends Database {
|
||||||
*/
|
*/
|
||||||
public static void cleanupOldTempDatabases() {
|
public static void cleanupOldTempDatabases() {
|
||||||
|
|
||||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
File tmpDir = Application.getUserTempDirectory();
|
||||||
File[] tempDbs = tmpDir.listFiles((FileFilter) file -> {
|
File[] tempDbs = tmpDir.listFiles((FileFilter) file -> {
|
||||||
String name = file.getName();
|
String name = file.getName();
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.logging.log4j.Logger;
|
||||||
import db.DBHandle;
|
import db.DBHandle;
|
||||||
import db.Database;
|
import db.Database;
|
||||||
import db.buffers.*;
|
import db.buffers.*;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.store.local.ItemSerializer;
|
import ghidra.framework.store.local.ItemSerializer;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -417,7 +418,8 @@ public class VersionedDatabase extends Database {
|
||||||
else {
|
else {
|
||||||
BufferFile bf = openBufferFile(version, -1);
|
BufferFile bf = openBufferFile(version, -1);
|
||||||
try {
|
try {
|
||||||
File tmpFile = File.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
File tmpFile =
|
||||||
|
Application.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
||||||
tmpFile.delete();
|
tmpFile.delete();
|
||||||
BufferFile tmpBf = new LocalBufferFile(tmpFile, bf.getBufferSize());
|
BufferFile tmpBf = new LocalBufferFile(tmpFile, bf.getBufferSize());
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
|
@ -425,18 +427,10 @@ public class VersionedDatabase extends Database {
|
||||||
LocalBufferFile.copyFile(bf, tmpBf, null, monitor);
|
LocalBufferFile.copyFile(bf, tmpBf, null, monitor);
|
||||||
tmpBf.close();
|
tmpBf.close();
|
||||||
|
|
||||||
InputStream itemIn = new FileInputStream(tmpFile);
|
try (InputStream itemIn = new FileInputStream(tmpFile)) {
|
||||||
try {
|
|
||||||
ItemSerializer.outputItem(name, contentType, filetype, tmpFile.length(),
|
ItemSerializer.outputItem(name, contentType, filetype, tmpFile.length(),
|
||||||
itemIn, outputFile, monitor);
|
itemIn, outputFile, monitor);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
itemIn.close();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.framework.store.remote;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
import db.buffers.*;
|
import db.buffers.*;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.client.RepositoryAdapter;
|
import ghidra.framework.client.RepositoryAdapter;
|
||||||
import ghidra.framework.remote.RepositoryItem;
|
import ghidra.framework.remote.RepositoryItem;
|
||||||
import ghidra.framework.store.DatabaseItem;
|
import ghidra.framework.store.DatabaseItem;
|
||||||
|
@ -101,25 +102,17 @@ public class RemoteDatabaseItem extends RemoteFolderItem implements DatabaseItem
|
||||||
|
|
||||||
BufferFile bf = repository.openDatabase(parentPath, itemName, version, -1);
|
BufferFile bf = repository.openDatabase(parentPath, itemName, version, -1);
|
||||||
try {
|
try {
|
||||||
File tmpFile = File.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
File tmpFile = Application.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
||||||
tmpFile.delete();
|
tmpFile.delete();
|
||||||
BufferFile tmpBf = new LocalBufferFile(tmpFile, bf.getBufferSize());
|
BufferFile tmpBf = new LocalBufferFile(tmpFile, bf.getBufferSize());
|
||||||
try {
|
try {
|
||||||
LocalBufferFile.copyFile(bf, tmpBf, null, monitor);
|
LocalBufferFile.copyFile(bf, tmpBf, null, monitor);
|
||||||
tmpBf.close();
|
tmpBf.close();
|
||||||
|
|
||||||
InputStream itemIn = new FileInputStream(tmpFile);
|
try (InputStream itemIn = new FileInputStream(tmpFile)) {
|
||||||
try {
|
|
||||||
ItemSerializer.outputItem(getName(), getContentType(), DATABASE_FILE_TYPE,
|
ItemSerializer.outputItem(getName(), getContentType(), DATABASE_FILE_TYPE,
|
||||||
tmpFile.length(), itemIn, outputFile, monitor);
|
tmpFile.length(), itemIn, outputFile, monitor);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
itemIn.close();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tmpBf.close();
|
tmpBf.close();
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
package generic.application;
|
package generic.application;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
@ -59,9 +59,9 @@ public class GenericApplicationLayout extends ApplicationLayout {
|
||||||
*
|
*
|
||||||
* @param name The name of the application.
|
* @param name The name of the application.
|
||||||
* @param version The version of the application.
|
* @param version The version of the application.
|
||||||
* @throws FileNotFoundException if there was a problem getting a user directory.
|
* @throws IOException if there was a problem getting a user directory.
|
||||||
*/
|
*/
|
||||||
public GenericApplicationLayout(String name, String version) throws FileNotFoundException {
|
public GenericApplicationLayout(String name, String version) throws IOException {
|
||||||
this(new ApplicationProperties(name, version, NO_RELEASE_NAME));
|
this(new ApplicationProperties(name, version, NO_RELEASE_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,10 +70,10 @@ public class GenericApplicationLayout extends ApplicationLayout {
|
||||||
* properties. The default Ghidra application root directory(s) will be used.
|
* properties. The default Ghidra application root directory(s) will be used.
|
||||||
*
|
*
|
||||||
* @param applicationProperties The properties object that will be read system properties.
|
* @param applicationProperties The properties object that will be read system properties.
|
||||||
* @throws FileNotFoundException if there was a problem getting a user directory.
|
* @throws IOException if there was a problem getting a user directory.
|
||||||
*/
|
*/
|
||||||
public GenericApplicationLayout(ApplicationProperties applicationProperties)
|
public GenericApplicationLayout(ApplicationProperties applicationProperties)
|
||||||
throws FileNotFoundException {
|
throws IOException {
|
||||||
this(getDefaultApplicationRootDirs(), applicationProperties);
|
this(getDefaultApplicationRootDirs(), applicationProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,10 +85,10 @@ public class GenericApplicationLayout extends ApplicationLayout {
|
||||||
* used to identify modules and resources. The first entry will be treated as the
|
* used to identify modules and resources. The first entry will be treated as the
|
||||||
* installation root.
|
* installation root.
|
||||||
* @param applicationProperties The properties object that will be read system properties.
|
* @param applicationProperties The properties object that will be read system properties.
|
||||||
* @throws FileNotFoundException if there was a problem getting a user directory.
|
* @throws IOException if there was a problem getting a user directory.
|
||||||
*/
|
*/
|
||||||
public GenericApplicationLayout(Collection<ResourceFile> applicationRootDirs,
|
public GenericApplicationLayout(Collection<ResourceFile> applicationRootDirs,
|
||||||
ApplicationProperties applicationProperties) throws FileNotFoundException {
|
ApplicationProperties applicationProperties) throws IOException {
|
||||||
|
|
||||||
this.applicationProperties = Objects.requireNonNull(applicationProperties);
|
this.applicationProperties = Objects.requireNonNull(applicationProperties);
|
||||||
this.applicationRootDirs = applicationRootDirs;
|
this.applicationRootDirs = applicationRootDirs;
|
||||||
|
@ -117,7 +117,8 @@ public class GenericApplicationLayout extends ApplicationLayout {
|
||||||
modules = Collections.unmodifiableMap(allModules);
|
modules = Collections.unmodifiableMap(allModules);
|
||||||
|
|
||||||
// User directories
|
// User directories
|
||||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(applicationProperties);
|
userTempDir =
|
||||||
|
ApplicationUtilities.getDefaultUserTempDir(applicationProperties.getApplicationName());
|
||||||
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(applicationProperties,
|
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(applicationProperties,
|
||||||
applicationInstallationDir);
|
applicationInstallationDir);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ package generic.test;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -35,6 +36,7 @@ import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.UniversalIdGenerator;
|
import ghidra.util.UniversalIdGenerator;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
|
import utility.application.ApplicationUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A root for system tests that provides known system information.
|
* A root for system tests that provides known system information.
|
||||||
|
@ -110,16 +112,21 @@ public abstract class AbstractGTest {
|
||||||
// In batch mode we rely on the fact that the test environment has been setup with a
|
// In batch mode we rely on the fact that the test environment has been setup with a
|
||||||
// custom temp directory.
|
// custom temp directory.
|
||||||
//
|
//
|
||||||
return System.getProperty("java.io.tmpdir") + File.separator + "Ghidra_test_" +
|
try {
|
||||||
UUID.randomUUID() + File.separator + "temp.data";
|
return new File(ApplicationUtilities.getDefaultUserTempDir("ghidra"),
|
||||||
|
"test_" + UUID.randomUUID() + File.separator + "temp.data").getPath();
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
throw new AssertException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildDevelopmentDirectoryPath() {
|
private static String buildDevelopmentDirectoryPath() {
|
||||||
//
|
//
|
||||||
// Create a unique name based upon the repo from which we are running.
|
// Create a unique name based upon the repo from which we are running.
|
||||||
//
|
//
|
||||||
File tempDir = TestApplicationUtils.getUniqueTempFolder();
|
File tempDir = TestApplicationUtils.getUniqueTempDir();
|
||||||
return tempDir.getAbsolutePath();
|
return tempDir.getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getTestDirectoryPath() {
|
public static String getTestDirectoryPath() {
|
||||||
|
|
|
@ -809,10 +809,10 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a file in the Java temp directory using the given name as a
|
* Creates a file in the Application temp directory using the given name as a
|
||||||
* prefix and the given suffix. The final filename will also include the
|
* prefix and the given suffix. The final filename will also include the
|
||||||
* current test name, as well as any data added by
|
* current test name, as well as any data added by
|
||||||
* {@link File#createTempFile(String, String)}. The file suffix will be
|
* {@link File#createTempFile(String, String, File)}. The file suffix will be
|
||||||
* <code>.tmp</code>
|
* <code>.tmp</code>
|
||||||
* <p>
|
* <p>
|
||||||
* The file will be marked to delete on JVM exit. This will not work if the
|
* The file will be marked to delete on JVM exit. This will not work if the
|
||||||
|
@ -830,10 +830,10 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a file in the Java temp directory using the given name as a
|
* Creates a file in the Application temp directory using the given name as a
|
||||||
* prefix and the given suffix. The final filename will also include the
|
* prefix and the given suffix. The final filename will also include the
|
||||||
* current test name, as well as any data added by
|
* current test name, as well as any data added by
|
||||||
* {@link File#createTempFile(String, String)}.
|
* {@link File#createTempFile(String, String, File)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The file will be marked to delete on JVM exit. This will not work if the
|
* The file will be marked to delete on JVM exit. This will not work if the
|
||||||
* JVM is taken down the hard way, as when pressing the stop button in
|
* JVM is taken down the hard way, as when pressing the stop button in
|
||||||
|
|
|
@ -29,6 +29,7 @@ import util.CollectionUtils;
|
||||||
import utilities.util.FileUtilities;
|
import utilities.util.FileUtilities;
|
||||||
import utilities.util.reflection.ReflectionUtilities;
|
import utilities.util.reflection.ReflectionUtilities;
|
||||||
import utility.application.ApplicationLayout;
|
import utility.application.ApplicationLayout;
|
||||||
|
import utility.application.ApplicationUtilities;
|
||||||
import utility.module.ModuleUtilities;
|
import utility.module.ModuleUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -667,7 +668,6 @@ public class Application {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the temporary directory specific to the user and the application.
|
* Returns the temporary directory specific to the user and the application.
|
||||||
* Directory has name of <username>-<appname>
|
|
||||||
* This directory may be removed at system reboot or during periodic
|
* This directory may be removed at system reboot or during periodic
|
||||||
* system cleanup of unused temp files.
|
* system cleanup of unused temp files.
|
||||||
* This directory is specific to the application name but not the version.
|
* This directory is specific to the application name but not the version.
|
||||||
|
@ -677,15 +677,22 @@ public class Application {
|
||||||
* @return temp directory
|
* @return temp directory
|
||||||
*/
|
*/
|
||||||
public static File getUserTempDirectory() {
|
public static File getUserTempDirectory() {
|
||||||
checkAppInitialized();
|
try {
|
||||||
return app.layout.getUserTempDir();
|
// 'app' will be null when the application has not been initialized yet. In this case,
|
||||||
|
// we provide the default user temp directory.
|
||||||
|
return app != null ? app.layout.getUserTempDir()
|
||||||
|
: ApplicationUtilities.getDefaultUserTempDir("ghidra");
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
throw new AssertException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cache directory specific to the user and the application.
|
* Returns the cache directory specific to the user and the application.
|
||||||
* The intention is for directory contents to be preserved, however the
|
* The intention is for directory contents to be preserved, however the
|
||||||
* specific location is platform specific and contents may be removed when
|
* specific location is platform specific and contents may be removed when
|
||||||
* not in use and may in fact be the same directory the user temp directory.
|
* not in use.
|
||||||
* This directory is specific to the application name but not the version.
|
* This directory is specific to the application name but not the version.
|
||||||
* Resources stored within this directory should utilize some
|
* Resources stored within this directory should utilize some
|
||||||
* form of access locking and/or unique naming.
|
* form of access locking and/or unique naming.
|
||||||
|
@ -696,6 +703,24 @@ public class Application {
|
||||||
return app.layout.getUserCacheDir();
|
return app.layout.getUserCacheDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty file in the Application's temp directory, using the given prefix and
|
||||||
|
* suffix strings to generate its name.
|
||||||
|
*
|
||||||
|
* @param prefix The prefix string to be used in generating the file's name; must be at least
|
||||||
|
* three characters long
|
||||||
|
* @param suffix The suffix string to be used in generating the file's name; may be
|
||||||
|
* {@code null}, in which case the suffix {@code ".tmp"} will be used
|
||||||
|
* @return A {@link File} denoting a newly-created empty file
|
||||||
|
* @throws IllegalArgumentException If the {@code prefix} argument contains fewer than three
|
||||||
|
* characters
|
||||||
|
* @throws IOException If a file could not be created
|
||||||
|
* @see File#createTempFile(String, String, File)
|
||||||
|
*/
|
||||||
|
public static File createTempFile(String prefix, String suffix) throws IOException {
|
||||||
|
return File.createTempFile(prefix, suffix, getUserTempDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a collection of all the module root directories. A module root directory is
|
* Returns a collection of all the module root directories. A module root directory is
|
||||||
* the top-level directory of a module.
|
* the top-level directory of a module.
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.framework;
|
package ghidra.framework;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileFilter;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
@ -24,6 +23,8 @@ import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import ghidra.framework.preferences.Preferences;
|
import ghidra.framework.preferences.Preferences;
|
||||||
import util.CollectionUtils;
|
import util.CollectionUtils;
|
||||||
|
import utility.application.ApplicationLayout;
|
||||||
|
import utility.application.ApplicationUtilities;
|
||||||
|
|
||||||
public class GenericRunInfo {
|
public class GenericRunInfo {
|
||||||
|
|
||||||
|
@ -42,10 +43,23 @@ public class GenericRunInfo {
|
||||||
* <b>Note: </b>This method ignores Test directories
|
* <b>Note: </b>This method ignores Test directories
|
||||||
*/
|
*/
|
||||||
private static List<File> getUserSettingsDirsByTime() {
|
private static List<File> getUserSettingsDirsByTime() {
|
||||||
File userDataDirectory = Application.getUserSettingsDirectory();
|
ApplicationLayout layout = Application.getApplicationLayout();
|
||||||
File userDataDirParentFile = userDataDirectory.getParentFile();
|
File userSettingsDirectory = Application.getUserSettingsDirectory();
|
||||||
|
|
||||||
List<File> appDirs = collectAllApplicationDirectories(userDataDirParentFile);
|
List<File> appDirs =
|
||||||
|
collectAllApplicationDirectories(userSettingsDirectory.getParentFile());
|
||||||
|
|
||||||
|
// Search "legacy" user setting directory locations in case the user has upgraded from an
|
||||||
|
// older version
|
||||||
|
try {
|
||||||
|
File legacyUserSettingsDirectory = ApplicationUtilities.getLegacyUserSettingsDir(
|
||||||
|
layout.getApplicationProperties(), layout.getApplicationInstallationDir());
|
||||||
|
appDirs.addAll(
|
||||||
|
collectAllApplicationDirectories(legacyUserSettingsDirectory.getParentFile()));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
Comparator<File> modifyTimeComparator = (f1, f2) -> {
|
Comparator<File> modifyTimeComparator = (f1, f2) -> {
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package ghidra.framework;
|
package ghidra.framework;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -24,6 +25,7 @@ import ghidra.util.Msg;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import utilities.util.FileUtilities;
|
import utilities.util.FileUtilities;
|
||||||
|
import utility.application.ApplicationUtilities;
|
||||||
import utility.module.ModuleUtilities;
|
import utility.module.ModuleUtilities;
|
||||||
|
|
||||||
public class TestApplicationUtils {
|
public class TestApplicationUtils {
|
||||||
|
@ -127,13 +129,13 @@ public class TestApplicationUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a folder that is unique for the current installation. This allows clients to
|
* Creates a directory that is unique for the current installation. This allows clients to
|
||||||
* have multiple clones (for development mode) or multiple installations (for release mode)
|
* have multiple clones (for development mode) or multiple installations (for release mode)
|
||||||
* on their machine, running tests from each repo simultaneously.
|
* on their machine, running tests from each repo simultaneously.
|
||||||
*
|
*
|
||||||
* @return a folder that is unique for the current installation
|
* @return an absolute form directory that is unique for the current installation
|
||||||
*/
|
*/
|
||||||
public static File getUniqueTempFolder() {
|
public static File getUniqueTempDir() {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create a unique name based upon the repo from which we are running.
|
// Create a unique name based upon the repo from which we are running.
|
||||||
|
@ -144,14 +146,18 @@ public class TestApplicationUtils {
|
||||||
reposContainer = installDir;
|
reposContainer = installDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
try {
|
||||||
String tempName = tmpDir.getName();
|
File tmpDir = ApplicationUtilities.getDefaultUserTempDir("ghidra");
|
||||||
|
|
||||||
//
|
//
|
||||||
// The container name makes this name unique across multiple Eclipses; the system temp
|
// The container name makes this name unique across multiple Eclipses; the system temp
|
||||||
// name makes this name unique across multiple runs from the same Eclipse
|
// name makes this name unique across multiple runs from the same Eclipse
|
||||||
//
|
//
|
||||||
String name = reposContainer.getName() + tempName;
|
String name = reposContainer.getName();
|
||||||
return new File(tmpDir, name);
|
return new File(tmpDir, name);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
throw new AssertException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package utilities.util;
|
package utilities.util;
|
||||||
|
|
||||||
import static generic.test.AbstractGTest.assertListEqualsArrayOrdered;
|
import static generic.test.AbstractGTest.*;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -30,8 +30,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import generic.test.AbstractGenericTest;
|
import generic.test.AbstractGenericTest;
|
||||||
import ghidra.framework.OperatingSystem;
|
import ghidra.framework.*;
|
||||||
import ghidra.framework.Platform;
|
|
||||||
import utilities.util.FileResolutionResult.FileResolutionStatus;
|
import utilities.util.FileResolutionResult.FileResolutionStatus;
|
||||||
|
|
||||||
public class FileUtilitiesTest {
|
public class FileUtilitiesTest {
|
||||||
|
@ -198,11 +197,11 @@ public class FileUtilitiesTest {
|
||||||
@Test
|
@Test
|
||||||
public void copyFile_ResourceFile_To_ResourceFile() throws Exception {
|
public void copyFile_ResourceFile_To_ResourceFile() throws Exception {
|
||||||
|
|
||||||
File from = File.createTempFile("from.file", ".txt");
|
File from = Application.createTempFile("from.file", ".txt");
|
||||||
FileUtilities.writeLinesToFile(from, Arrays.asList("From file contents"));
|
FileUtilities.writeLinesToFile(from, Arrays.asList("From file contents"));
|
||||||
from.deleteOnExit();
|
from.deleteOnExit();
|
||||||
|
|
||||||
File to = File.createTempFile("to.file", ".txt");
|
File to = Application.createTempFile("to.file", ".txt");
|
||||||
to.deleteOnExit();
|
to.deleteOnExit();
|
||||||
FileUtilities.writeLinesToFile(to, Arrays.asList("To file contents"));
|
FileUtilities.writeLinesToFile(to, Arrays.asList("To file contents"));
|
||||||
|
|
||||||
|
@ -222,7 +221,7 @@ public class FileUtilitiesTest {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
File to = File.createTempFile("to.file", ".txt");
|
File to = Application.createTempFile("to.file", ".txt");
|
||||||
to.deleteOnExit();
|
to.deleteOnExit();
|
||||||
|
|
||||||
// should fail
|
// should fail
|
||||||
|
@ -232,7 +231,7 @@ public class FileUtilitiesTest {
|
||||||
@Test(expected = IOException.class)
|
@Test(expected = IOException.class)
|
||||||
public void copyFile_ExceptionFromOutputStream() throws Exception {
|
public void copyFile_ExceptionFromOutputStream() throws Exception {
|
||||||
|
|
||||||
File from = File.createTempFile("from.file", ".txt");
|
File from = Application.createTempFile("from.file", ".txt");
|
||||||
from.deleteOnExit();
|
from.deleteOnExit();
|
||||||
|
|
||||||
ResourceFile to = new ResourceFile(new File("/to.from.file")) {
|
ResourceFile to = new ResourceFile(new File("/to.from.file")) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import javax.swing.Icon;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
import generic.util.image.ImageUtils;
|
import generic.util.image.ImageUtils;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +95,7 @@ public class IconProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File imageFile = File.createTempFile("temp.help.icon", null);
|
File imageFile = Application.createTempFile("temp.help.icon", null);
|
||||||
imageFile.deleteOnExit(); // don't let this linger
|
imageFile.deleteOnExit(); // don't let this linger
|
||||||
ImageIcon imageIcon = ResourceManager.getImageIcon(icon);
|
ImageIcon imageIcon = ResourceManager.getImageIcon(icon);
|
||||||
ImageUtils.writeFile(imageIcon.getImage(), imageFile);
|
ImageUtils.writeFile(imageIcon.getImage(), imageFile);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.xml.sax.*;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
import org.xml.sax.helpers.ParserAdapter;
|
import org.xml.sax.helpers.ParserAdapter;
|
||||||
|
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.util.xml.XmlUtilities;
|
import ghidra.util.xml.XmlUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,7 +175,7 @@ public class TOCConverter {
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private File createTempTOCFile() throws IOException {
|
private File createTempTOCFile() throws IOException {
|
||||||
File tempFile = File.createTempFile("toc", ".xml");
|
File tempFile = Application.createTempFile("toc", ".xml");
|
||||||
|
|
||||||
PrintWriter out = new PrintWriter(new FileOutputStream(tempFile));
|
PrintWriter out = new PrintWriter(new FileOutputStream(tempFile));
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(sourceFilename));
|
BufferedReader reader = new BufferedReader(new FileReader(sourceFilename));
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.protocol.ghidra.GhidraURL;
|
import ghidra.framework.protocol.ghidra.GhidraURL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,7 +68,7 @@ public class ProjectLocator {
|
||||||
}
|
}
|
||||||
this.name = name;
|
this.name = name;
|
||||||
if (StringUtils.isBlank(path)) {
|
if (StringUtils.isBlank(path)) {
|
||||||
path = System.getProperty("java.io.tmpdir");
|
path = Application.getUserTempDirectory().getAbsolutePath();
|
||||||
}
|
}
|
||||||
this.location = checkAbsolutePath(path);
|
this.location = checkAbsolutePath(path);
|
||||||
url = GhidraURL.makeURL(location, name);
|
url = GhidraURL.makeURL(location, name);
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.client.NotConnectedException;
|
import ghidra.framework.client.NotConnectedException;
|
||||||
import ghidra.framework.client.RepositoryAdapter;
|
import ghidra.framework.client.RepositoryAdapter;
|
||||||
import ghidra.framework.model.ProjectLocator;
|
import ghidra.framework.model.ProjectLocator;
|
||||||
|
@ -172,7 +173,7 @@ public class TransientProjectManager {
|
||||||
private TransientProjectData createTransientProject(RepositoryAdapter repository,
|
private TransientProjectData createTransientProject(RepositoryAdapter repository,
|
||||||
RepositoryInfo repositoryInfo) throws IOException {
|
RepositoryInfo repositoryInfo) throws IOException {
|
||||||
|
|
||||||
File tmp = File.createTempFile("ghidraPrj", "");
|
File tmp = Application.createTempFile("ghidraPrj", "");
|
||||||
tmp.delete();
|
tmp.delete();
|
||||||
|
|
||||||
ProjectLocator tmpProjectLocation = new TransientProjectStorageLocator(
|
ProjectLocator tmpProjectLocation = new TransientProjectStorageLocator(
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import generic.test.AbstractGenericTest;
|
import generic.test.AbstractGenericTest;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.OperatingSystem;
|
import ghidra.framework.OperatingSystem;
|
||||||
import ghidra.framework.protocol.ghidra.Handler;
|
import ghidra.framework.protocol.ghidra.Handler;
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ public class ProjectLocatorTest extends AbstractGenericTest {
|
||||||
@Test
|
@Test
|
||||||
public void testTempPath() throws MalformedURLException {
|
public void testTempPath() throws MalformedURLException {
|
||||||
|
|
||||||
String tmpPath = System.getProperty("java.io.tmpdir").replace("\\", "/");
|
String tmpPath = Application.getUserTempDirectory().getAbsolutePath().replace("\\", "/");
|
||||||
if (!tmpPath.startsWith("/")) {
|
if (!tmpPath.startsWith("/")) {
|
||||||
tmpPath = "/" + tmpPath;
|
tmpPath = "/" + tmpPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest {
|
||||||
public ResourceFile createCustomPspecFile(String name, String content) {
|
public ResourceFile createCustomPspecFile(String name, String content) {
|
||||||
File newPspecFile = null;
|
File newPspecFile = null;
|
||||||
try {
|
try {
|
||||||
newPspecFile = File.createTempFile(name, ".pspec");
|
newPspecFile = Application.createTempFile(name, ".pspec");
|
||||||
BufferedWriter bw = new BufferedWriter(new FileWriter(newPspecFile));
|
BufferedWriter bw = new BufferedWriter(new FileWriter(newPspecFile));
|
||||||
bw.write(content);
|
bw.write(content);
|
||||||
bw.close();
|
bw.close();
|
||||||
|
@ -239,7 +239,7 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File editedPspecFile = File.createTempFile(name, ".ldefs");
|
File editedPspecFile = Application.createTempFile(name, ".ldefs");
|
||||||
BufferedReader br = new BufferedReader(new FileReader(originalLdefFile.getFile(false)));
|
BufferedReader br = new BufferedReader(new FileReader(originalLdefFile.getFile(false)));
|
||||||
BufferedWriter bw = new BufferedWriter(new FileWriter(editedPspecFile));
|
BufferedWriter bw = new BufferedWriter(new FileWriter(editedPspecFile));
|
||||||
String s;
|
String s;
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package ghidra;
|
package ghidra;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
|
@ -36,12 +37,10 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
||||||
/**
|
/**
|
||||||
* Constructs a new Ghidra application layout object.
|
* Constructs a new Ghidra application layout object.
|
||||||
*
|
*
|
||||||
* @throws FileNotFoundException if there was a problem getting a user
|
* @throws IOException if there was a problem getting a user directory or the application
|
||||||
* directory.
|
* properties or modules.
|
||||||
* @throws IOException if there was a problem getting the application
|
|
||||||
* properties or modules.
|
|
||||||
*/
|
*/
|
||||||
public GhidraApplicationLayout() throws FileNotFoundException, IOException {
|
public GhidraApplicationLayout() throws IOException {
|
||||||
|
|
||||||
// Application root directories
|
// Application root directories
|
||||||
applicationRootDirs = findGhidraApplicationRootDirs();
|
applicationRootDirs = findGhidraApplicationRootDirs();
|
||||||
|
@ -53,7 +52,8 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
||||||
applicationInstallationDir = findGhidraApplicationInstallationDir();
|
applicationInstallationDir = findGhidraApplicationInstallationDir();
|
||||||
|
|
||||||
// User directories
|
// User directories
|
||||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(getApplicationProperties());
|
userTempDir = ApplicationUtilities
|
||||||
|
.getDefaultUserTempDir(getApplicationProperties().getApplicationName());
|
||||||
userCacheDir = ApplicationUtilities.getDefaultUserCacheDir(getApplicationProperties());
|
userCacheDir = ApplicationUtilities.getDefaultUserCacheDir(getApplicationProperties());
|
||||||
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(getApplicationProperties(),
|
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(getApplicationProperties(),
|
||||||
getApplicationInstallationDir());
|
getApplicationInstallationDir());
|
||||||
|
@ -77,13 +77,10 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
||||||
* (like the Eclipse GhidraDevPlugin).
|
* (like the Eclipse GhidraDevPlugin).
|
||||||
*
|
*
|
||||||
* @param applicationInstallationDir The application installation directory.
|
* @param applicationInstallationDir The application installation directory.
|
||||||
* @throws FileNotFoundException if there was a problem getting a user
|
* @throws IOException if there was a problem getting a user directory or the application
|
||||||
* directory.
|
* properties.
|
||||||
* @throws IOException if there was a problem getting the application
|
|
||||||
* properties.
|
|
||||||
*/
|
*/
|
||||||
public GhidraApplicationLayout(File applicationInstallationDir)
|
public GhidraApplicationLayout(File applicationInstallationDir) throws IOException {
|
||||||
throws FileNotFoundException, IOException {
|
|
||||||
|
|
||||||
// Application installation directory
|
// Application installation directory
|
||||||
this.applicationInstallationDir = new ResourceFile(applicationInstallationDir);
|
this.applicationInstallationDir = new ResourceFile(applicationInstallationDir);
|
||||||
|
@ -96,7 +93,8 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
||||||
applicationProperties = new ApplicationProperties(applicationRootDirs);
|
applicationProperties = new ApplicationProperties(applicationRootDirs);
|
||||||
|
|
||||||
// User directories
|
// User directories
|
||||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(getApplicationProperties());
|
userTempDir = ApplicationUtilities
|
||||||
|
.getDefaultUserTempDir(getApplicationProperties().getApplicationName());
|
||||||
userCacheDir = ApplicationUtilities.getDefaultUserCacheDir(getApplicationProperties());
|
userCacheDir = ApplicationUtilities.getDefaultUserCacheDir(getApplicationProperties());
|
||||||
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(getApplicationProperties(),
|
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(getApplicationProperties(),
|
||||||
getApplicationInstallationDir());
|
getApplicationInstallationDir());
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class SystemUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the boolean value of the system property by the given name. If the property is
|
* Gets the boolean value of the system property by the given name. If the property is
|
||||||
* not set, the defaultValue is returned. If the value is set, then it will be passed
|
* not set, the defaultValue is returned. If the value is set, then it will be passed
|
||||||
* into {@link Boolean#parseBoolean(String)}.
|
* into {@link Boolean#parseBoolean(String)}.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1189,29 +1189,6 @@ public final class FileUtilities {
|
||||||
return formatter.format((length / 1000000f)) + "MB";
|
return formatter.format((length / 1000000f)) + "MB";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a temporary directory using the given prefix
|
|
||||||
* @param prefix the prefix
|
|
||||||
* @return the temp file
|
|
||||||
*/
|
|
||||||
public static File createTempDirectory(String prefix) {
|
|
||||||
try {
|
|
||||||
File temp = File.createTempFile(prefix, Long.toString(System.currentTimeMillis()));
|
|
||||||
if (!temp.delete()) {
|
|
||||||
throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
|
|
||||||
}
|
|
||||||
if (!createDir(temp)) {
|
|
||||||
throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
|
|
||||||
}
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
Msg.error(FileUtilities.class, "Error creating temporary directory", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the given file (or directory) to readable and writable by only the owner.
|
* Sets the given file (or directory) to readable and writable by only the owner.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,310 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* 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 utility.application;
|
||||||
|
|
||||||
|
import static utility.application.ApplicationUtilities.*;
|
||||||
|
import static utility.application.XdgUtils.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import generic.jar.ResourceFile;
|
||||||
|
import ghidra.GhidraApplicationLayout;
|
||||||
|
import ghidra.GhidraLaunchable;
|
||||||
|
import ghidra.framework.ApplicationProperties;
|
||||||
|
import ghidra.framework.OperatingSystem;
|
||||||
|
import ghidra.util.SystemUtilities;
|
||||||
|
import utilities.util.FileUtilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interactive utility to discover and delete artifacts that Ghidra lays down on the filesystem
|
||||||
|
*/
|
||||||
|
public class AppCleaner implements GhidraLaunchable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launches the {@link AppCleaner}
|
||||||
|
*
|
||||||
|
* @param layout The application layout to use for the launch
|
||||||
|
* @param args One argument is expected: the name of the application to clean. All other
|
||||||
|
* arguments are ignored.
|
||||||
|
* @throws Exception if there was a problem with the launch
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void launch(GhidraApplicationLayout layout, String[] args) throws Exception {
|
||||||
|
|
||||||
|
if (args.length != 1) {
|
||||||
|
System.out.println("Expected 1 argument but got " + args.length);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String appName = args[0];
|
||||||
|
System.out.println("\nDiscovering " + appName + " artifact directories....");
|
||||||
|
|
||||||
|
// Discover directories
|
||||||
|
Set<File> discoveredSet = new LinkedHashSet<>();
|
||||||
|
discoveredSet.addAll(findSettingsDirs(appName, layout));
|
||||||
|
discoveredSet.addAll(findCacheDirs(appName, layout));
|
||||||
|
discoveredSet.addAll(findTempDirs(appName, layout));
|
||||||
|
List<File> discoveredDirs = new ArrayList<>(discoveredSet);
|
||||||
|
|
||||||
|
// Exit if we didn't discover any directories
|
||||||
|
if (discoveredDirs.isEmpty()) {
|
||||||
|
System.out.println("NONE FOUND");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output discovered directories and prompt user
|
||||||
|
File potentialParentDir = null;
|
||||||
|
for (int i = 0; i < discoveredDirs.size(); i++) {
|
||||||
|
File d = discoveredDirs.get(i);
|
||||||
|
File parentDir = d.getParentFile();
|
||||||
|
boolean indent = parentDir.equals(potentialParentDir);
|
||||||
|
System.out.println("%2d)%s %s".formatted(i + 1, indent ? " " : "", d));
|
||||||
|
if (!indent) {
|
||||||
|
potentialParentDir = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("*) All");
|
||||||
|
System.out.println("0) Exit");
|
||||||
|
System.out.print("Enter a directory to delete: ");
|
||||||
|
|
||||||
|
// Get user choice and delete
|
||||||
|
String choice = null;
|
||||||
|
try (Scanner scanner = new Scanner(System.in)){
|
||||||
|
List<File> failures = new ArrayList<>();
|
||||||
|
choice = scanner.nextLine().trim();
|
||||||
|
switch (choice) {
|
||||||
|
case "0":
|
||||||
|
System.out.println("Exiting...");
|
||||||
|
return;
|
||||||
|
case "*":
|
||||||
|
for (File dir : discoveredDirs) {
|
||||||
|
if (dir.isDirectory()) {
|
||||||
|
if (!FileUtilities.deleteDir(dir)) {
|
||||||
|
failures.add(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
File dir = discoveredDirs.get(Integer.parseInt(choice) - 1);
|
||||||
|
if (!FileUtilities.deleteDir(dir)) {
|
||||||
|
failures.add(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(failures.isEmpty() ? "SUCCESS" : "Failed to delete:");
|
||||||
|
failures.forEach(dir -> System.out.println(" " + dir));
|
||||||
|
}
|
||||||
|
catch (NoSuchElementException e) {
|
||||||
|
// User likely hit ctrl+c to exit
|
||||||
|
}
|
||||||
|
catch (NumberFormatException | IndexOutOfBoundsException e) {
|
||||||
|
System.out.println("Invalid entry: \"" + choice + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds user settings directories
|
||||||
|
*
|
||||||
|
* @param appName The name of the application
|
||||||
|
* @param layout The layout
|
||||||
|
* @return A {@link Set} of discovered user settings directories, ordered such that
|
||||||
|
* parent directories are directly followed by their subdirectories, if applicable
|
||||||
|
* @see ApplicationUtilities#getDefaultUserSettingsDir(ApplicationProperties, ResourceFile)
|
||||||
|
* @see ApplicationUtilities#getLegacyUserSettingsDir(ApplicationProperties, ResourceFile)
|
||||||
|
*/
|
||||||
|
private Set<File> findSettingsDirs(String appName, ApplicationLayout layout) {
|
||||||
|
Set<File> discoveredDirs = new LinkedHashSet<>();
|
||||||
|
appName = appName.toLowerCase();
|
||||||
|
String userNameAndAppName = SystemUtilities.getUserName() + "-" + appName;
|
||||||
|
|
||||||
|
// Legacy default settings directory
|
||||||
|
getDirFromProperty("user.home", "." + appName).ifPresent(dir -> {
|
||||||
|
discoveredDirs.add(dir);
|
||||||
|
discoveredDirs.addAll(getSubdirs(dir));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Current default settings directory
|
||||||
|
File settingsDir = layout.getUserSettingsDir();
|
||||||
|
File settingsParentDir = settingsDir.getParentFile();
|
||||||
|
if (settingsParentDir != null && (settingsParentDir.getName().equals(appName) ||
|
||||||
|
settingsParentDir.getName().equals(userNameAndAppName))) {
|
||||||
|
discoveredDirs.add(settingsParentDir);
|
||||||
|
discoveredDirs.addAll(getSubdirs(settingsParentDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Application system property override (likely not set for AppCleaner)
|
||||||
|
getDirFromProperty(PROPERTY_SETTINGS_DIR, appName).ifPresent(dir -> {
|
||||||
|
discoveredDirs.add(dir);
|
||||||
|
discoveredDirs.addAll(getSubdirs(dir));
|
||||||
|
});
|
||||||
|
getDirFromProperty(PROPERTY_SETTINGS_DIR, userNameAndAppName).ifPresent(dir -> {
|
||||||
|
discoveredDirs.add(dir);
|
||||||
|
discoveredDirs.addAll(getSubdirs(dir));
|
||||||
|
});
|
||||||
|
|
||||||
|
// XDG environment variable override
|
||||||
|
getDirFromEnv(XDG_CONFIG_HOME, appName).ifPresent(dir -> {
|
||||||
|
discoveredDirs.add(dir);
|
||||||
|
discoveredDirs.addAll(getSubdirs(dir));
|
||||||
|
});
|
||||||
|
getDirFromEnv(XDG_CONFIG_HOME, userNameAndAppName).ifPresent(dir -> {
|
||||||
|
discoveredDirs.add(dir);
|
||||||
|
discoveredDirs.addAll(getSubdirs(dir));
|
||||||
|
});
|
||||||
|
|
||||||
|
return discoveredDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds user cache directories
|
||||||
|
*
|
||||||
|
* @param appName The name of the application
|
||||||
|
* @param layout The layout
|
||||||
|
* @return A {@link Set} of discovered user cache directories, ordered such that
|
||||||
|
* parent directories are directly followed by their subdirectories, if applicable
|
||||||
|
* @see ApplicationUtilities#getDefaultUserCacheDir(ApplicationProperties)
|
||||||
|
*/
|
||||||
|
private Set<File> findCacheDirs(String appName, ApplicationLayout layout) {
|
||||||
|
Set<File> discoveredDirs = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
// Legacy cache directories
|
||||||
|
if (OperatingSystem.CURRENT_OPERATING_SYSTEM.equals(OperatingSystem.WINDOWS)) {
|
||||||
|
getDirFromEnv("LOCALAPPDATA", appName).ifPresent(discoveredDirs::add);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String legacyName = SystemUtilities.getUserName() + "-" + appName;
|
||||||
|
getDirFromProperty("java.io.tmpdir", legacyName).ifPresent(discoveredDirs::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Newer cache directories always use a lowercase application name
|
||||||
|
appName = appName.toLowerCase();
|
||||||
|
String userNameAndAppName = SystemUtilities.getUserName() + "-" + appName;
|
||||||
|
|
||||||
|
// Current cache directories
|
||||||
|
File cacheDir = layout.getUserCacheDir();
|
||||||
|
if (cacheDir != null && cacheDir.isDirectory()) {
|
||||||
|
discoveredDirs.add(cacheDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Application system property override (likely not set for AppCleaner)
|
||||||
|
getDirFromProperty(PROPERTY_CACHE_DIR, appName).ifPresent(discoveredDirs::add);
|
||||||
|
getDirFromProperty(PROPERTY_CACHE_DIR, userNameAndAppName).ifPresent(discoveredDirs::add);
|
||||||
|
|
||||||
|
// XDG environment variable override
|
||||||
|
getDirFromEnv(XDG_CACHE_HOME, appName).ifPresent(discoveredDirs::add);
|
||||||
|
getDirFromEnv(XDG_CACHE_HOME, userNameAndAppName).ifPresent(discoveredDirs::add);
|
||||||
|
|
||||||
|
return discoveredDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds user temp directories
|
||||||
|
*
|
||||||
|
* @param appName The name of the application
|
||||||
|
* @param layout The layout
|
||||||
|
* @return A {@link Set} of discovered user temp directories, ordered such that
|
||||||
|
* parent directories are directly followed by their subdirectories, if applicable
|
||||||
|
* @see ApplicationUtilities#getDefaultUserTempDir(String)
|
||||||
|
*/
|
||||||
|
private Set<File> findTempDirs(String appName, ApplicationLayout layout) {
|
||||||
|
Set<File> discoveredDirs = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
// Legacy temp directories
|
||||||
|
String legacyName = SystemUtilities.getUserName() + "-" + appName;
|
||||||
|
if (OperatingSystem.CURRENT_OPERATING_SYSTEM.equals(OperatingSystem.WINDOWS)) {
|
||||||
|
getDirFromEnv("TEMP", legacyName).ifPresent(discoveredDirs::add);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getDirFromProperty("java.io.tmpdir", legacyName).ifPresent(discoveredDirs::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Newer temp directories always use a lowercase application name
|
||||||
|
appName = appName.toLowerCase();
|
||||||
|
String userNameAndAppName = SystemUtilities.getUserName() + "-" + appName;
|
||||||
|
|
||||||
|
// Current temp directories
|
||||||
|
File tempDir = layout.getUserTempDir();
|
||||||
|
if (tempDir != null && tempDir.isDirectory()) {
|
||||||
|
discoveredDirs.add(tempDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Application system property override (likely not set for AppCleaner)
|
||||||
|
getDirFromProperty(PROPERTY_TEMP_DIR, appName).ifPresent(discoveredDirs::add);
|
||||||
|
getDirFromProperty(PROPERTY_TEMP_DIR, userNameAndAppName).ifPresent(discoveredDirs::add);
|
||||||
|
|
||||||
|
// XDG environment variable override
|
||||||
|
getDirFromEnv(XDG_RUNTIME_DIR, appName).ifPresent(discoveredDirs::add);
|
||||||
|
getDirFromEnv(XDG_RUNTIME_DIR, userNameAndAppName).ifPresent(discoveredDirs::add);
|
||||||
|
|
||||||
|
return discoveredDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the subdirectory of the given name found within the directory specified by the given
|
||||||
|
* system property
|
||||||
|
*
|
||||||
|
* @param propertyName The name of the system property
|
||||||
|
* @param subdirName The name of the subdirectory within the directory specified by the given
|
||||||
|
* system property
|
||||||
|
* @return The subdirectory of the given name found within the directory specified by the given
|
||||||
|
* systemProperty
|
||||||
|
*/
|
||||||
|
private Optional<File> getDirFromProperty(String propertyName, String subdirName) {
|
||||||
|
String path = System.getProperty(propertyName, "").trim();
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
File dir = new File(path, subdirName);
|
||||||
|
if (dir.isDirectory()) {
|
||||||
|
return Optional.of(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the subdirectory of the given name found within the directory specified by the given
|
||||||
|
* environment variable
|
||||||
|
*
|
||||||
|
* @param envName The name of the environment variable
|
||||||
|
* @param subdirName The name of the subdirectory within the directory specified by the given
|
||||||
|
* environment variable
|
||||||
|
* @return The subdirectory of the given name found within the directory specified by the given
|
||||||
|
* environment variable
|
||||||
|
*/
|
||||||
|
private Optional<File> getDirFromEnv(String envName, String subdirName) {
|
||||||
|
String path = System.getenv(envName);
|
||||||
|
if (path != null && !path.isBlank()) {
|
||||||
|
File dir = new File(path, subdirName);
|
||||||
|
if (dir.isDirectory()) {
|
||||||
|
return Optional.of(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the direct sub-directories of the given directory (non-recursive)
|
||||||
|
*
|
||||||
|
* @param dir The directory to get the sub-directories of
|
||||||
|
* @return The direct sub-directories of the given directory
|
||||||
|
*/
|
||||||
|
private List<File> getSubdirs(File dir) {
|
||||||
|
File[] listing = dir.listFiles(File::isDirectory);
|
||||||
|
return listing != null ? Arrays.asList(listing) : List.of();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,11 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package utility.application;
|
package utility.application;
|
||||||
|
|
||||||
import ghidra.framework.PluggableServiceRegistry;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import utilities.util.FileUtilities;
|
import ghidra.framework.PluggableServiceRegistry;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
public class ApplicationSettings {
|
public class ApplicationSettings {
|
||||||
static {
|
static {
|
||||||
|
@ -46,6 +46,13 @@ public class ApplicationSettings {
|
||||||
* application version.
|
* application version.
|
||||||
*/
|
*/
|
||||||
protected File doGetUserApplicationSettingsDirectory() {
|
protected File doGetUserApplicationSettingsDirectory() {
|
||||||
return FileUtilities.createTempDirectory("application.settings_");
|
try {
|
||||||
|
return ApplicationUtilities.getDefaultUserTempDir("application.settings");
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
Msg.error(ApplicationSettings.class, "Error creating application.settings directory",
|
||||||
|
e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,28 @@ import generic.jar.ResourceFile;
|
||||||
import ghidra.framework.*;
|
import ghidra.framework.*;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
|
import utilities.util.FileUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for default application things.
|
* Utility class for default application things.
|
||||||
*/
|
*/
|
||||||
public class ApplicationUtilities {
|
public class ApplicationUtilities {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of system property used to override the location of the user temporary directory
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_TEMP_DIR = "application.tempdir";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of system property used to override the location of the user cache directory
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_CACHE_DIR = "application.cachedir";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of system property used to override the location of the user settings directory
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_SETTINGS_DIR = "application.settingsdir";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for default application root directories.
|
* Searches for default application root directories.
|
||||||
*
|
*
|
||||||
|
@ -137,85 +153,145 @@ public class ApplicationUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default application's user temp directory.
|
* Gets the application's default user temp directory.
|
||||||
|
* <p>
|
||||||
|
* NOTE: This method does not create the directory.
|
||||||
*
|
*
|
||||||
* @param applicationProperties The application properties.
|
* @param applicationName The application name.
|
||||||
* @return The default application's user temp directory.
|
* @return The application's default user temp directory. The returned {@link File} will
|
||||||
* @throws FileNotFoundException if the user temp directory could not be determined.
|
* represent an absolute path.
|
||||||
|
* @throws FileNotFoundException if the absolute path of the user temp directory could not be
|
||||||
|
* determined.
|
||||||
*/
|
*/
|
||||||
public static File getDefaultUserTempDir(ApplicationProperties applicationProperties)
|
public static File getDefaultUserTempDir(String applicationName) throws FileNotFoundException {
|
||||||
throws FileNotFoundException {
|
|
||||||
String tmpdir = System.getProperty("java.io.tmpdir");
|
String appName = applicationName.toLowerCase();
|
||||||
if (tmpdir == null || tmpdir.isEmpty()) {
|
|
||||||
throw new FileNotFoundException("System property \"java.io.tmpdir\" is not set!");
|
// Look for Ghidra-specific system property
|
||||||
|
File tempOverrideDir = getSystemPropertyFile(PROPERTY_TEMP_DIR, false);
|
||||||
|
if (tempOverrideDir != null) {
|
||||||
|
return new File(tempOverrideDir, getUserSpecificDirName(tempOverrideDir, appName));
|
||||||
}
|
}
|
||||||
return new File(tmpdir,
|
|
||||||
SystemUtilities.getUserName() + "-" + applicationProperties.getApplicationName());
|
// Look for XDG environment variable
|
||||||
|
File xdgRuntimeDir = getEnvFile(XdgUtils.XDG_RUNTIME_DIR, false);
|
||||||
|
if (xdgRuntimeDir != null) {
|
||||||
|
return new File(xdgRuntimeDir, getUserSpecificDirName(xdgRuntimeDir, appName));
|
||||||
|
}
|
||||||
|
|
||||||
|
File javaTmpDir = getJavaTmpDir();
|
||||||
|
return new File(javaTmpDir, getUserSpecificDirName(javaTmpDir, appName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default application's user cache directory.
|
* Gets the application's default user cache directory.
|
||||||
|
* <p>
|
||||||
|
* NOTE: This method does not create the directory.
|
||||||
*
|
*
|
||||||
* @param applicationProperties The application properties.
|
* @param applicationProperties The application properties.
|
||||||
* @return The default application's user cache directory.
|
* @return The application's default user cache directory. The returned {@link File} will
|
||||||
* @throws FileNotFoundException if the user cache directory could not be determined.
|
* represent an absolute path.
|
||||||
|
* @throws FileNotFoundException if the absolute path of the user cache directory could not be
|
||||||
|
* determined.
|
||||||
*/
|
*/
|
||||||
public static File getDefaultUserCacheDir(ApplicationProperties applicationProperties)
|
public static File getDefaultUserCacheDir(ApplicationProperties applicationProperties)
|
||||||
throws FileNotFoundException {
|
throws FileNotFoundException {
|
||||||
|
|
||||||
// Look for preset cache directory
|
String appName = applicationProperties.getApplicationName().toLowerCase();
|
||||||
String cachedir = System.getProperty("application.cachedir", "").trim();
|
|
||||||
if (!cachedir.isEmpty()) {
|
// Look for Ghidra-specific system property
|
||||||
return new File(cachedir,
|
File cacheOverrideDir = getSystemPropertyFile(PROPERTY_CACHE_DIR, false);
|
||||||
SystemUtilities.getUserName() + "-" + applicationProperties.getApplicationName());
|
if (cacheOverrideDir != null) {
|
||||||
|
return new File(cacheOverrideDir, getUserSpecificDirName(cacheOverrideDir, appName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Windows specially
|
// Look for XDG environment variable
|
||||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
File xdgCacheHomeDir = getEnvFile(XdgUtils.XDG_CACHE_HOME, false);
|
||||||
File localAppDataDir = null;
|
if (xdgCacheHomeDir != null) {
|
||||||
String localAppDataDirPath = System.getenv("LOCALAPPDATA"); // e.g., /Users/myname/AppData/Local
|
return new File(xdgCacheHomeDir, getUserSpecificDirName(xdgCacheHomeDir, appName));
|
||||||
if (localAppDataDirPath != null && !localAppDataDirPath.isEmpty()) {
|
|
||||||
localAppDataDir = new File(localAppDataDirPath);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String userHome = System.getProperty("user.home");
|
|
||||||
if (userHome != null) {
|
|
||||||
localAppDataDir = new File(userHome, "AppData\\Local");
|
|
||||||
if (!localAppDataDir.isDirectory()) {
|
|
||||||
localAppDataDir = new File(userHome, "Local Settings");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (localAppDataDir != null && localAppDataDir.isDirectory()) {
|
|
||||||
return new File(localAppDataDir, applicationProperties.getApplicationName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use user temp directory if platform specific scheme does not exist above or it failed
|
// Use platform-specific default location
|
||||||
return getDefaultUserTempDir(applicationProperties);
|
String userDirName = SystemUtilities.getUserName() + "-" + appName;
|
||||||
|
return switch (OperatingSystem.CURRENT_OPERATING_SYSTEM) {
|
||||||
|
case WINDOWS -> new File(getEnvFile("LOCALAPPDATA", true), appName);
|
||||||
|
case LINUX -> new File("/var/tmp/" + userDirName);
|
||||||
|
case MAC_OS_X -> new File("/var/tmp/" + userDirName);
|
||||||
|
default -> throw new FileNotFoundException(
|
||||||
|
"Failed to find the user cache directory: Unsupported operating system.");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default application's user settings directory.
|
* Gets the application's default user settings directory.
|
||||||
|
* <p>
|
||||||
|
* NOTE: This method does not create the directory.
|
||||||
*
|
*
|
||||||
* @param applicationProperties The application properties.
|
* @param applicationProperties The application properties.
|
||||||
* @param installationDirectory The application installation directory.
|
* @param installationDirectory The application installation directory.
|
||||||
* @return The application's user settings directory.
|
* @return The application's default user settings directory. The returned {@link File} will
|
||||||
* @throws FileNotFoundException if the user settings directory could not be determined.
|
* represent an absolute path.
|
||||||
|
* @throws FileNotFoundException if the absolute path of the user settings directory could not
|
||||||
|
* be determined.
|
||||||
*/
|
*/
|
||||||
public static File getDefaultUserSettingsDir(ApplicationProperties applicationProperties,
|
public static File getDefaultUserSettingsDir(ApplicationProperties applicationProperties,
|
||||||
ResourceFile installationDirectory) throws FileNotFoundException {
|
ResourceFile installationDirectory) throws FileNotFoundException {
|
||||||
|
|
||||||
String homedir = System.getProperty("user.home");
|
String appName = applicationProperties.getApplicationName().toLowerCase();
|
||||||
if (homedir == null || homedir.isEmpty()) {
|
ApplicationIdentifier applicationIdentifier =
|
||||||
throw new FileNotFoundException("System property \"user.home\" is not set!");
|
new ApplicationIdentifier(applicationProperties);
|
||||||
|
String versionedName = applicationIdentifier.toString();
|
||||||
|
if (SystemUtilities.isInDevelopmentMode()) {
|
||||||
|
// Add the application's installation directory name to this variable, so that each
|
||||||
|
// branch's project user directory is unique.
|
||||||
|
versionedName += "_location_" + installationDirectory.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for Ghidra-specific system property
|
||||||
|
File settingsOverrideDir = getSystemPropertyFile(PROPERTY_SETTINGS_DIR, false);
|
||||||
|
if (settingsOverrideDir != null) {
|
||||||
|
return new File(settingsOverrideDir,
|
||||||
|
getUserSpecificDirName(settingsOverrideDir, appName) + "/" + versionedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for XDG environment variable
|
||||||
|
File xdgConfigHomeDir = getEnvFile(XdgUtils.XDG_CONFIG_HOME, false);
|
||||||
|
if (xdgConfigHomeDir != null) {
|
||||||
|
return new File(xdgConfigHomeDir,
|
||||||
|
getUserSpecificDirName(xdgConfigHomeDir, appName) + "/" + versionedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
File userHomeDir = getJavaUserHomeDir();
|
||||||
|
String versionedSubdir = appName + "/" + versionedName;
|
||||||
|
return switch (OperatingSystem.CURRENT_OPERATING_SYSTEM) {
|
||||||
|
case WINDOWS -> new File(getEnvFile("APPDATA", true), versionedSubdir);
|
||||||
|
case LINUX -> new File(userHomeDir, ".config/" + versionedSubdir);
|
||||||
|
case MAC_OS_X -> new File(userHomeDir, "Library/" + versionedSubdir);
|
||||||
|
default -> throw new FileNotFoundException(
|
||||||
|
"Failed to find the user settings directory: Unsupported operating system.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the application's legacy (pre-Ghida 11.1) user settings directory.
|
||||||
|
* <p>
|
||||||
|
* NOTE: This method does not create the directory.
|
||||||
|
*
|
||||||
|
* @param applicationProperties The application properties.
|
||||||
|
* @param installationDirectory The application installation directory.
|
||||||
|
* @return The application's legacy user settings directory. The returned {@link File} will
|
||||||
|
* represent an absolute path.
|
||||||
|
* @throws FileNotFoundException if the absolute path of the legacy user settings directory
|
||||||
|
* could not be determined.
|
||||||
|
*/
|
||||||
|
public static File getLegacyUserSettingsDir(ApplicationProperties applicationProperties,
|
||||||
|
ResourceFile installationDirectory) throws FileNotFoundException {
|
||||||
|
|
||||||
ApplicationIdentifier applicationIdentifier =
|
ApplicationIdentifier applicationIdentifier =
|
||||||
new ApplicationIdentifier(applicationProperties);
|
new ApplicationIdentifier(applicationProperties);
|
||||||
|
|
||||||
File userSettingsParentDir =
|
File userSettingsParentDir =
|
||||||
new File(homedir, "." + applicationIdentifier.getApplicationName());
|
new File(getJavaUserHomeDir(), "." + applicationIdentifier.getApplicationName());
|
||||||
|
|
||||||
String userSettingsDirName = "." + applicationIdentifier;
|
String userSettingsDirName = "." + applicationIdentifier;
|
||||||
|
|
||||||
|
@ -227,4 +303,108 @@ public class ApplicationUtilities {
|
||||||
|
|
||||||
return new File(userSettingsParentDir, userSettingsDirName);
|
return new File(userSettingsParentDir, userSettingsDirName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets Java's temporary directory in absolute form
|
||||||
|
*
|
||||||
|
* @return Java's temporary directory in absolute form
|
||||||
|
* @throws FileNotFoundException if Java's temporary directory is not defined or it is not an
|
||||||
|
* absolute path
|
||||||
|
*/
|
||||||
|
private static File getJavaTmpDir() throws FileNotFoundException {
|
||||||
|
return getSystemPropertyFile("java.io.tmpdir", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets Java's user home directory in absolute form
|
||||||
|
*
|
||||||
|
* @return Java's user home directory in absolute form
|
||||||
|
* @throws FileNotFoundException if Java's user home directory is not defined or it is not an
|
||||||
|
* absolute path
|
||||||
|
*/
|
||||||
|
private static File getJavaUserHomeDir() throws FileNotFoundException {
|
||||||
|
return getSystemPropertyFile("user.home", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the absolute form {@link File} value of the system property by the given name
|
||||||
|
*
|
||||||
|
* @param name The system property name
|
||||||
|
* @param required True if given system property is required to be set; otherwise, false
|
||||||
|
* @return The absolute form {@link File} value of the system property by the given name, or
|
||||||
|
* null if it isn't set
|
||||||
|
* @throws FileNotFoundException if the property value was not an absolute path, or if it is
|
||||||
|
* required and not set
|
||||||
|
*/
|
||||||
|
private static File getSystemPropertyFile(String name, boolean required)
|
||||||
|
throws FileNotFoundException {
|
||||||
|
String path = System.getProperty(name);
|
||||||
|
if (path == null || path.isBlank()) {
|
||||||
|
if (required) {
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"Required system property \"%s\" is not set!".formatted(name));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
path = path.trim();
|
||||||
|
File file = new File(path);
|
||||||
|
if (!file.isAbsolute()) {
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"System property \"%s\" is not an absolute path: \"%s\"".formatted(name, path));
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the absolute form {@link File} value of the environment variable by the given name
|
||||||
|
*
|
||||||
|
* @param name The environment variable name
|
||||||
|
* @param required True if the given environment variable is required to be set; otherwise,
|
||||||
|
* false
|
||||||
|
* @return The absolute form {@link File} value of the environment variable by the given name,
|
||||||
|
* or null if it isn't set
|
||||||
|
* @throws FileNotFoundException if the property value was not an absolute path, or if it is
|
||||||
|
* required and not set
|
||||||
|
*/
|
||||||
|
private static File getEnvFile(String name, boolean required) throws FileNotFoundException {
|
||||||
|
String path = System.getenv(name);
|
||||||
|
if (path == null || path.isBlank()) {
|
||||||
|
if (required) {
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"Required environment variable \"%s\" is not set!".formatted(name));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
path = path.trim();
|
||||||
|
File file = new File(path);
|
||||||
|
if (!file.isAbsolute()) {
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"Environment variable \"%s\" is not an absolute path: \"%s\"".formatted(name,
|
||||||
|
path));
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a directory name that can be used to create a user-specific sub-directory in
|
||||||
|
* {@code parentDir}. If the {@code parentDir} is contained within the user's home directory,
|
||||||
|
* the given {@code appName} can simply be used since it will live in a user-specific location.
|
||||||
|
* Otherwise, the user's name will get prepended to the {@code appName} so it does not collide
|
||||||
|
* with other users' directories in the shared directory space.
|
||||||
|
|
||||||
|
* @param parentDir The parent directory where we'd like to create a user-specific sub-directory
|
||||||
|
* @param appName The application name
|
||||||
|
* @return A directory name that can be used to create a user-specific sub-directory in
|
||||||
|
* {@code parentDir}.
|
||||||
|
* @throws FileNotFoundException if Java's user home directory is not defined or it is not an
|
||||||
|
* absolute path
|
||||||
|
*/
|
||||||
|
private static String getUserSpecificDirName(File parentDir, String appName)
|
||||||
|
throws FileNotFoundException {
|
||||||
|
String userSpecificDirName = appName;
|
||||||
|
if (!FileUtilities.isPathContainedWithin(getJavaUserHomeDir(), parentDir)) {
|
||||||
|
userSpecificDirName = SystemUtilities.getUserName() + "-" + appName;
|
||||||
|
}
|
||||||
|
return userSpecificDirName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package utility.application;
|
package utility.application;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ public class DummyApplicationLayout extends ApplicationLayout {
|
||||||
/**
|
/**
|
||||||
* Constructs a new dummy application layout object.
|
* Constructs a new dummy application layout object.
|
||||||
* @param name the application name
|
* @param name the application name
|
||||||
* @throws FileNotFoundException if there was a problem getting a user directory.
|
* @throws IOException if there was a problem getting a user directory.
|
||||||
*/
|
*/
|
||||||
public DummyApplicationLayout(String name) throws FileNotFoundException {
|
public DummyApplicationLayout(String name) throws IOException {
|
||||||
|
|
||||||
// Application properties
|
// Application properties
|
||||||
applicationProperties = new ApplicationProperties(name);
|
applicationProperties = new ApplicationProperties(name);
|
||||||
|
@ -48,7 +48,8 @@ public class DummyApplicationLayout extends ApplicationLayout {
|
||||||
applicationRootDirs.add(cwd);
|
applicationRootDirs.add(cwd);
|
||||||
|
|
||||||
// User directories
|
// User directories
|
||||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(applicationProperties);
|
userTempDir =
|
||||||
|
ApplicationUtilities.getDefaultUserTempDir(applicationProperties.getApplicationName());
|
||||||
|
|
||||||
extensionInstallationDirs = Collections.emptyList();
|
extensionInstallationDirs = Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* 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 utility.application;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to support the "XDG Base Directory Specification"
|
||||||
|
* <p>
|
||||||
|
* Based off version 0.8
|
||||||
|
*
|
||||||
|
* @see <a href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-0.8.html">basedir-spec-0.8.html</a>
|
||||||
|
*/
|
||||||
|
public class XdgUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $XDG_DATA_HOME defines the base directory relative to which user-specific data files should
|
||||||
|
* be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to
|
||||||
|
* $HOME/.local/share should be used.
|
||||||
|
*/
|
||||||
|
public static final String XDG_DATA_HOME = "XDG_DATA_HOME";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $XDG_CONFIG_HOME defines the base directory relative to which user-specific configuration
|
||||||
|
* files should be stored. If $XDG_CONFIG_HOME is either not set or empty, a default equal to
|
||||||
|
* $HOME/.config should be used.
|
||||||
|
*/
|
||||||
|
public static final String XDG_CONFIG_HOME = "XDG_CONFIG_HOME";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $XDG_STATE_HOME defines the base directory relative to which user-specific state files should
|
||||||
|
* be stored. If $XDG_STATE_HOME is either not set or empty, a default equal to
|
||||||
|
* $HOME/.local/state should be used.
|
||||||
|
*/
|
||||||
|
public static final String XDG_STATE_HOME = "XDG_STATE_HOME";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data
|
||||||
|
* files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS
|
||||||
|
* should be separated with a colon ':'.
|
||||||
|
*/
|
||||||
|
public static final String XDG_DATA_DIRS = "XDG_DATA_DIRS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $XDG_CONFIG_DIRS defines the preference-ordered set of base directories to search for
|
||||||
|
* configuration files in addition to the $XDG_CONFIG_HOME base directory. The directories in
|
||||||
|
* $XDG_CONFIG_DIRS should be separated with a colon ':'.
|
||||||
|
*/
|
||||||
|
public static final String XDG_CONFIG_DIRS = "XDG_CONFIG_DIRS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $XDG_CACHE_HOME defines the base directory relative to which user-specific non-essential
|
||||||
|
* data files should be stored. If $XDG_CACHE_HOME is either not set or empty, a default equal
|
||||||
|
* to $HOME/.cache should be used.
|
||||||
|
*/
|
||||||
|
public static final String XDG_CACHE_HOME = "XDG_CACHE_HOME";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential
|
||||||
|
* runtime files and other file objects (such as sockets, named pipes, ...) should be stored.
|
||||||
|
* The directory MUST be owned by the user, and he MUST be the only one having read and write
|
||||||
|
* access to it. Its Unix access mode MUST be 0700.
|
||||||
|
*/
|
||||||
|
public static final String XDG_RUNTIME_DIR = "XDG_RUNTIME_DIR";
|
||||||
|
}
|
|
@ -83,17 +83,47 @@ VMARGS_WINDOWS=-Dlog4j.skipJansi=true
|
||||||
# Ghidra does not use class data sharing, so explicitly turn it off to avoid the warning.
|
# Ghidra does not use class data sharing, so explicitly turn it off to avoid the warning.
|
||||||
VMARGS=-Xshare:off
|
VMARGS=-Xshare:off
|
||||||
|
|
||||||
# Persistent cache directory used by the application. This directory will be used to store
|
# Settings directory used by the application to store application settings and data that persist
|
||||||
# persistent application caches for all users. The default location for Mac/Linux is the same as
|
# between application sessions, system reboots, and periodic system cleanup. Overridden values
|
||||||
# specified by java.io.tmpdir property. The default location for Windows corresponds to the
|
# are required to be absolute paths. The current user name may be incorporated into the settings
|
||||||
# application local settings directory for the user (e.g., %LOCALAPPDATA%). If you wish to use a
|
# directory's name if the settings directory lives outside of the user's home directory. The
|
||||||
# directory with more storage or avoid system cleanups, it may be desirable to override the default
|
# settings directory will be selected based on the following rules, in order of precedence:
|
||||||
# location.
|
# 1. System.getProperty("application.settingsdir")/[user-]<application>/<application>_<version>
|
||||||
|
# 2. System.getenv("XDG_CONFIG_HOME")/[user-]<application>/<application>_<version>
|
||||||
|
# 3. A platform specific default location:
|
||||||
|
# - Windows: %APPDATA%\<application>\<application>_<version>
|
||||||
|
# - Linux: $HOME/.config/<application>/<application>_<version>
|
||||||
|
# - macOS: $HOME/Library/<application>/<application>_<version>
|
||||||
|
#VMARGS=-Dapplication.settingsdir=
|
||||||
|
|
||||||
|
# Cache directory used by the application to store cached application data that ideally will persist
|
||||||
|
# between application sessions and system reboots, but is not required to do so. Files stored in
|
||||||
|
# the cache directory may be numerous and/or large. Overridden values are required to be absolute
|
||||||
|
# paths. The current user name may be incorporated into the cache directory's name if the cache
|
||||||
|
# directory lives outside of the user's home directory. The cache directory will be selected based
|
||||||
|
# on the following rules, in order of precedence
|
||||||
|
# 1. System.getProperty("application.cachedir")/[user-]<application>
|
||||||
|
# 2. System.getenv("XDG_CACHE_HOME")/[user-]<application>
|
||||||
|
# 3. A platform specific default location:
|
||||||
|
# - Windows: %LOCALAPPDATA%\<application>
|
||||||
|
# - Linux: /var/tmp/<user>-<application>
|
||||||
|
# - macOS: /var/tmp/<user>-<application>
|
||||||
#VMARGS=-Dapplication.cachedir=
|
#VMARGS=-Dapplication.cachedir=
|
||||||
|
|
||||||
# Temporary directory used by the application. This directory will be used for all temporary files
|
# Temporary directory used by the application to store short-lived files that are not required to
|
||||||
# and may also be used for the persistent user cache directory <java.io.tmpdir>/<username>-Ghidra.
|
# persist between application sessions. Overridden values are required to be absolute paths. The
|
||||||
# The specified directory must exist and have appropriate read/write/execute permissions
|
# current user name may be incorporated into the temporary directory's name if the temporary
|
||||||
|
# directory lives outside of the user's home directory. The temporary directory will be selected
|
||||||
|
# based on the following rules, in order of precedence:
|
||||||
|
# 1. System.getProperty("application.tempdir")/[user-]<application>
|
||||||
|
# 2. System.getenv("XDG_RUNTIME_DIR")/[user-]<application>
|
||||||
|
# 3. System.getProperty("java.io.tmpdir")/[user-]<application>
|
||||||
|
# Unless overridden below, the "java.io.tmpdir" system property typically defaults to the following
|
||||||
|
# platform specific locations:
|
||||||
|
# - Windows: %TEMP%
|
||||||
|
# - Linux: /tmp
|
||||||
|
# - macOS: $TMPDIR
|
||||||
|
#VMARGS=-Dapplication.tempdir=
|
||||||
#VMARGS=-Djava.io.tmpdir=
|
#VMARGS=-Djava.io.tmpdir=
|
||||||
|
|
||||||
# Disable alternating row colors in tables
|
# Disable alternating row colors in tables
|
||||||
|
|
21
Ghidra/RuntimeScripts/Linux/support/ghidraClean
Executable file
21
Ghidra/RuntimeScripts/Linux/support/ghidraClean
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------------------------
|
||||||
|
# Ghidra-Clean
|
||||||
|
# An interactive utility to discover and delete artifacts that Ghidra lays down on the filesystem.
|
||||||
|
#---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of
|
||||||
|
# the physical memory available to the OS. Uncomment MAXMEM setting if non-default value is needed.
|
||||||
|
#MAXMEM=1G
|
||||||
|
|
||||||
|
VMARG_LIST="-Djava.awt.headless=true "
|
||||||
|
|
||||||
|
# Resolve symbolic link if present and get the directory this script lives in.
|
||||||
|
# NOTE: "readlink -f" is best but works on Linux only, "readlink" will only work if your PWD
|
||||||
|
# contains the link you are calling (which is the best we can do on macOS), and the "echo" is the
|
||||||
|
# fallback, which doesn't attempt to do anything with links.
|
||||||
|
SCRIPT_FILE="$(readlink -f "$0" 2>/dev/null || readlink "$0" 2>/dev/null || echo "$0")"
|
||||||
|
SCRIPT_DIR="${SCRIPT_FILE%/*}"
|
||||||
|
|
||||||
|
"${SCRIPT_DIR}"/launch.sh fg jre Ghidra-Clean "$MAXMEM" "$VMARG_LIST" utility.application.AppCleaner Ghidra
|
9
Ghidra/RuntimeScripts/Windows/support/ghidraClean.bat
Normal file
9
Ghidra/RuntimeScripts/Windows/support/ghidraClean.bat
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
:: Ghidra-Clean
|
||||||
|
:: An interactive utility to discover and delete artifacts that Ghidra lays down on the filesystem.
|
||||||
|
|
||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
set VMARG_LIST=-Djava.awt.headless=true
|
||||||
|
|
||||||
|
call "%~dp0launch.bat" fg jdk Ghidra-Clean "" "" utility.application.AppCleaner Ghidra
|
|
@ -21,6 +21,7 @@ Linux/support/buildGhidraJar||GHIDRA||||END|
|
||||||
Linux/support/buildNatives||GHIDRA||||END|
|
Linux/support/buildNatives||GHIDRA||||END|
|
||||||
Linux/support/convertStorage||GHIDRA||||END|
|
Linux/support/convertStorage||GHIDRA||||END|
|
||||||
Linux/support/gdbGADPServerRun||GHIDRA||||END|
|
Linux/support/gdbGADPServerRun||GHIDRA||||END|
|
||||||
|
Linux/support/ghidraClean||GHIDRA||||END|
|
||||||
Linux/support/ghidraDebug||GHIDRA||||END|
|
Linux/support/ghidraDebug||GHIDRA||||END|
|
||||||
Linux/support/pythonRun||GHIDRA||||END|
|
Linux/support/pythonRun||GHIDRA||||END|
|
||||||
Linux/support/sleigh||GHIDRA||||END|
|
Linux/support/sleigh||GHIDRA||||END|
|
||||||
|
@ -40,6 +41,7 @@ Windows/support/createPdbXmlFiles.bat||GHIDRA||||END|
|
||||||
Windows/support/dbgengGADPServerRun.bat||GHIDRA||||END|
|
Windows/support/dbgengGADPServerRun.bat||GHIDRA||||END|
|
||||||
Windows/support/dbgmodelGADPServerRun.bat||GHIDRA||||END|
|
Windows/support/dbgmodelGADPServerRun.bat||GHIDRA||||END|
|
||||||
Windows/support/ghidra.ico||GHIDRA||||END|
|
Windows/support/ghidra.ico||GHIDRA||||END|
|
||||||
|
Windows/support/ghidraClean.bat||GHIDRA||||END|
|
||||||
Windows/support/ghidraDebug.bat||GHIDRA||||END|
|
Windows/support/ghidraDebug.bat||GHIDRA||||END|
|
||||||
Windows/support/launch.bat||GHIDRA||||END|
|
Windows/support/launch.bat||GHIDRA||||END|
|
||||||
Windows/support/pythonRun.bat||GHIDRA||||END|
|
Windows/support/pythonRun.bat||GHIDRA||||END|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import docking.wizard.WizardManager;
|
||||||
import docking.wizard.WizardPanel;
|
import docking.wizard.WizardPanel;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.app.plugin.core.archive.RestoreDialog;
|
import ghidra.app.plugin.core.archive.RestoreDialog;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.data.DefaultProjectData;
|
import ghidra.framework.data.DefaultProjectData;
|
||||||
import ghidra.framework.data.GhidraFileData;
|
import ghidra.framework.data.GhidraFileData;
|
||||||
import ghidra.framework.main.*;
|
import ghidra.framework.main.*;
|
||||||
|
@ -56,7 +57,6 @@ import resources.MultiIcon;
|
||||||
|
|
||||||
public class FrontEndPluginScreenShots extends GhidraScreenShotGenerator {
|
public class FrontEndPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
private static final String OTHER_PROJECT = "Other_Project";
|
private static final String OTHER_PROJECT = "Other_Project";
|
||||||
private final static String TEMP_DIR = System.getProperty("java.io.tmpdir");
|
|
||||||
Icon icon = (Icon) getInstanceField("CONVERT_ICON", ProjectInfoDialog.class);
|
Icon icon = (Icon) getInstanceField("CONVERT_ICON", ProjectInfoDialog.class);
|
||||||
|
|
||||||
public FrontEndPluginScreenShots() {
|
public FrontEndPluginScreenShots() {
|
||||||
|
@ -659,6 +659,7 @@ public class FrontEndPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
@Test
|
@Test
|
||||||
public void testViewOtherProjects()
|
public void testViewOtherProjects()
|
||||||
throws IOException, LockException, InvalidNameException, CancelledException {
|
throws IOException, LockException, InvalidNameException, CancelledException {
|
||||||
|
String TEMP_DIR = Application.getUserTempDirectory().getAbsolutePath();
|
||||||
|
|
||||||
Project project = env.getProject();
|
Project project = env.getProject();
|
||||||
program = env.getProgram("WinHelloCPP.exe");
|
program = env.getProgram("WinHelloCPP.exe");
|
||||||
|
@ -692,6 +693,7 @@ public class FrontEndPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
@Test
|
@Test
|
||||||
public void testLinkOtherProject()
|
public void testLinkOtherProject()
|
||||||
throws IOException, LockException, InvalidNameException, CancelledException {
|
throws IOException, LockException, InvalidNameException, CancelledException {
|
||||||
|
String TEMP_DIR = Application.getUserTempDirectory().getAbsolutePath();
|
||||||
|
|
||||||
Project project = env.getProject();
|
Project project = env.getProject();
|
||||||
program = env.getProgram("WinHelloCPP.exe");
|
program = env.getProgram("WinHelloCPP.exe");
|
||||||
|
|
|
@ -30,6 +30,7 @@ import javax.rmi.ssl.SslRMIClientSocketFactory;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
|
||||||
import generic.test.*;
|
import generic.test.*;
|
||||||
|
import ghidra.framework.Application;
|
||||||
import ghidra.framework.client.*;
|
import ghidra.framework.client.*;
|
||||||
import ghidra.framework.data.ContentHandler;
|
import ghidra.framework.data.ContentHandler;
|
||||||
import ghidra.framework.data.DomainObjectAdapter;
|
import ghidra.framework.data.DomainObjectAdapter;
|
||||||
|
@ -347,7 +348,7 @@ public class ServerTestUtil {
|
||||||
|
|
||||||
private static synchronized File getPkiTestDirectory() {
|
private static synchronized File getPkiTestDirectory() {
|
||||||
if (testPkiDirectory == null) {
|
if (testPkiDirectory == null) {
|
||||||
testPkiDirectory = new File(System.getProperty("java.io.tmpdir"), "test-pki");
|
testPkiDirectory = new File(Application.getUserTempDirectory(), "test-pki");
|
||||||
FileUtilities.deleteDir(testPkiDirectory);
|
FileUtilities.deleteDir(testPkiDirectory);
|
||||||
testPkiDirectory.mkdirs();
|
testPkiDirectory.mkdirs();
|
||||||
|
|
||||||
|
|
|
@ -359,6 +359,23 @@ public class JavaConfig {
|
||||||
*/
|
*/
|
||||||
private void initJavaHomeSaveFile(File installDir) throws FileNotFoundException {
|
private void initJavaHomeSaveFile(File installDir) throws FileNotFoundException {
|
||||||
boolean isDev = new File(installDir, "build.gradle").isFile();
|
boolean isDev = new File(installDir, "build.gradle").isFile();
|
||||||
|
String appName = applicationName.toLowerCase();
|
||||||
|
|
||||||
|
String userSettingsDirName = appName + "_" + applicationVersion + "_" +
|
||||||
|
applicationReleaseName.replaceAll("\\s", "").toUpperCase();
|
||||||
|
if (isDev) {
|
||||||
|
userSettingsDirName += "_location_" + installDir.getParentFile().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
File userSettingsDir = null;
|
||||||
|
|
||||||
|
// Look for XDG environment variable
|
||||||
|
String xdgConfigHomeDirStr = System.getenv("XDG_CONFIG_HOME");
|
||||||
|
if (xdgConfigHomeDirStr != null && !xdgConfigHomeDirStr.isEmpty()) {
|
||||||
|
userSettingsDir = new File(xdgConfigHomeDirStr, appName + "/" + userSettingsDirName);
|
||||||
|
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure there is a user home directory (there definitely should be)
|
// Ensure there is a user home directory (there definitely should be)
|
||||||
String userHomeDirPath = System.getProperty("user.home");
|
String userHomeDirPath = System.getProperty("user.home");
|
||||||
|
@ -370,18 +387,27 @@ public class JavaConfig {
|
||||||
throw new FileNotFoundException("User home directory does not exist: " + userHomeDir);
|
throw new FileNotFoundException("User home directory does not exist: " + userHomeDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the java home save file from user home directory (it might not exist yet).
|
switch (JavaFinder.getCurrentPlatform()) {
|
||||||
File userSettingsParentDir =
|
case WINDOWS:
|
||||||
new File(userHomeDir, "." + applicationName.replaceAll("\\s", "").toLowerCase());
|
String localAppDataDirPath = System.getenv("APPDATA");
|
||||||
|
if (localAppDataDirPath == null || localAppDataDirPath.trim().isEmpty()) {
|
||||||
String userSettingsDirName = userSettingsParentDir.getName() + "_" + applicationVersion +
|
throw new FileNotFoundException("\"APPDATA\" environment variable is not set");
|
||||||
"_" + applicationReleaseName.replaceAll("\\s", "").toUpperCase();
|
}
|
||||||
|
userSettingsDir =
|
||||||
if (isDev) {
|
new File(localAppDataDirPath, appName + "/" + userSettingsDirName);
|
||||||
userSettingsDirName += "_location_" + installDir.getParentFile().getName();
|
break;
|
||||||
|
case LINUX:
|
||||||
|
userSettingsDir =
|
||||||
|
new File(userHomeDir, ".config/" + appName + "/" + userSettingsDirName);
|
||||||
|
break;
|
||||||
|
case MACOS:
|
||||||
|
userSettingsDir =
|
||||||
|
new File(userHomeDir, "Library/" + appName + "/" + userSettingsDirName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"Failed to find the user settings directory: Unsupported operating system.");
|
||||||
}
|
}
|
||||||
|
|
||||||
File userSettingsDir = new File(userSettingsParentDir, userSettingsDirName);
|
|
||||||
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
|
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue