From 1ac5536f29aa4e88296e89b0c95f8c067ad0475c Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Tue, 30 Jan 2024 22:03:15 +0530 Subject: [PATCH] Use PlatformDirectories to get paths to user data folders. * src/configurationmanager.cpp: - Add new methods ConfigurationManager::{getDataDir, getStateDir}. - Replace ConfigurationManager::getConfFolderSubdir with getDataFolderSubdir, as it is only used for creating SDK directories, which should be in the data directory. - ConfigurationManager::loadConfigDir: Use PlatformDirectories to get config folder. - ConfigurationManager::{lockExecutor/unlockExecution}: Store the lock file in the state folder. * src/megacmd.cpp: - executeServer: Use data dir and subfolders in it for SDK storage. * src/megacmdlogger.cpp: - Store logs in the state directory. --- src/configurationmanager.cpp | 182 ++++++++---------- src/configurationmanager.h | 7 +- src/megacmd.cpp | 4 +- src/megacmdlogger.cpp | 15 +- .../megacmdshellcommunications.cpp | 74 +++---- 5 files changed, 124 insertions(+), 158 deletions(-) diff --git a/src/configurationmanager.cpp b/src/configurationmanager.cpp index 600beb78..93731f60 100644 --- a/src/configurationmanager.cpp +++ b/src/configurationmanager.cpp @@ -17,6 +17,8 @@ */ #include "configurationmanager.h" +#include "mega/types.h" +#include "megacmdcommonutils.h" #include "megacmdversion.h" #include "megacmdutils.h" #include "listeners.h" @@ -84,53 +86,16 @@ static const char* const persistentmcmdconfigurationkeys[] = void ConfigurationManager::loadConfigDir() { + auto dirs = PlatformDirectories::getPlatformSpecificDirectories(); std::lock_guard g(settingsMutex); - -#ifdef _WIN32 - - TCHAR szPath[MAX_PATH]; - if (!SUCCEEDED(GetModuleFileName(NULL, szPath , MAX_PATH))) + configFolder = dirs->configDirPath(); + if (configFolder.empty()) { - LOG_fatal << "Couldnt get EXECUTABLE folder"; + LOG_fatal << "Could not get config directory path"; + return; } - else - { - if (SUCCEEDED(PathRemoveFileSpec(szPath))) - { - if (PathAppend(szPath,TEXT(".megaCmd"))) - { - MegaApi::utf16ToUtf8(szPath, lstrlen(szPath), &configFolder); - } - } - } -#else - const char *homedir = NULL; - homedir = getenv("HOME"); - if (!homedir) - { - struct passwd pd; - struct passwd* pwdptr = &pd; - struct passwd* tempPwdPtr; - char pwdbuffer[200]; - int pwdlinelen = sizeof( pwdbuffer ); - - if (( getpwuid_r(22, pwdptr, pwdbuffer, pwdlinelen, &tempPwdPtr)) != 0) - { - LOG_fatal << "Couldnt get HOME folder"; - return; - } - else - { - homedir = pwdptr->pw_dir; - } - } - stringstream sconfigDir; - sconfigDir << homedir << "/" << ".megaCmd"; - configFolder = sconfigDir.str(); -#endif - - MegaFileSystemAccess *fsAccess = new MegaFileSystemAccess(); + auto fsAccess = ::mega::make_unique(); fsAccess->setdefaultfolderpermissions(0700); LocalPath localConfigFolder = LocalPath::fromAbsolutePath(configFolder); constexpr bool isHidden = true; @@ -139,45 +104,70 @@ void ConfigurationManager::loadConfigDir() { LOG_err << "Config folder not created"; } - delete fsAccess; } - -std::string ConfigurationManager::getConfFolderSubdir(const string &utf8Name) +std::string ConfigurationManager::getDataDir() { - if (!configFolder.size()) + auto dirs = PlatformDirectories::getPlatformSpecificDirectories(); + auto data_dir = dirs->dataDirPath(); + + auto fsAccess = ::mega::make_unique(); + fsAccess->setdefaultfolderpermissions(0700); + LocalPath local_data_dir = LocalPath::fromAbsolutePath(data_dir); + if (!is_file_exist(data_dir.c_str()) && !fsAccess->mkdirlocal(local_data_dir, false, false)) { - ConfigurationManager::loadConfigDir(); + LOG_err << "Data directory not created"; } + return data_dir; +} + +std::string ConfigurationManager::getStateDir() +{ + auto dirs = PlatformDirectories::getPlatformSpecificDirectories(); + auto state_dir = dirs->stateDirPath(); + + auto fsAccess = ::mega::make_unique(); + fsAccess->setdefaultfolderpermissions(0700); + LocalPath local_data_dir = LocalPath::fromAbsolutePath(state_dir); + if (!is_file_exist(state_dir.c_str()) && !fsAccess->mkdirlocal(local_data_dir, false, false)) + { + LOG_err << "State directory not created"; + } + + return state_dir; +} + +std::string ConfigurationManager::getDataFolderSubdir(const string &utf8Name) +{ + auto dirs = PlatformDirectories::getPlatformSpecificDirectories(); + auto data_dir = dirs->dataDirPath(); + MegaFileSystemAccess fsAccess; fsAccess.setdefaultfolderpermissions(0700); - LocalPath confSubdir = LocalPath::fromAbsolutePath(configFolder); + LocalPath dataSubDir = LocalPath::fromAbsolutePath(data_dir); - confSubdir.appendWithSeparator(LocalPath::fromRelativePath(utf8Name), true); + dataSubDir.appendWithSeparator(LocalPath::fromRelativePath(utf8Name), true); constexpr bool isHidden = true; constexpr bool reportExisting = false; - if (!is_file_exist(confSubdir.toPath(false).c_str()) && !fsAccess.mkdirlocal(confSubdir, isHidden, reportExisting)) + if (!is_file_exist(dataSubDir.toPath(false).c_str()) && !fsAccess.mkdirlocal(dataSubDir, isHidden, reportExisting)) { - LOG_err << "Config subfolder not created"; + LOG_err << "State subfolder not created"; } - return confSubdir.toPath(false); + return dataSubDir.toPath(false); } void ConfigurationManager::saveSession(const char*session) { std::lock_guard g(settingsMutex); + auto data_dir = getDataDir(); stringstream sessionfile; - if (!configFolder.size()) + if (!data_dir.empty()) { - loadConfigDir(); - } - if (configFolder.size()) - { - sessionfile << configFolder << "/" << "session"; + sessionfile << data_dir << "/" << "session"; LOG_debug << "Session file: " << sessionfile.str(); ofstream fo(sessionfile.str().c_str(), ios::out); @@ -191,7 +181,7 @@ void ConfigurationManager::saveSession(const char*session) } else { - LOG_err << "Couldnt access configuration folder "; + LOG_err << "Couldnt access data directory"; } } @@ -199,11 +189,11 @@ void ConfigurationManager::saveProperty(const char *property, const char *value) { std::lock_guard g(settingsMutex); - if (!configFolder.size()) + if (configFolder.empty()) { loadConfigDir(); } - if (configFolder.size()) + if (!configFolder.empty()) { bool found = false; stringstream configFile; @@ -325,11 +315,11 @@ void ConfigurationManager::saveSyncs(map *syncsmap) std::lock_guard g(settingsMutex); stringstream syncsfile; - if (!configFolder.size()) + if (configFolder.empty()) { loadConfigDir(); } - if (configFolder.size()) + if (!configFolder.empty()) { syncsfile << configFolder << "/" << "syncs"; LOG_debug << "Syncs file: " << syncsfile.str(); @@ -374,11 +364,11 @@ void ConfigurationManager::saveBackups(map *backupsmap) std::lock_guard g(settingsMutex); stringstream backupsfile; - if (!configFolder.size()) + if (configFolder.empty()) { loadConfigDir(); } - if (configFolder.size()) + if (!configFolder.empty()) { backupsfile << configFolder << "/" << "backups"; LOG_debug << "Backups file: " << backupsfile.str(); @@ -445,11 +435,11 @@ void ConfigurationManager::saveExcludedNames() { std::lock_guard g(settingsMutex); stringstream excludedNamesFile; - if (!configFolder.size()) + if (configFolder.empty()) { loadConfigDir(); } - if (configFolder.size()) + if (!configFolder.empty()) { excludedNamesFile << configFolder << "/" << "excluded"; LOG_debug << "Exclusion file: " << excludedNamesFile.str(); @@ -475,11 +465,11 @@ void ConfigurationManager::loadExcludedNames() { std::lock_guard g(settingsMutex); stringstream excludedNamesFile; - if (!configFolder.size()) + if (configFolder.empty()) { loadConfigDir(); } - if (configFolder.size()) + if (!configFolder.empty()) { excludedNamesFile << configFolder << "/" << "excluded"; LOG_debug << "Excluded file: " << excludedNamesFile.str(); @@ -543,11 +533,11 @@ void ConfigurationManager::loadsyncs() { std::lock_guard g(settingsMutex); stringstream syncsfile; - if (!configFolder.size()) + if (configFolder.empty()) { loadConfigDir(); } - if (configFolder.size()) + if (!configFolder.empty()) { syncsfile << configFolder << "/" << "syncs"; LOG_debug << "Syncs file: " << syncsfile.str(); @@ -620,11 +610,11 @@ void ConfigurationManager::loadbackups() { std::lock_guard g(settingsMutex); stringstream backupsfile; - if (!configFolder.size()) + if (configFolder.empty()) { loadConfigDir(); } - if (configFolder.size()) + if (!configFolder.empty()) { backupsfile << configFolder << "/" << "backups"; LOG_debug << "Backups file: " << backupsfile.str(); @@ -694,15 +684,14 @@ void ConfigurationManager::loadConfiguration(bool debug) { std::lock_guard g(settingsMutex); - if (!configFolder.size()) + // SESSION + stringstream sessionfile; + auto data_dir = getDataDir(); + + if (!data_dir.empty()) { - loadConfigDir(); - } - if (configFolder.size()) - { - //SESSION - stringstream sessionfile; - sessionfile << configFolder << "/" << "session"; + sessionfile << data_dir << "/" + << "session"; if (debug) { @@ -724,8 +713,7 @@ void ConfigurationManager::loadConfiguration(bool debug) fi.close(); } - - //Check if version has been updated. + // Check if version has been updated. stringstream versionionfile; versionionfile << configFolder << "/" << VERSION_FILE_NAME; @@ -759,25 +747,22 @@ void ConfigurationManager::loadConfiguration(bool debug) { if (debug) { - std::cout << "Couldnt access configuration folder " << std::endl; + std::cout << "Couldnt access data folder " << std::endl; } } } bool ConfigurationManager::lockExecution() { - if (!configFolder.size()) - { - loadConfigDir(); - } - if (configFolder.size()) + auto state_dir = getStateDir(); + if (!state_dir.empty()) { stringstream lockfile; #ifdef _WIN32 lockfile << "\\\\?\\"; - lockfile << configFolder << "\\" << "lockMCMD"; + lockfile << state_dir << "\\" << "lockMCMD"; #else - lockfile << configFolder << "/" << "lockMCMD"; + lockfile << state_dir << "/" << "lockMCMD"; #endif LOG_err << "Lock file: " << lockfile.str(); @@ -821,21 +806,18 @@ bool ConfigurationManager::lockExecution() } else { - LOG_err << "Couldnt access configuration folder "; + LOG_err << "Couldnt access state folder "; } return false; } void ConfigurationManager::unlockExecution() { - if (!configFolder.size()) - { - loadConfigDir(); - } - if (configFolder.size()) + auto state_dir = getStateDir(); + if (!state_dir.empty()) { stringstream lockfile; - lockfile << configFolder << "/" << "lockMCMD"; + lockfile << state_dir << "/" << "lockMCMD"; #if !defined(_WIN32) && defined(LOCK_EX) && defined(LOCK_NB) flock(fd, LOCK_UN | LOCK_NB); @@ -845,7 +827,7 @@ void ConfigurationManager::unlockExecution() } else { - LOG_err << "Couldnt access configuration folder "; + LOG_err << "Couldnt access state folder "; } } string ConfigurationManager::getConfigurationSValue(string propertyName) diff --git a/src/configurationmanager.h b/src/configurationmanager.h index 5479b015..05fffc01 100644 --- a/src/configurationmanager.h +++ b/src/configurationmanager.h @@ -40,7 +40,6 @@ private: static void loadConfigDir(); - static void removeSyncConfig(sync_struct *syncToRemove); public: static std::map oldConfiguredSyncs; //This will refer to old syncs from now on @@ -238,8 +237,10 @@ public: static std::string getConfigFolder(); - // creates a subfolder within config dir and returns it (utf8) - static std::string getConfFolderSubdir(const std::string &utf8Name); + // creates a subfolder within the state dir and returns it (utf8) + static std::string getDataFolderSubdir(const std::string &utf8Name); + static std::string getStateDir(); + static std::string getDataDir(); static bool getHasBeenUpdated(); diff --git a/src/megacmd.cpp b/src/megacmd.cpp index 7a1e1ae9..2691993b 100644 --- a/src/megacmd.cpp +++ b/src/megacmd.cpp @@ -5008,7 +5008,7 @@ int executeServer(int argc, char* argv[], LOG_debug << "MEGAcmd version: " << MEGACMD_MAJOR_VERSION << "." << MEGACMD_MINOR_VERSION << "." << MEGACMD_MICRO_VERSION << "." << MEGACMD_BUILD_ID << ": code " << MEGACMD_CODE_VERSION; - api = new MegaApi("BdARkQSQ", (MegaGfxProcessor*)NULL, ConfigurationManager::getConfigFolder().c_str(), userAgent); + api = new MegaApi("BdARkQSQ", (MegaGfxProcessor*)NULL, ConfigurationManager::getDataDir().c_str(), userAgent); if (!debug_api_url.empty()) { @@ -5020,7 +5020,7 @@ int executeServer(int argc, char* argv[], for (int i = 0; i < 5; i++) { MegaApi *apiFolder = new MegaApi("BdARkQSQ", (MegaGfxProcessor*)NULL, - ConfigurationManager::getConfFolderSubdir(std::string("apiFolder_").append(std::to_string(i))).c_str() + ConfigurationManager::getDataFolderSubdir(std::string("apiFolder_").append(std::to_string(i))).c_str() , userAgent); apiFolder->setLanguage(localecode.c_str()); apiFolders.push(apiFolder); diff --git a/src/megacmdlogger.cpp b/src/megacmdlogger.cpp index fe146733..faa6a99d 100644 --- a/src/megacmdlogger.cpp +++ b/src/megacmdlogger.cpp @@ -17,6 +17,7 @@ */ #include "megacmdlogger.h" +#include "megacmdcommonutils.h" #include @@ -307,13 +308,17 @@ OUTFSTREAMTYPE streamForDefaultFile() } } #else - const char* home = getenv("HOME"); - if (home) + auto dirs = PlatformDirectories::getPlatformSpecificDirectories(); + path = dirs->stateDirPath(); + + auto fsAccess = ::mega::make_unique(); + fsAccess->setdefaultfolderpermissions(0700); + LocalPath local_data_dir = LocalPath::fromAbsolutePath(path); + if (!fsAccess->mkdirlocal(local_data_dir, false, false)) { - path.append(home); - path.append("/.megaCmd/"); - path.append("/megacmdserver.log"); + LOG_err << "State directory not created"; } + path.append("/megacmdserver.log"); #endif return OUTFSTREAMTYPE(path); diff --git a/src/megacmdshell/megacmdshellcommunications.cpp b/src/megacmdshell/megacmdshellcommunications.cpp index 751b8245..3d426e69 100644 --- a/src/megacmdshell/megacmdshellcommunications.cpp +++ b/src/megacmdshell/megacmdshellcommunications.cpp @@ -20,6 +20,7 @@ */ #include "megacmdshellcommunications.h" +#include "megacmdcommonutils.h" #include #include @@ -105,61 +106,38 @@ void MegaCmdShellCommunications::closeSocket(SOCKET socket){ string createAndRetrieveConfigFolder() { - string configFolder; - + auto dirs = PlatformDirectories::getPlatformSpecificDirectories(); #ifdef _WIN32 - - TCHAR szPath[MAX_PATH]; - if (!SUCCEEDED(GetModuleFileName(NULL, szPath , MAX_PATH))) - { - cerr << "Couldnt get EXECUTABLE folder" << endl; - } - else - { - if (SUCCEEDED(PathRemoveFileSpec(szPath))) - { - if (PathAppend(szPath,TEXT(".megaCmd"))) - { - utf16ToUtf8(szPath, lstrlen(szPath), &configFolder); - } - } - } + return dirs->configDirPath(); //TODO: create folder (not required currently) #else - const char *homedir = NULL; + auto dir = dirs->configDirPath(); + struct stat st = {}; - homedir = getenv("HOME"); - if (!homedir) + if (stat(dir.c_str(), &st) == -1) { - struct passwd pd; - struct passwd* pwdptr = &pd; - struct passwd* tempPwdPtr; - char pwdbuffer[200]; - int pwdlinelen = sizeof( pwdbuffer ); - - if (( getpwuid_r(22, pwdptr, pwdbuffer, pwdlinelen, &tempPwdPtr)) != 0) - { - cerr << "Couldnt get HOME folder" << endl; - return "/tmp"; - } - else - { - homedir = pwdptr->pw_dir; - } + mkdir(dir.c_str(), 0700); } - stringstream sconfigDir; - sconfigDir << homedir << "/" << ".megaCmd"; - configFolder = sconfigDir.str(); - - - struct stat st; - if (stat(configFolder.c_str(), &st) == -1) { - mkdir(configFolder.c_str(), 0700); - } - + return dir; #endif +} - return configFolder; +string createAndRetrieveStateFolder() +{ + auto dirs = PlatformDirectories::getPlatformSpecificDirectories(); +#ifdef _WIN32 + return dirs->stateDirPath(); + //TODO: create folder (not required currently) +#else + auto dir = dirs->stateDirPath(); + struct stat st = {}; + + if (stat(dir.c_str(), &st) == -1) + { + mkdir(dir.c_str(), 0700); + } + return dir; +#endif } @@ -332,7 +310,7 @@ SOCKET MegaCmdShellCommunications::createSocket(int number, bool initializeserve setsid(); //create new session so as not to receive parent's Ctrl+C // Give an indication of where the logs will be find: - string pathtolog = createAndRetrieveConfigFolder()+"/megacmdserver.log"; + string pathtolog = createAndRetrieveStateFolder()+"/megacmdserver.log"; CERR << "[Initiating MEGAcmd server in background. Log: " << pathtolog << "]" << endl; freopen(std::string(pathtolog).append(".out").c_str(),"w",stdout);