forked from I2P_Developers/i2p.i2p
Compare commits
5 Commits
i2p.i2p.2.
...
bulk-confi
Author | SHA1 | Date | |
---|---|---|---|
56f76d8162 | |||
62c5d1a3e4 | |||
9047ada936 | |||
82c9e027da | |||
7312e9693d |
265
router/java/src/net/i2p/router/ClientConfigManager.java
Normal file
265
router/java/src/net/i2p/router/ClientConfigManager.java
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
package net.i2p.router;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import net.i2p.router.startup.WorkingDir;
|
||||||
|
import net.i2p.util.FileSuffixFilter;
|
||||||
|
import net.i2p.util.FileUtil;
|
||||||
|
import net.i2p.util.SystemVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute bulk edits against I2P application config files or config
|
||||||
|
* directories. This is a command-line application only, which is intended
|
||||||
|
* to work agnostic of whether the router is runnning.
|
||||||
|
*
|
||||||
|
* @author idk 2023
|
||||||
|
*/
|
||||||
|
public class ClientConfigManager extends WorkingDir {
|
||||||
|
private String clientName = null;
|
||||||
|
private String workDir = null;
|
||||||
|
/**
|
||||||
|
* editPropertiesFile opens a single properties(.config) file and edits
|
||||||
|
* every entry in it that matches the regular expression `prop` to contain
|
||||||
|
* the value `value`.
|
||||||
|
* @param clientAppConfig
|
||||||
|
* @param prop
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean editPropertiesFile(File clientAppConfig, String prop,
|
||||||
|
String value)
|
||||||
|
throws FileNotFoundException {
|
||||||
|
System.out.println("editing config file " + clientAppConfig.getName());
|
||||||
|
boolean go = true;
|
||||||
|
Properties clientAppConfigProps = new Properties();
|
||||||
|
File backupConfig = new File(clientAppConfig + ".bak");
|
||||||
|
FileUtil.copy(clientAppConfig, backupConfig, true,
|
||||||
|
false);
|
||||||
|
try {
|
||||||
|
FileInputStream clientAppConfigReader = new FileInputStream(backupConfig);
|
||||||
|
clientAppConfigProps.load(clientAppConfigReader);
|
||||||
|
final Iterator entries = clientAppConfigProps.entrySet().iterator();
|
||||||
|
while (entries.hasNext()) {
|
||||||
|
final Map.Entry entry = (Map.Entry)entries.next();
|
||||||
|
String key = (String)entry.getKey();
|
||||||
|
if (Pattern.matches(prop, key)) {
|
||||||
|
clientAppConfigProps.setProperty(key, value);
|
||||||
|
// System.out.println("set property " + key + "=" + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
FileWriter clientAppConfigWriter = new FileWriter(clientAppConfig);
|
||||||
|
clientAppConfigProps.store(clientAppConfigWriter,
|
||||||
|
"inserted by ClientConfigManager");
|
||||||
|
} catch (IOException e) {
|
||||||
|
go = false;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
go = false;
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
go = false;
|
||||||
|
}
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* editClientsConfig checks clients.config and clients.config.d to enable
|
||||||
|
* bulk configuration of client applications
|
||||||
|
*
|
||||||
|
* @param configDir
|
||||||
|
* @param prop
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
public void editClientsConfig(File configDir, String prop, String value)
|
||||||
|
throws FileNotFoundException {
|
||||||
|
File clientAppConfigDir = new File(configDir, "clients.config.d");
|
||||||
|
if (clientAppConfigDir.exists()) {
|
||||||
|
File[] clientAppConfigFiles =
|
||||||
|
clientAppConfigDir.listFiles(new FileSuffixFilter(".config"));
|
||||||
|
if (clientAppConfigFiles != null) {
|
||||||
|
for (int i = 0; i < clientAppConfigFiles.length; i++) {
|
||||||
|
boolean cont =
|
||||||
|
editPropertiesFile(clientAppConfigFiles[i], prop, value);
|
||||||
|
if (!cont)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
File clientAppConfig = new File(configDir, "clients.config");
|
||||||
|
if (!clientAppConfig.exists())
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
editPropertiesFile(clientAppConfig, prop, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* editClientAppConfig edits the configuration files for a client based
|
||||||
|
* on the client's name(the un-translated one). Common values would be
|
||||||
|
* `i2ptunnel` or `i2psnark`. It can handle both monolithic and split-file
|
||||||
|
* confiurations I2P apps.
|
||||||
|
*
|
||||||
|
* @param configDir
|
||||||
|
* @param clientName
|
||||||
|
* @param prop
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
public void editClientAppConfig(File configDir, String clientName,
|
||||||
|
String prop, String value)
|
||||||
|
throws FileNotFoundException {
|
||||||
|
File i2pTunnelConfigDir = new File(configDir, clientName + ".config.d");
|
||||||
|
if (i2pTunnelConfigDir.exists()) {
|
||||||
|
File[] i2pTunnelConfigFiles =
|
||||||
|
i2pTunnelConfigDir.listFiles(new FileSuffixFilter(".config"));
|
||||||
|
if (i2pTunnelConfigFiles != null) {
|
||||||
|
for (int i = 0; i < i2pTunnelConfigFiles.length; i++) {
|
||||||
|
boolean cont =
|
||||||
|
editPropertiesFile(i2pTunnelConfigFiles[i], prop, value);
|
||||||
|
if (!cont)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
File i2pTunnelConfig = new File(configDir, clientName + ".config");
|
||||||
|
if (!i2pTunnelConfig.exists())
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
editPropertiesFile(i2pTunnelConfig, prop, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private class PropSet {
|
||||||
|
String key;
|
||||||
|
String value;
|
||||||
|
PropSet(String inkey, String invalue) {
|
||||||
|
key = inkey;
|
||||||
|
value = invalue;
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
if (key == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
return key + "=";
|
||||||
|
}
|
||||||
|
return key + "=" + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* parses arguments and flags from the command line. Valid flags are:
|
||||||
|
*
|
||||||
|
* -clientapp name
|
||||||
|
* -workdir path
|
||||||
|
*
|
||||||
|
* which must be followed by 2 trailing arguments, the first of which is
|
||||||
|
* a regular expression, the second of which is a value which will be applied
|
||||||
|
* to all keys matching the regular expression.
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* @return PropSet containing the regex to match against the key, and the
|
||||||
|
* value to set
|
||||||
|
* @throws Error
|
||||||
|
*/
|
||||||
|
public PropSet parseArgs(String args[]) throws Error {
|
||||||
|
if (args.length < 2) {
|
||||||
|
throw new Error("insufficient bulk edit arguments");
|
||||||
|
} else if (args.length == 2) {
|
||||||
|
return new PropSet(args[0], args[1]);
|
||||||
|
}
|
||||||
|
String key = null;
|
||||||
|
String value = null;
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
if (args[i].startsWith("-")) {
|
||||||
|
if (args[i].equals("-clientapp")) {
|
||||||
|
if (args.length >= i + 1) {
|
||||||
|
System.out.println("Setting clientName to " + args[i] +
|
||||||
|
args[i + 1]);
|
||||||
|
clientName = args[i + 1];
|
||||||
|
i++;
|
||||||
|
} else
|
||||||
|
throw new Error(
|
||||||
|
"Insufficient arguments, -clientapp requires an an application name");
|
||||||
|
} else if (args[i].equals("-clientapp")) {
|
||||||
|
if (args.length >= i + 1) {
|
||||||
|
System.out.println("Setting workDir to " + args[i] + args[i + 1]);
|
||||||
|
workDir = args[i + 1];
|
||||||
|
i++;
|
||||||
|
} else
|
||||||
|
throw new Error(
|
||||||
|
"Insufficient arguments, -workdir requires an a directory");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (key == null)
|
||||||
|
key = args[i];
|
||||||
|
else {
|
||||||
|
value = args[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new PropSet(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* editClientApp helps determine if we're editing clients.config or an
|
||||||
|
* application config.
|
||||||
|
*
|
||||||
|
* @return true if editing an app, false if editing clients.config
|
||||||
|
*/
|
||||||
|
public boolean editClientApp() {
|
||||||
|
if (clientName != null)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get the "default" config directory for your platform.
|
||||||
|
*
|
||||||
|
* @return the default configuration directory, or workDir if it is set.
|
||||||
|
*/
|
||||||
|
public File getConfigDir() {
|
||||||
|
if (workDir != null) {
|
||||||
|
System.out.println("workdir set to" + workDir);
|
||||||
|
return new File(workDir);
|
||||||
|
}
|
||||||
|
System.out.println("finding default config dir");
|
||||||
|
boolean isWindows = SystemVersion.isWindows();
|
||||||
|
String defaultPath = getDefaultDir(isWindows).getAbsolutePath();
|
||||||
|
System.out.println("using default config dir " + defaultPath);
|
||||||
|
return new File(defaultPath);
|
||||||
|
}
|
||||||
|
public static void main(String args[]) {
|
||||||
|
System.out.println("ClientConfigManager");
|
||||||
|
ClientConfigManager ccm = new ClientConfigManager();
|
||||||
|
try {
|
||||||
|
PropSet propSet = ccm.parseArgs(args);
|
||||||
|
System.out.println("args are " + propSet.toString());
|
||||||
|
File configDir = ccm.getConfigDir();
|
||||||
|
System.out.println("configs are " + configDir.getAbsolutePath());
|
||||||
|
if (ccm.editClientApp()) {
|
||||||
|
try {
|
||||||
|
ccm.editClientAppConfig(configDir, ccm.clientName, propSet.key,
|
||||||
|
propSet.value);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println(
|
||||||
|
"Client not found, check name and config directory");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
ccm.editClientsConfig(configDir, propSet.key, propSet.value);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println(
|
||||||
|
"Client config file not found, check config directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Error e) {
|
||||||
|
System.out.println(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ import java.util.List;
|
|||||||
public class CommandLine extends net.i2p.util.CommandLine {
|
public class CommandLine extends net.i2p.util.CommandLine {
|
||||||
|
|
||||||
protected static final List<String> RCLASSES = Arrays.asList(new String[] {
|
protected static final List<String> RCLASSES = Arrays.asList(new String[] {
|
||||||
|
"net.i2p.router.ClientConfigManager",
|
||||||
"com.maxmind.geoip2.DatabaseReader",
|
"com.maxmind.geoip2.DatabaseReader",
|
||||||
"net.i2p.data.router.RouterInfo",
|
"net.i2p.data.router.RouterInfo",
|
||||||
"net.i2p.data.router.RouterKeyGenerator",
|
"net.i2p.data.router.RouterKeyGenerator",
|
||||||
|
@ -56,6 +56,103 @@ public class WorkingDir {
|
|||||||
/** Feb 16 2006 */
|
/** Feb 16 2006 */
|
||||||
private static final long EEPSITE_TIMESTAMP = 1140048000000l;
|
private static final long EEPSITE_TIMESTAMP = 1140048000000l;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the default working directory for a given platform by examining
|
||||||
|
* the host system, and applies secure configuration to that directory.
|
||||||
|
*
|
||||||
|
* @param isWindows set to true if the host system is Windows, false if it's anything else
|
||||||
|
* @return a File containing the working directory
|
||||||
|
*/
|
||||||
|
public static File getDefaultDir(boolean isWindows){
|
||||||
|
File dirf = null;
|
||||||
|
String gentooWarning = null;
|
||||||
|
String home = System.getProperty("user.home");
|
||||||
|
if (isWindows) {
|
||||||
|
String localappdata = System.getenv("LOCALAPPDATA");
|
||||||
|
if (localappdata != null) {
|
||||||
|
home = localappdata;
|
||||||
|
}
|
||||||
|
// Don't mess with existing Roaming Application Data installs,
|
||||||
|
// in case somebody is using roaming appdata for a reason
|
||||||
|
// already. In new installs, use local appdata by default. -idk
|
||||||
|
String appdata = System.getenv("APPDATA");
|
||||||
|
if (appdata != null) {
|
||||||
|
File checkOld = new File(appdata, WORKING_DIR_DEFAULT_WINDOWS);
|
||||||
|
if (checkOld.exists() && checkOld.isDirectory()){
|
||||||
|
File routerConfig = new File(checkOld.getAbsolutePath(), "router.config");
|
||||||
|
// The Firefox profile installer was mistakenly using the Roaming application data
|
||||||
|
// which is synced between devices on some Windows machines using MS cloud services,
|
||||||
|
// instead of the local application data which is used by default.
|
||||||
|
// It would create the router.config file in an empty directory, which the router would
|
||||||
|
// then attempt to use, resulting in a router with no client applications. Checking
|
||||||
|
// for clients.config.d determines if the directory is "Real" or not.
|
||||||
|
File clientAppsConfig = new File(checkOld.getAbsolutePath(), "clients.config.d");
|
||||||
|
if (routerConfig.exists() && clientAppsConfig.exists() && clientAppsConfig.isDirectory()) {
|
||||||
|
home = appdata;
|
||||||
|
} else {
|
||||||
|
clientAppsConfig = new File(checkOld.getAbsolutePath(), "clients.config");
|
||||||
|
if (routerConfig.exists() && clientAppsConfig.exists())
|
||||||
|
home = appdata;
|
||||||
|
}
|
||||||
|
System.err.println("System is Windows: " + home);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_WINDOWS);
|
||||||
|
} else if (SystemVersion.isMac()) {
|
||||||
|
String appdata = "/Library/Application Support/";
|
||||||
|
File old = new File(home,WORKING_DIR_DEFAULT);
|
||||||
|
if (old.exists() && old.isDirectory())
|
||||||
|
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT);
|
||||||
|
else {
|
||||||
|
home = home+appdata;
|
||||||
|
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_MAC);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (SystemVersion.isLinuxService()) {
|
||||||
|
if (SystemVersion.isGentoo() &&
|
||||||
|
SystemVersion.GENTOO_USER.equals(System.getProperty("user.name"))) {
|
||||||
|
// whoops, we didn't recognize Gentoo as a service until 0.9.29,
|
||||||
|
// so the config dir was /var/lib/i2p/.i2p through 0.9.28
|
||||||
|
// and changed to /var/lib/i2p/i2p-config in 0.9.29.
|
||||||
|
// Look for both to decide which to use.
|
||||||
|
// We prefer .i2p if neither exists.
|
||||||
|
// We prefer the newer if both exist.
|
||||||
|
File d1 = new SecureDirectory(home, WORKING_DIR_DEFAULT);
|
||||||
|
File d2 = new SecureDirectory(home, WORKING_DIR_DEFAULT_DAEMON);
|
||||||
|
boolean e1 = isSetup(d1);
|
||||||
|
boolean e2 = isSetup(d2);
|
||||||
|
if (e1 && e2) {
|
||||||
|
// d1 is probably older. Switch if it isn't.
|
||||||
|
if (d2.lastModified() < d1.lastModified()) {
|
||||||
|
File tmp = d2;
|
||||||
|
d2 = d1;
|
||||||
|
d1 = tmp;
|
||||||
|
// d1 now is the older one
|
||||||
|
}
|
||||||
|
dirf = d2;
|
||||||
|
gentooWarning = "Warning - Found both an old configuration directory " + d1.getAbsolutePath() +
|
||||||
|
" and new configuration directory " + d2.getAbsolutePath() +
|
||||||
|
" created due to a bug in release 0.9.29\n. Using the new configuration" +
|
||||||
|
" directory. To use the old directory instead, stop i2p," +
|
||||||
|
" delete the new directory, and restart.";
|
||||||
|
} else if (e1 && !e2) {
|
||||||
|
dirf = d1;
|
||||||
|
} else if (!e1 && e2) {
|
||||||
|
dirf = d2;
|
||||||
|
} else {
|
||||||
|
dirf = d1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_DAEMON);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirf;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only call this once on router invocation.
|
* Only call this once on router invocation.
|
||||||
* Caller should store the return value for future reference.
|
* Caller should store the return value for future reference.
|
||||||
@ -78,89 +175,7 @@ public class WorkingDir {
|
|||||||
if (dir != null) {
|
if (dir != null) {
|
||||||
dirf = new SecureDirectory(dir);
|
dirf = new SecureDirectory(dir);
|
||||||
} else {
|
} else {
|
||||||
String home = System.getProperty("user.home");
|
dirf = getDefaultDir(isWindows);
|
||||||
if (isWindows) {
|
|
||||||
String localappdata = System.getenv("LOCALAPPDATA");
|
|
||||||
if (localappdata != null) {
|
|
||||||
home = localappdata;
|
|
||||||
}
|
|
||||||
// Don't mess with existing Roaming Application Data installs,
|
|
||||||
// in case somebody is using roaming appdata for a reason
|
|
||||||
// already. In new installs, use local appdata by default. -idk
|
|
||||||
String appdata = System.getenv("APPDATA");
|
|
||||||
if (appdata != null) {
|
|
||||||
File checkOld = new File(appdata, WORKING_DIR_DEFAULT_WINDOWS);
|
|
||||||
if (checkOld.exists() && checkOld.isDirectory()){
|
|
||||||
File routerConfig = new File(checkOld.getAbsolutePath(), "router.config");
|
|
||||||
// The Firefox profile installer was mistakenly using the Roaming application data
|
|
||||||
// which is synced between devices on some Windows machines using MS cloud services,
|
|
||||||
// instead of the local application data which is used by default.
|
|
||||||
// It would create the router.config file in an empty directory, which the router would
|
|
||||||
// then attempt to use, resulting in a router with no client applications. Checking
|
|
||||||
// for clients.config.d determines if the directory is "Real" or not.
|
|
||||||
File clientAppsConfig = new File(checkOld.getAbsolutePath(), "clients.config.d");
|
|
||||||
if (routerConfig.exists() && clientAppsConfig.exists() && clientAppsConfig.isDirectory()) {
|
|
||||||
home = appdata;
|
|
||||||
} else {
|
|
||||||
clientAppsConfig = new File(checkOld.getAbsolutePath(), "clients.config");
|
|
||||||
if (routerConfig.exists() && clientAppsConfig.exists())
|
|
||||||
home = appdata;
|
|
||||||
}
|
|
||||||
System.err.println("System is Windows: " + home);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_WINDOWS);
|
|
||||||
} else if (SystemVersion.isMac()) {
|
|
||||||
String appdata = "/Library/Application Support/";
|
|
||||||
File old = new File(home,WORKING_DIR_DEFAULT);
|
|
||||||
if (old.exists() && old.isDirectory())
|
|
||||||
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT);
|
|
||||||
else {
|
|
||||||
home = home+appdata;
|
|
||||||
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_MAC);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SystemVersion.isLinuxService()) {
|
|
||||||
if (SystemVersion.isGentoo() &&
|
|
||||||
SystemVersion.GENTOO_USER.equals(System.getProperty("user.name"))) {
|
|
||||||
// whoops, we didn't recognize Gentoo as a service until 0.9.29,
|
|
||||||
// so the config dir was /var/lib/i2p/.i2p through 0.9.28
|
|
||||||
// and changed to /var/lib/i2p/i2p-config in 0.9.29.
|
|
||||||
// Look for both to decide which to use.
|
|
||||||
// We prefer .i2p if neither exists.
|
|
||||||
// We prefer the newer if both exist.
|
|
||||||
File d1 = new SecureDirectory(home, WORKING_DIR_DEFAULT);
|
|
||||||
File d2 = new SecureDirectory(home, WORKING_DIR_DEFAULT_DAEMON);
|
|
||||||
boolean e1 = isSetup(d1);
|
|
||||||
boolean e2 = isSetup(d2);
|
|
||||||
if (e1 && e2) {
|
|
||||||
// d1 is probably older. Switch if it isn't.
|
|
||||||
if (d2.lastModified() < d1.lastModified()) {
|
|
||||||
File tmp = d2;
|
|
||||||
d2 = d1;
|
|
||||||
d1 = tmp;
|
|
||||||
// d1 now is the older one
|
|
||||||
}
|
|
||||||
dirf = d2;
|
|
||||||
gentooWarning = "Warning - Found both an old configuration directory " + d1.getAbsolutePath() +
|
|
||||||
" and new configuration directory " + d2.getAbsolutePath() +
|
|
||||||
" created due to a bug in release 0.9.29\n. Using the new configuration" +
|
|
||||||
" directory. To use the old directory instead, stop i2p," +
|
|
||||||
" delete the new directory, and restart.";
|
|
||||||
} else if (e1 && !e2) {
|
|
||||||
dirf = d1;
|
|
||||||
} else if (!e1 && e2) {
|
|
||||||
dirf = d2;
|
|
||||||
} else {
|
|
||||||
dirf = d1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_DAEMON);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// where we are now
|
// where we are now
|
||||||
|
Reference in New Issue
Block a user