diff --git a/src/Application.cpp b/src/Application.cpp index 2f05c39440..7ad1c870e8 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -17,10 +17,11 @@ Application* theApp = NULL; -DatabaseCon::DatabaseCon(const std::string& name, const char *initStrings[], int initCount) +DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount) { - std::string path=strprintf("%s%s", theConfig.DATA_DIR.c_str(), name.c_str()); - mDatabase = new SqliteDatabase(path.c_str()); + boost::filesystem::path pPath = theConfig.DATA_DIR / strName; + + mDatabase = new SqliteDatabase(pPath.c_str()); mDatabase->connect(); for(int i = 0; i < initCount; ++i) mDatabase->executeSQL(initStrings[i], true); diff --git a/src/Config.cpp b/src/Config.cpp index 08b3f36c57..a580d94ea5 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -35,8 +35,71 @@ Config theConfig; Config::Config() { + boost::system::error_code ec; + + // + // Determine the config and data directories. + // If the config file is found in the current working directory, use the current working directory as the config directory and + // that with "db" as the data directory. + // + + CONFIG_DIR = boost::filesystem::current_path(); + CONFIG_FILE = CONFIG_DIR / CONFIG_FILE_NAME; + + if (exists(CONFIG_FILE) + || (!getenv("HOME") && !getenv("XDG_CONFIG_HOME"))) + { + // Current place is fine, put dbs in a subdir. + DATA_DIR = CONFIG_DIR / "db"; + } + else + { + // Construct XDG config and data home. + // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + std::string strHome = strGetEnv("HOME"); + std::string strXdgConfigHome = strGetEnv("XDG_CONFIG_HOME"); + std::string strXdgDataHome = strGetEnv("XDG_DATA_HOME"); + + if (strXdgConfigHome.empty()) + { + // $XDG_CONFIG_HOME was not set, use default based on $HOME. + strXdgConfigHome = str(boost::format("%s/.config") % strHome); + } + + CONFIG_DIR = str(boost::format("%s/" SYSTEM_NAME) % strXdgConfigHome); + + boost::filesystem::create_directories(CONFIG_DIR, ec); + + if (ec) + throw std::runtime_error(str(boost::format("Can not create %s") % CONFIG_DIR)); + + if (strXdgDataHome.empty()) + { + // $XDG_DATA_HOME was not set, use default based on $HOME. + strXdgDataHome = str(boost::format("%s/.local/share") % strHome); + } + + DATA_DIR = str(boost::format("%s/" SYSTEM_NAME) % strXdgDataHome); + + } + + boost::filesystem::create_directories(DATA_DIR, ec); + + if (ec) + throw std::runtime_error(str(boost::format("Can not create %s") % DATA_DIR)); + + std::cerr << "CONFIG DIR: " << CONFIG_DIR << std::endl; + std::cerr << "DATA DIR: " << DATA_DIR << std::endl; + + // + // Defaults + // + VERSION = 1; + CONFIG_FILE = CONFIG_DIR; + CONFIG_FILE /= CONFIG_FILE_NAME; + NETWORK_START_TIME = 1319844908; PEER_PORT = SYSTEM_PEER_PORT; @@ -50,8 +113,6 @@ Config::Config() RPC_PASSWORD = "pass"; RPC_ALLOW_REMOTE = false; - DATA_DIR = "db/"; - PEER_SSL_CIPHER_LIST = DEFAULT_PEER_SSL_CIPHER_LIST; PEER_SCAN_INTERVAL_MIN = DEFAULT_PEER_SCAN_INTERVAL_MIN; diff --git a/src/Config.h b/src/Config.h index 909f636ebd..74bd42e74a 100644 --- a/src/Config.h +++ b/src/Config.h @@ -5,6 +5,7 @@ #include "SerializedTypes.h" #include +#include #define SYSTEM_NAME "newcoin" #define VALIDATORS_SITE "redstem.com" @@ -38,6 +39,11 @@ public: int VERSION; std::string VERSION_STR; + // Configuration parameters + boost::filesystem::path CONFIG_FILE; + boost::filesystem::path CONFIG_DIR; + boost::filesystem::path DATA_DIR; + // Network parameters int NETWORK_START_TIME; // The Unix time we start ledger 0 int TRANSACTION_FEE_BASE; @@ -80,9 +86,6 @@ public: uint64 FEE_ACCOUNT_CREATE; // Fee to create an account. uint64 FEE_NICKNAME_CREATE; // Fee to create a nickname. - // Configuration parameters - std::string DATA_DIR; - // Client behavior int ACCOUNT_PROBE_MAX; // How far to scan for accounts. diff --git a/src/main.cpp b/src/main.cpp index 4c6bc5213e..07e1574b88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,6 +82,7 @@ int main(int argc, char* argv[]) po::options_description desc("Options"); desc.add_options() ("help,h", "Display this message.") + ("conf", "Specify the configuration file.") ("rpc", "Perform rpc command (default).") ("test,t", "Perform unit tests.") ("parameters", po::value< vector >(), "Specify comma separated parameters.") diff --git a/src/utils.h b/src/utils.h index ee5ef0b598..721fbff879 100644 --- a/src/utils.h +++ b/src/utils.h @@ -94,6 +94,10 @@ DH* DH_der_load_hex(const std::string& strDer); void DH_der_gen(std::string& strDer, int iKeyLength); void DH_der_gen_hex(std::string& strDer, int iKeyLength); +inline std::string strGetEnv(const std::string& strKey) +{ + return getenv(strKey.c_str()) ? getenv(strKey.c_str()) : ""; +} #endif // vim:ts=4