mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-09-20 09:31:47 +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.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();
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import ghidra.app.context.*;
|
|||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.plugin.ProgramPlugin;
|
||||
import ghidra.app.services.GoToService;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.plugintool.PluginInfo;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
|
@ -190,7 +191,7 @@ public class ShowInstructionInfoPlugin extends ProgramPlugin {
|
|||
private File writeWrapperFile(URL fileURL) throws IOException {
|
||||
File f;
|
||||
if (manualWrapperFiles.size() < MAX_MANUAL_WRAPPER_FILE_COUNT) {
|
||||
f = File.createTempFile("pdfView", ".html");
|
||||
f = Application.createTempFile("pdfView", ".html");
|
||||
f.deleteOnExit();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -24,6 +24,7 @@ import generic.theme.GThemeDefaults.Colors;
|
|||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.app.util.cparser.CPP.PreProcessor;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.framework.store.LockException;
|
||||
import ghidra.program.model.data.*;
|
||||
|
@ -535,7 +536,7 @@ public class CParserUtils {
|
|||
String fName = dtMgr.getName();
|
||||
|
||||
// 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 (dtMgr instanceof FileDataTypeManager) {
|
||||
path = ((FileDataTypeManager) dtMgr).getPath();
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.program.database.mem.AddressSourceInfo;
|
||||
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.
|
||||
// This is done to ensure a random access write failure doesn't corrupt a file the user
|
||||
// might be overwriting.
|
||||
File tempFile = File.createTempFile("ghidra_export_", null);
|
||||
File tempFile = Application.createTempFile("ghidra_export_", null);
|
||||
try (OutputStream out = new FileOutputStream(tempFile, false)) {
|
||||
FileUtilities.copyStreamToStream(new FileBytesInputStream(fileBytes, true), out,
|
||||
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.relocation.*;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.store.LockException;
|
||||
import ghidra.program.database.mem.FileBytes;
|
||||
|
@ -1606,7 +1607,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
Address debugDataAddr = findLoadAddress(debugDataSection, 0);
|
||||
if (debugDataAddr != null) {
|
||||
try {
|
||||
File tmpFile = File.createTempFile("ghidra_gnu_debugdata", null);
|
||||
File tmpFile = Application.createTempFile("ghidra_gnu_debugdata", null);
|
||||
try (ByteProviderWrapper compressedDebugDataBP = new ByteProviderWrapper(
|
||||
new MemoryByteProvider(memory, debugDataAddr), 0, debugDataSection.getSize());
|
||||
XZCompressorInputStream xzIS =
|
||||
|
|
|
@ -25,6 +25,7 @@ import db.DBHandle;
|
|||
import ghidra.app.util.Option;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.framework.model.Project;
|
||||
import ghidra.framework.store.db.PackedDatabase;
|
||||
|
@ -138,7 +139,7 @@ public class GdtLoader implements Loader {
|
|||
|
||||
private static File createTmpFile(ByteProvider provider, TaskMonitor monitor)
|
||||
throws IOException {
|
||||
File tmpFile = File.createTempFile("ghidra_gdt_loader", null);
|
||||
File tmpFile = Application.createTempFile("ghidra_gdt_loader", null);
|
||||
try (InputStream is = provider.getInputStream(0);
|
||||
FileOutputStream fos = new FileOutputStream(tmpFile)) {
|
||||
FileUtilities.copyStreamToStream(is, fos, monitor);
|
||||
|
|
|
@ -25,6 +25,7 @@ import db.DBHandle;
|
|||
import ghidra.app.util.Option;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.framework.model.Project;
|
||||
import ghidra.framework.store.db.PackedDatabase;
|
||||
|
@ -148,7 +149,7 @@ public class GzfLoader implements Loader {
|
|||
|
||||
private static File createTmpFile(ByteProvider provider, TaskMonitor monitor)
|
||||
throws IOException {
|
||||
File tmpFile = File.createTempFile("ghidra_gzf_loader", null);
|
||||
File tmpFile = Application.createTempFile("ghidra_gzf_loader", null);
|
||||
try (InputStream is = provider.getInputStream(0);
|
||||
FileOutputStream fos = new FileOutputStream(tmpFile)) {
|
||||
FileUtilities.copyStreamToStream(is, fos, monitor);
|
||||
|
|
|
@ -577,7 +577,7 @@ public class FileSystemService {
|
|||
public File createPlaintextTempFile(ByteProvider provider, String filenamePrefix,
|
||||
TaskMonitor monitor) throws IOException {
|
||||
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.initialize(provider.length());
|
||||
try {
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Comparator;
|
|||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.CryptoException;
|
||||
|
@ -138,7 +139,7 @@ public abstract class GFileSystemBase implements GFileSystem {
|
|||
protected void debug(byte[] bytes, String fileName) {
|
||||
try {
|
||||
if (SystemUtilities.isInDevelopmentMode()) {
|
||||
File file = File.createTempFile(fileName, ".ghidra.tmp");
|
||||
File file = Application.createTempFile(fileName, ".ghidra.tmp");
|
||||
OutputStream out = new FileOutputStream(file);
|
||||
try {
|
||||
out.write(bytes);
|
||||
|
|
|
@ -28,8 +28,7 @@ import ghidra.app.util.importer.AutoImporter;
|
|||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.opinion.LoadException;
|
||||
import ghidra.app.util.opinion.LoadResults;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.HeadlessGhidraApplicationConfiguration;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
|
@ -38,6 +37,7 @@ import ghidra.program.util.DefaultLanguageService;
|
|||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import utility.application.ApplicationLayout;
|
||||
import utility.application.ApplicationUtilities;
|
||||
|
||||
/**
|
||||
* 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()) {
|
||||
ApplicationLayout layout;
|
||||
try {
|
||||
layout =
|
||||
new GhidraTestApplicationLayout(new File(System.getProperty("java.io.tmpdir")));
|
||||
layout = new GhidraTestApplicationLayout(ApplicationUtilities.getDefaultUserTempDir(
|
||||
new ApplicationProperties(ApplicationUtilities.findDefaultApplicationRootDirs())
|
||||
.getApplicationName()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GhidraException(e);
|
||||
|
@ -184,8 +185,7 @@ public class ProgramExaminer {
|
|||
int txID = program.startTransaction("find images");
|
||||
try {
|
||||
EmbeddedMediaAnalyzer imageAnalyzer = new EmbeddedMediaAnalyzer();
|
||||
imageAnalyzer.added(program, program.getMemory(), TaskMonitor.DUMMY,
|
||||
messageLog);
|
||||
imageAnalyzer.added(program, program.getMemory(), TaskMonitor.DUMMY, messageLog);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// using Dummy, can't happen
|
||||
|
|
|
@ -428,7 +428,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||
// return; // already enabled by batch test environment
|
||||
// }
|
||||
//
|
||||
// String tmpDir = System.getProperty("java.io.tmpdir");
|
||||
// File tmpDir = Application.getUserTempDirectory();
|
||||
// File cacheDir = new File(tmpDir, "EmulatorDBTestCache");
|
||||
// if (cacheDir.exists() && !FileUtilities.deleteDir(cacheDir)) {
|
||||
// Msg.warn(ProcessorEmulatorTestAdapter.class,
|
||||
|
|
|
@ -704,7 +704,7 @@ public class GhidraJarBuilder implements GhidraLaunchable {
|
|||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
File tempFile = File.createTempFile("jarBuilder", "treeIDX");
|
||||
File tempFile = Application.createTempFile("jarBuilder", "treeIDX");
|
||||
classTree.trim();
|
||||
classTree.saveFile(tempFile);
|
||||
try {
|
||||
|
|
|
@ -54,6 +54,7 @@ import ghidra.app.plugin.core.datamgr.tree.DataTypeNode;
|
|||
import ghidra.app.plugin.core.datamgr.util.DataTypeChooserDialog;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.app.services.ProgramManager;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.database.data.ProgramDataTypeManager;
|
||||
|
@ -723,7 +724,7 @@ public class DataTypeSelectionDialogTest extends AbstractGhidraHeadedIntegration
|
|||
DataTypeManagerHandler dataTypeManagerHandler = plugin.getDataTypeManagerHandler();
|
||||
File tempArchiveFile;
|
||||
try {
|
||||
tempArchiveFile = File.createTempFile("TestFileArchive", ".gdt");
|
||||
tempArchiveFile = Application.createTempFile("TestFileArchive", ".gdt");
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
package db;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -240,7 +241,7 @@ public class DbViewer extends JFrame {
|
|||
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");
|
||||
DockingApplicationConfiguration configuration = new DockingApplicationConfiguration();
|
||||
configuration.setShowSplashScreen(false);
|
||||
|
|
|
@ -27,6 +27,7 @@ import ghidra.formats.gfilesystem.*;
|
|||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileAttribute;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import utilities.util.FileUtilities;
|
||||
|
@ -76,7 +77,7 @@ public class JavaClassDecompilerFileSystem implements GFileSystem {
|
|||
throws CancelledException, IOException {
|
||||
File tempDir = null;
|
||||
try {
|
||||
tempDir = FileUtilities.createTempDirectory("JavaClassDecompilerFileSystem");
|
||||
tempDir = new File(Application.getUserTempDirectory(), "JavaClassDecompilerFileSystem");
|
||||
|
||||
File tempClassFile = new File(tempDir, containerFSRL.getName());
|
||||
FSUtilities.copyByteProviderToFile(provider, tempClassFile, monitor);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package ghidra.server.remote;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
|
@ -34,10 +33,10 @@ public class GhidraServerApplicationLayout extends ApplicationLayout {
|
|||
/**
|
||||
* 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 the application properties.
|
||||
* @throws IOException if there was a problem getting a user directory or the application
|
||||
* properties.
|
||||
*/
|
||||
public GhidraServerApplicationLayout() throws FileNotFoundException, IOException {
|
||||
public GhidraServerApplicationLayout() throws IOException {
|
||||
|
||||
// Application root directories
|
||||
applicationRootDirs = ApplicationUtilities.findDefaultApplicationRootDirs();
|
||||
|
@ -56,7 +55,8 @@ public class GhidraServerApplicationLayout extends ApplicationLayout {
|
|||
extensionInstallationDirs = Collections.emptyList();
|
||||
|
||||
// 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 = ModuleUtilities.findModules(applicationRootDirs,
|
||||
|
|
|
@ -21,8 +21,7 @@ import java.util.*;
|
|||
import db.DBChangeSet;
|
||||
import db.DBHandle;
|
||||
import db.buffers.LocalBufferFile.BufferFileFilter;
|
||||
import ghidra.framework.ShutdownHookRegistry;
|
||||
import ghidra.framework.ShutdownPriority;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.datastruct.ObjectArray;
|
||||
|
@ -2049,7 +2048,7 @@ public class BufferMgr {
|
|||
}
|
||||
|
||||
public static void cleanupOldCacheFiles() {
|
||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
File tmpDir = Application.getUserTempDirectory();
|
||||
File[] cacheFiles =
|
||||
tmpDir.listFiles(new BufferFileFilter(CACHE_FILE_PREFIX, CACHE_FILE_EXT));
|
||||
if (cacheFiles == null) {
|
||||
|
|
|
@ -18,6 +18,7 @@ package db.buffers;
|
|||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.BigEndianDataConverter;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.datastruct.IntSet;
|
||||
|
@ -197,8 +198,7 @@ public class LocalBufferFile implements BufferFile {
|
|||
this.blockSize = bufferSize + BUFFER_PREFIX_SIZE;
|
||||
this.readOnly = false;
|
||||
this.temporary = true;
|
||||
file = File.createTempFile(tmpPrefix, tmpExtension);
|
||||
// file.deleteOnExit();
|
||||
file = Application.createTempFile(tmpPrefix, tmpExtension);
|
||||
raf = new RandomAccessFile(file, "rw");
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Random;
|
|||
import org.junit.Assert;
|
||||
|
||||
import db.buffers.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -815,7 +816,7 @@ public class DBTestUtils {
|
|||
public static DBHandle cloneDbHandle(DBHandle dbh) throws IOException {
|
||||
|
||||
try {
|
||||
File tmpFile = File.createTempFile("tmp", ".db");
|
||||
File tmpFile = Application.createTempFile("tmp", ".db");
|
||||
tmpFile.delete();
|
||||
|
||||
LocalBufferFile bf = new LocalBufferFile(tmpFile, dbh.getBufferSize());
|
||||
|
|
|
@ -24,6 +24,7 @@ import db.Database;
|
|||
import db.buffers.BufferFileManager;
|
||||
import db.buffers.LocalManagedBufferFile;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.store.FolderItem;
|
||||
import ghidra.framework.store.db.PackedDatabaseCache.CachedDB;
|
||||
import ghidra.framework.store.local.*;
|
||||
|
@ -32,7 +33,6 @@ import ghidra.util.datastruct.WeakDataStructureFactory;
|
|||
import ghidra.util.datastruct.WeakSet;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
/**
|
||||
|
@ -364,7 +364,7 @@ public class PackedDatabase extends Database {
|
|||
*/
|
||||
private static File createDBDir() throws IOException {
|
||||
|
||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
File tmpDir = Application.getUserTempDirectory();
|
||||
int tries = 0;
|
||||
while (tries++ < 10) {
|
||||
File dir = new File(tmpDir, TEMPDB_DIR_PREFIX + getRandomString() + TEMPDB_DIR_EXT);
|
||||
|
@ -620,7 +620,7 @@ public class PackedDatabase extends Database {
|
|||
InputStream itemIn = null;
|
||||
File tmpFile = null;
|
||||
try {
|
||||
tmpFile = File.createTempFile("pack", ".tmp");
|
||||
tmpFile = Application.createTempFile("pack", ".tmp");
|
||||
tmpFile.delete();
|
||||
dbh.saveAs(tmpFile, false, monitor);
|
||||
itemIn = new BufferedInputStream(new FileInputStream(tmpFile));
|
||||
|
@ -838,7 +838,7 @@ public class PackedDatabase extends Database {
|
|||
*/
|
||||
public static void cleanupOldTempDatabases() {
|
||||
|
||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
File tmpDir = Application.getUserTempDirectory();
|
||||
File[] tempDbs = tmpDir.listFiles((FileFilter) file -> {
|
||||
String name = file.getName();
|
||||
if (file.isDirectory()) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.logging.log4j.Logger;
|
|||
import db.DBHandle;
|
||||
import db.Database;
|
||||
import db.buffers.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.store.local.ItemSerializer;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
@ -417,7 +418,8 @@ public class VersionedDatabase extends Database {
|
|||
else {
|
||||
BufferFile bf = openBufferFile(version, -1);
|
||||
try {
|
||||
File tmpFile = File.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
||||
File tmpFile =
|
||||
Application.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
||||
tmpFile.delete();
|
||||
BufferFile tmpBf = new LocalBufferFile(tmpFile, bf.getBufferSize());
|
||||
boolean success = false;
|
||||
|
@ -425,18 +427,10 @@ public class VersionedDatabase extends Database {
|
|||
LocalBufferFile.copyFile(bf, tmpBf, null, monitor);
|
||||
tmpBf.close();
|
||||
|
||||
InputStream itemIn = new FileInputStream(tmpFile);
|
||||
try {
|
||||
try (InputStream itemIn = new FileInputStream(tmpFile)) {
|
||||
ItemSerializer.outputItem(name, contentType, filetype, tmpFile.length(),
|
||||
itemIn, outputFile, monitor);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
itemIn.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.framework.store.remote;
|
|||
import java.io.*;
|
||||
|
||||
import db.buffers.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.client.RepositoryAdapter;
|
||||
import ghidra.framework.remote.RepositoryItem;
|
||||
import ghidra.framework.store.DatabaseItem;
|
||||
|
@ -101,25 +102,17 @@ public class RemoteDatabaseItem extends RemoteFolderItem implements DatabaseItem
|
|||
|
||||
BufferFile bf = repository.openDatabase(parentPath, itemName, version, -1);
|
||||
try {
|
||||
File tmpFile = File.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
||||
File tmpFile = Application.createTempFile("ghidra", LocalBufferFile.TEMP_FILE_EXT);
|
||||
tmpFile.delete();
|
||||
BufferFile tmpBf = new LocalBufferFile(tmpFile, bf.getBufferSize());
|
||||
try {
|
||||
LocalBufferFile.copyFile(bf, tmpBf, null, monitor);
|
||||
tmpBf.close();
|
||||
|
||||
InputStream itemIn = new FileInputStream(tmpFile);
|
||||
try {
|
||||
try (InputStream itemIn = new FileInputStream(tmpFile)) {
|
||||
ItemSerializer.outputItem(getName(), getContentType(), DATABASE_FILE_TYPE,
|
||||
tmpFile.length(), itemIn, outputFile, monitor);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
itemIn.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
tmpBf.close();
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
package generic.application;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -59,9 +59,9 @@ public class GenericApplicationLayout extends ApplicationLayout {
|
|||
*
|
||||
* @param name The name 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));
|
||||
}
|
||||
|
||||
|
@ -70,10 +70,10 @@ public class GenericApplicationLayout extends ApplicationLayout {
|
|||
* properties. The default Ghidra application root directory(s) will be used.
|
||||
*
|
||||
* @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)
|
||||
throws FileNotFoundException {
|
||||
throws IOException {
|
||||
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
|
||||
* installation root.
|
||||
* @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,
|
||||
ApplicationProperties applicationProperties) throws FileNotFoundException {
|
||||
ApplicationProperties applicationProperties) throws IOException {
|
||||
|
||||
this.applicationProperties = Objects.requireNonNull(applicationProperties);
|
||||
this.applicationRootDirs = applicationRootDirs;
|
||||
|
@ -117,7 +117,8 @@ public class GenericApplicationLayout extends ApplicationLayout {
|
|||
modules = Collections.unmodifiableMap(allModules);
|
||||
|
||||
// User directories
|
||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(applicationProperties);
|
||||
userTempDir =
|
||||
ApplicationUtilities.getDefaultUserTempDir(applicationProperties.getApplicationName());
|
||||
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(applicationProperties,
|
||||
applicationInstallationDir);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package generic.test;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -35,6 +36,7 @@ import ghidra.util.SystemUtilities;
|
|||
import ghidra.util.UniversalIdGenerator;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import utility.application.ApplicationUtilities;
|
||||
|
||||
/**
|
||||
* 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
|
||||
// custom temp directory.
|
||||
//
|
||||
return System.getProperty("java.io.tmpdir") + File.separator + "Ghidra_test_" +
|
||||
UUID.randomUUID() + File.separator + "temp.data";
|
||||
try {
|
||||
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() {
|
||||
//
|
||||
// Create a unique name based upon the repo from which we are running.
|
||||
//
|
||||
File tempDir = TestApplicationUtils.getUniqueTempFolder();
|
||||
return tempDir.getAbsolutePath();
|
||||
File tempDir = TestApplicationUtils.getUniqueTempDir();
|
||||
return tempDir.getPath();
|
||||
}
|
||||
|
||||
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
|
||||
* 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>
|
||||
* <p>
|
||||
* 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
|
||||
* current test name, as well as any data added by
|
||||
* {@link File#createTempFile(String, String)}.
|
||||
* {@link File#createTempFile(String, String, File)}.
|
||||
* <p>
|
||||
* 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
|
||||
|
|
|
@ -29,6 +29,7 @@ import util.CollectionUtils;
|
|||
import utilities.util.FileUtilities;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
import utility.application.ApplicationLayout;
|
||||
import utility.application.ApplicationUtilities;
|
||||
import utility.module.ModuleUtilities;
|
||||
|
||||
/**
|
||||
|
@ -667,7 +668,6 @@ public class 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
|
||||
* system cleanup of unused temp files.
|
||||
* This directory is specific to the application name but not the version.
|
||||
|
@ -677,15 +677,22 @@ public class Application {
|
|||
* @return temp directory
|
||||
*/
|
||||
public static File getUserTempDirectory() {
|
||||
checkAppInitialized();
|
||||
return app.layout.getUserTempDir();
|
||||
try {
|
||||
// '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.
|
||||
* The intention is for directory contents to be preserved, however the
|
||||
* 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.
|
||||
* Resources stored within this directory should utilize some
|
||||
* form of access locking and/or unique naming.
|
||||
|
@ -696,6 +703,24 @@ public class Application {
|
|||
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
|
||||
* the top-level directory of a module.
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package ghidra.framework;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
@ -24,6 +23,8 @@ import org.apache.logging.log4j.Logger;
|
|||
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
import util.CollectionUtils;
|
||||
import utility.application.ApplicationLayout;
|
||||
import utility.application.ApplicationUtilities;
|
||||
|
||||
public class GenericRunInfo {
|
||||
|
||||
|
@ -42,10 +43,23 @@ public class GenericRunInfo {
|
|||
* <b>Note: </b>This method ignores Test directories
|
||||
*/
|
||||
private static List<File> getUserSettingsDirsByTime() {
|
||||
File userDataDirectory = Application.getUserSettingsDirectory();
|
||||
File userDataDirParentFile = userDataDirectory.getParentFile();
|
||||
ApplicationLayout layout = Application.getApplicationLayout();
|
||||
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) -> {
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.framework;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -24,6 +25,7 @@ import ghidra.util.Msg;
|
|||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import utilities.util.FileUtilities;
|
||||
import utility.application.ApplicationUtilities;
|
||||
import utility.module.ModuleUtilities;
|
||||
|
||||
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)
|
||||
* 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.
|
||||
|
@ -144,14 +146,18 @@ public class TestApplicationUtils {
|
|||
reposContainer = installDir;
|
||||
}
|
||||
|
||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
String tempName = tmpDir.getName();
|
||||
try {
|
||||
File tmpDir = ApplicationUtilities.getDefaultUserTempDir("ghidra");
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
String name = reposContainer.getName() + tempName;
|
||||
return new File(tmpDir, name);
|
||||
//
|
||||
// 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
|
||||
//
|
||||
String name = reposContainer.getName();
|
||||
return new File(tmpDir, name);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new AssertException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
*/
|
||||
package utilities.util;
|
||||
|
||||
import static generic.test.AbstractGTest.assertListEqualsArrayOrdered;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static generic.test.AbstractGTest.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.*;
|
||||
|
@ -30,8 +30,7 @@ import org.junit.Test;
|
|||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.Platform;
|
||||
import ghidra.framework.*;
|
||||
import utilities.util.FileResolutionResult.FileResolutionStatus;
|
||||
|
||||
public class FileUtilitiesTest {
|
||||
|
@ -198,11 +197,11 @@ public class FileUtilitiesTest {
|
|||
@Test
|
||||
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"));
|
||||
from.deleteOnExit();
|
||||
|
||||
File to = File.createTempFile("to.file", ".txt");
|
||||
File to = Application.createTempFile("to.file", ".txt");
|
||||
to.deleteOnExit();
|
||||
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();
|
||||
|
||||
// should fail
|
||||
|
@ -232,7 +231,7 @@ public class FileUtilitiesTest {
|
|||
@Test(expected = IOException.class)
|
||||
public void copyFile_ExceptionFromOutputStream() throws Exception {
|
||||
|
||||
File from = File.createTempFile("from.file", ".txt");
|
||||
File from = Application.createTempFile("from.file", ".txt");
|
||||
from.deleteOnExit();
|
||||
|
||||
ResourceFile to = new ResourceFile(new File("/to.from.file")) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import javax.swing.Icon;
|
|||
import javax.swing.ImageIcon;
|
||||
|
||||
import generic.util.image.ImageUtils;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
|
@ -94,7 +95,7 @@ public class IconProvider {
|
|||
}
|
||||
|
||||
try {
|
||||
File imageFile = File.createTempFile("temp.help.icon", null);
|
||||
File imageFile = Application.createTempFile("temp.help.icon", null);
|
||||
imageFile.deleteOnExit(); // don't let this linger
|
||||
ImageIcon imageIcon = ResourceManager.getImageIcon(icon);
|
||||
ImageUtils.writeFile(imageIcon.getImage(), imageFile);
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.xml.sax.*;
|
|||
import org.xml.sax.helpers.DefaultHandler;
|
||||
import org.xml.sax.helpers.ParserAdapter;
|
||||
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.xml.XmlUtilities;
|
||||
|
||||
/**
|
||||
|
@ -174,7 +175,7 @@ public class TOCConverter {
|
|||
* @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));
|
||||
BufferedReader reader = new BufferedReader(new FileReader(sourceFilename));
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Set;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.protocol.ghidra.GhidraURL;
|
||||
|
||||
/**
|
||||
|
@ -67,7 +68,7 @@ public class ProjectLocator {
|
|||
}
|
||||
this.name = name;
|
||||
if (StringUtils.isBlank(path)) {
|
||||
path = System.getProperty("java.io.tmpdir");
|
||||
path = Application.getUserTempDirectory().getAbsolutePath();
|
||||
}
|
||||
this.location = checkAbsolutePath(path);
|
||||
url = GhidraURL.makeURL(location, name);
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.client.NotConnectedException;
|
||||
import ghidra.framework.client.RepositoryAdapter;
|
||||
import ghidra.framework.model.ProjectLocator;
|
||||
|
@ -172,7 +173,7 @@ public class TransientProjectManager {
|
|||
private TransientProjectData createTransientProject(RepositoryAdapter repository,
|
||||
RepositoryInfo repositoryInfo) throws IOException {
|
||||
|
||||
File tmp = File.createTempFile("ghidraPrj", "");
|
||||
File tmp = Application.createTempFile("ghidraPrj", "");
|
||||
tmp.delete();
|
||||
|
||||
ProjectLocator tmpProjectLocation = new TransientProjectStorageLocator(
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.protocol.ghidra.Handler;
|
||||
|
||||
|
@ -120,7 +121,7 @@ public class ProjectLocatorTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testTempPath() throws MalformedURLException {
|
||||
|
||||
String tmpPath = System.getProperty("java.io.tmpdir").replace("\\", "/");
|
||||
String tmpPath = Application.getUserTempDirectory().getAbsolutePath().replace("\\", "/");
|
||||
if (!tmpPath.startsWith("/")) {
|
||||
tmpPath = "/" + tmpPath;
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest {
|
|||
public ResourceFile createCustomPspecFile(String name, String content) {
|
||||
File newPspecFile = null;
|
||||
try {
|
||||
newPspecFile = File.createTempFile(name, ".pspec");
|
||||
newPspecFile = Application.createTempFile(name, ".pspec");
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(newPspecFile));
|
||||
bw.write(content);
|
||||
bw.close();
|
||||
|
@ -239,7 +239,7 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest {
|
|||
}
|
||||
|
||||
try {
|
||||
File editedPspecFile = File.createTempFile(name, ".ldefs");
|
||||
File editedPspecFile = Application.createTempFile(name, ".ldefs");
|
||||
BufferedReader br = new BufferedReader(new FileReader(originalLdefFile.getFile(false)));
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(editedPspecFile));
|
||||
String s;
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
*/
|
||||
package ghidra;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
|
@ -36,12 +37,10 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
|||
/**
|
||||
* Constructs a new Ghidra application layout object.
|
||||
*
|
||||
* @throws FileNotFoundException if there was a problem getting a user
|
||||
* directory.
|
||||
* @throws IOException if there was a problem getting the application
|
||||
* properties or modules.
|
||||
* @throws IOException if there was a problem getting a user directory or the application
|
||||
* properties or modules.
|
||||
*/
|
||||
public GhidraApplicationLayout() throws FileNotFoundException, IOException {
|
||||
public GhidraApplicationLayout() throws IOException {
|
||||
|
||||
// Application root directories
|
||||
applicationRootDirs = findGhidraApplicationRootDirs();
|
||||
|
@ -53,7 +52,8 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
|||
applicationInstallationDir = findGhidraApplicationInstallationDir();
|
||||
|
||||
// User directories
|
||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(getApplicationProperties());
|
||||
userTempDir = ApplicationUtilities
|
||||
.getDefaultUserTempDir(getApplicationProperties().getApplicationName());
|
||||
userCacheDir = ApplicationUtilities.getDefaultUserCacheDir(getApplicationProperties());
|
||||
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(getApplicationProperties(),
|
||||
getApplicationInstallationDir());
|
||||
|
@ -77,13 +77,10 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
|||
* (like the Eclipse GhidraDevPlugin).
|
||||
*
|
||||
* @param applicationInstallationDir The application installation directory.
|
||||
* @throws FileNotFoundException if there was a problem getting a user
|
||||
* directory.
|
||||
* @throws IOException if there was a problem getting the application
|
||||
* properties.
|
||||
* @throws IOException if there was a problem getting a user directory or the application
|
||||
* properties.
|
||||
*/
|
||||
public GhidraApplicationLayout(File applicationInstallationDir)
|
||||
throws FileNotFoundException, IOException {
|
||||
public GhidraApplicationLayout(File applicationInstallationDir) throws IOException {
|
||||
|
||||
// Application installation directory
|
||||
this.applicationInstallationDir = new ResourceFile(applicationInstallationDir);
|
||||
|
@ -96,7 +93,8 @@ public class GhidraApplicationLayout extends ApplicationLayout {
|
|||
applicationProperties = new ApplicationProperties(applicationRootDirs);
|
||||
|
||||
// User directories
|
||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(getApplicationProperties());
|
||||
userTempDir = ApplicationUtilities
|
||||
.getDefaultUserTempDir(getApplicationProperties().getApplicationName());
|
||||
userCacheDir = ApplicationUtilities.getDefaultUserCacheDir(getApplicationProperties());
|
||||
userSettingsDir = ApplicationUtilities.getDefaultUserSettingsDir(getApplicationProperties(),
|
||||
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
|
||||
* into {@link Boolean#parseBoolean(String)}.
|
||||
*
|
||||
|
|
|
@ -1189,29 +1189,6 @@ public final class FileUtilities {
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
||||
import ghidra.framework.PluggableServiceRegistry;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import utilities.util.FileUtilities;
|
||||
import ghidra.framework.PluggableServiceRegistry;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class ApplicationSettings {
|
||||
static {
|
||||
|
@ -46,6 +46,13 @@ public class ApplicationSettings {
|
|||
* application version.
|
||||
*/
|
||||
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.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
/**
|
||||
* Utility class for default application things.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -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.
|
||||
* @return The default application's user temp directory.
|
||||
* @throws FileNotFoundException if the user temp directory could not be determined.
|
||||
* @param applicationName The application name.
|
||||
* @return The application's default user temp directory. The returned {@link File} will
|
||||
* 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)
|
||||
throws FileNotFoundException {
|
||||
String tmpdir = System.getProperty("java.io.tmpdir");
|
||||
if (tmpdir == null || tmpdir.isEmpty()) {
|
||||
throw new FileNotFoundException("System property \"java.io.tmpdir\" is not set!");
|
||||
public static File getDefaultUserTempDir(String applicationName) throws FileNotFoundException {
|
||||
|
||||
String appName = applicationName.toLowerCase();
|
||||
|
||||
// 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.
|
||||
* @return The default application's user cache directory.
|
||||
* @throws FileNotFoundException if the user cache directory could not be determined.
|
||||
* @return The application's default user cache directory. The returned {@link File} will
|
||||
* 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)
|
||||
throws FileNotFoundException {
|
||||
|
||||
// Look for preset cache directory
|
||||
String cachedir = System.getProperty("application.cachedir", "").trim();
|
||||
if (!cachedir.isEmpty()) {
|
||||
return new File(cachedir,
|
||||
SystemUtilities.getUserName() + "-" + applicationProperties.getApplicationName());
|
||||
String appName = applicationProperties.getApplicationName().toLowerCase();
|
||||
|
||||
// Look for Ghidra-specific system property
|
||||
File cacheOverrideDir = getSystemPropertyFile(PROPERTY_CACHE_DIR, false);
|
||||
if (cacheOverrideDir != null) {
|
||||
return new File(cacheOverrideDir, getUserSpecificDirName(cacheOverrideDir, appName));
|
||||
}
|
||||
|
||||
// Handle Windows specially
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
File localAppDataDir = null;
|
||||
String localAppDataDirPath = System.getenv("LOCALAPPDATA"); // e.g., /Users/myname/AppData/Local
|
||||
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());
|
||||
}
|
||||
// Look for XDG environment variable
|
||||
File xdgCacheHomeDir = getEnvFile(XdgUtils.XDG_CACHE_HOME, false);
|
||||
if (xdgCacheHomeDir != null) {
|
||||
return new File(xdgCacheHomeDir, getUserSpecificDirName(xdgCacheHomeDir, appName));
|
||||
}
|
||||
|
||||
// Use user temp directory if platform specific scheme does not exist above or it failed
|
||||
return getDefaultUserTempDir(applicationProperties);
|
||||
|
||||
// Use platform-specific default location
|
||||
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 installationDirectory The application installation directory.
|
||||
* @return The application's user settings directory.
|
||||
* @throws FileNotFoundException if the user settings directory could not be determined.
|
||||
* @return The application's default user settings directory. The returned {@link File} will
|
||||
* 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,
|
||||
ResourceFile installationDirectory) throws FileNotFoundException {
|
||||
|
||||
String homedir = System.getProperty("user.home");
|
||||
if (homedir == null || homedir.isEmpty()) {
|
||||
throw new FileNotFoundException("System property \"user.home\" is not set!");
|
||||
String appName = applicationProperties.getApplicationName().toLowerCase();
|
||||
ApplicationIdentifier applicationIdentifier =
|
||||
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 =
|
||||
new ApplicationIdentifier(applicationProperties);
|
||||
|
||||
File userSettingsParentDir =
|
||||
new File(homedir, "." + applicationIdentifier.getApplicationName());
|
||||
new File(getJavaUserHomeDir(), "." + applicationIdentifier.getApplicationName());
|
||||
|
||||
String userSettingsDirName = "." + applicationIdentifier;
|
||||
|
||||
|
@ -227,4 +303,108 @@ public class ApplicationUtilities {
|
|||
|
||||
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;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
|
@ -32,9 +32,9 @@ public class DummyApplicationLayout extends ApplicationLayout {
|
|||
/**
|
||||
* Constructs a new dummy application layout object.
|
||||
* @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
|
||||
applicationProperties = new ApplicationProperties(name);
|
||||
|
@ -48,7 +48,8 @@ public class DummyApplicationLayout extends ApplicationLayout {
|
|||
applicationRootDirs.add(cwd);
|
||||
|
||||
// User directories
|
||||
userTempDir = ApplicationUtilities.getDefaultUserTempDir(applicationProperties);
|
||||
userTempDir =
|
||||
ApplicationUtilities.getDefaultUserTempDir(applicationProperties.getApplicationName());
|
||||
|
||||
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.
|
||||
VMARGS=-Xshare:off
|
||||
|
||||
# Persistent cache directory used by the application. This directory will be used to store
|
||||
# persistent application caches for all users. The default location for Mac/Linux is the same as
|
||||
# specified by java.io.tmpdir property. The default location for Windows corresponds to the
|
||||
# application local settings directory for the user (e.g., %LOCALAPPDATA%). If you wish to use a
|
||||
# directory with more storage or avoid system cleanups, it may be desirable to override the default
|
||||
# location.
|
||||
# Settings directory used by the application to store application settings and data that persist
|
||||
# between application sessions, system reboots, and periodic system cleanup. Overridden values
|
||||
# are required to be absolute paths. The current user name may be incorporated into the settings
|
||||
# directory's name if the settings directory lives outside of the user's home directory. The
|
||||
# settings directory will be selected based on the following rules, in order of precedence:
|
||||
# 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=
|
||||
|
||||
# Temporary directory used by the application. This directory will be used for all temporary files
|
||||
# and may also be used for the persistent user cache directory <java.io.tmpdir>/<username>-Ghidra.
|
||||
# The specified directory must exist and have appropriate read/write/execute permissions
|
||||
# Temporary directory used by the application to store short-lived files that are not required to
|
||||
# persist between application sessions. Overridden values are required to be absolute paths. The
|
||||
# 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=
|
||||
|
||||
# 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/convertStorage||GHIDRA||||END|
|
||||
Linux/support/gdbGADPServerRun||GHIDRA||||END|
|
||||
Linux/support/ghidraClean||GHIDRA||||END|
|
||||
Linux/support/ghidraDebug||GHIDRA||||END|
|
||||
Linux/support/pythonRun||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/dbgmodelGADPServerRun.bat||GHIDRA||||END|
|
||||
Windows/support/ghidra.ico||GHIDRA||||END|
|
||||
Windows/support/ghidraClean.bat||GHIDRA||||END|
|
||||
Windows/support/ghidraDebug.bat||GHIDRA||||END|
|
||||
Windows/support/launch.bat||GHIDRA||||END|
|
||||
Windows/support/pythonRun.bat||GHIDRA||||END|
|
||||
|
|
|
@ -35,6 +35,7 @@ import docking.wizard.WizardManager;
|
|||
import docking.wizard.WizardPanel;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import ghidra.app.plugin.core.archive.RestoreDialog;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.data.DefaultProjectData;
|
||||
import ghidra.framework.data.GhidraFileData;
|
||||
import ghidra.framework.main.*;
|
||||
|
@ -56,7 +57,6 @@ import resources.MultiIcon;
|
|||
|
||||
public class FrontEndPluginScreenShots extends GhidraScreenShotGenerator {
|
||||
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);
|
||||
|
||||
public FrontEndPluginScreenShots() {
|
||||
|
@ -659,6 +659,7 @@ public class FrontEndPluginScreenShots extends GhidraScreenShotGenerator {
|
|||
@Test
|
||||
public void testViewOtherProjects()
|
||||
throws IOException, LockException, InvalidNameException, CancelledException {
|
||||
String TEMP_DIR = Application.getUserTempDirectory().getAbsolutePath();
|
||||
|
||||
Project project = env.getProject();
|
||||
program = env.getProgram("WinHelloCPP.exe");
|
||||
|
@ -692,6 +693,7 @@ public class FrontEndPluginScreenShots extends GhidraScreenShotGenerator {
|
|||
@Test
|
||||
public void testLinkOtherProject()
|
||||
throws IOException, LockException, InvalidNameException, CancelledException {
|
||||
String TEMP_DIR = Application.getUserTempDirectory().getAbsolutePath();
|
||||
|
||||
Project project = env.getProject();
|
||||
program = env.getProgram("WinHelloCPP.exe");
|
||||
|
|
|
@ -30,6 +30,7 @@ import javax.rmi.ssl.SslRMIClientSocketFactory;
|
|||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
|
||||
import generic.test.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.client.*;
|
||||
import ghidra.framework.data.ContentHandler;
|
||||
import ghidra.framework.data.DomainObjectAdapter;
|
||||
|
@ -347,7 +348,7 @@ public class ServerTestUtil {
|
|||
|
||||
private static synchronized File getPkiTestDirectory() {
|
||||
if (testPkiDirectory == null) {
|
||||
testPkiDirectory = new File(System.getProperty("java.io.tmpdir"), "test-pki");
|
||||
testPkiDirectory = new File(Application.getUserTempDirectory(), "test-pki");
|
||||
FileUtilities.deleteDir(testPkiDirectory);
|
||||
testPkiDirectory.mkdirs();
|
||||
|
||||
|
|
|
@ -359,6 +359,23 @@ public class JavaConfig {
|
|||
*/
|
||||
private void initJavaHomeSaveFile(File installDir) throws FileNotFoundException {
|
||||
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)
|
||||
String userHomeDirPath = System.getProperty("user.home");
|
||||
|
@ -370,18 +387,27 @@ public class JavaConfig {
|
|||
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).
|
||||
File userSettingsParentDir =
|
||||
new File(userHomeDir, "." + applicationName.replaceAll("\\s", "").toLowerCase());
|
||||
|
||||
String userSettingsDirName = userSettingsParentDir.getName() + "_" + applicationVersion +
|
||||
"_" + applicationReleaseName.replaceAll("\\s", "").toUpperCase();
|
||||
|
||||
if (isDev) {
|
||||
userSettingsDirName += "_location_" + installDir.getParentFile().getName();
|
||||
switch (JavaFinder.getCurrentPlatform()) {
|
||||
case WINDOWS:
|
||||
String localAppDataDirPath = System.getenv("APPDATA");
|
||||
if (localAppDataDirPath == null || localAppDataDirPath.trim().isEmpty()) {
|
||||
throw new FileNotFoundException("\"APPDATA\" environment variable is not set");
|
||||
}
|
||||
userSettingsDir =
|
||||
new File(localAppDataDirPath, appName + "/" + userSettingsDirName);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user