diff options
author | AndreyL ProductEngine <alihatskiy@productengine.com> | 2019-03-01 02:24:00 +0200 |
---|---|---|
committer | AndreyL ProductEngine <alihatskiy@productengine.com> | 2019-03-01 02:24:00 +0200 |
commit | 36cb6933e6c1ad92e1887503b74a05c32988b0f1 (patch) | |
tree | 80739997a9b1e00f93af4e273058ab52a761e36a /indra/llvfs | |
parent | 599e08181544f214142703928a6d242a0ae72e60 (diff) | |
parent | 03db2ddc9c27cf842c6185826617b0da0d2b87f5 (diff) |
Merged in lindenlab/viewer-release
Diffstat (limited to 'indra/llvfs')
-rw-r--r-- | indra/llvfs/lldir.cpp | 5 | ||||
-rw-r--r-- | indra/llvfs/lldir_linux.cpp | 33 | ||||
-rw-r--r-- | indra/llvfs/lldir_mac.cpp | 4 | ||||
-rw-r--r-- | indra/llvfs/lldir_solaris.cpp | 60 | ||||
-rw-r--r-- | indra/llvfs/lldir_win32.cpp | 111 |
5 files changed, 149 insertions, 64 deletions
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 2069888774..18836e54b0 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -42,6 +42,7 @@ #include "lldiriterator.h" #include "stringize.h" +#include "llstring.h" #include <boost/filesystem.hpp> #include <boost/foreach.hpp> #include <boost/range/begin.hpp> @@ -317,9 +318,9 @@ const std::string& LLDir::getChatLogsDir() const void LLDir::setDumpDir( const std::string& path ) { LLDir::sDumpDir = path; - if (! sDumpDir.empty() && sDumpDir.rbegin() == mDirDelimiter.rbegin() ) + if (LLStringUtil::endsWith(sDumpDir, mDirDelimiter)) { - sDumpDir.erase(sDumpDir.size() -1); + sDumpDir.erase(sDumpDir.size() - mDirDelimiter.size()); } } diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index 2cd06b81f8..80ad05345a 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -29,6 +29,7 @@ #include "lldir_linux.h" #include "llerror.h" #include "llrand.h" +#include "llstring.h" #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> @@ -40,28 +41,24 @@ static std::string getCurrentUserHome(char* fallback) { const uid_t uid = getuid(); struct passwd *pw; - char *result_cstr = fallback; - + pw = getpwuid(uid); if ((pw != NULL) && (pw->pw_dir != NULL)) { - result_cstr = (char*) pw->pw_dir; + return pw->pw_dir; + } + + LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; + auto home_env = LLStringUtil::getoptenv("HOME"); + if (home_env) + { + return *home_env; } else { - LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; - const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */ - if (home_env) - { - result_cstr = (char*) home_env; - } - else - { - LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; - } + LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; + return fallback; } - - return std::string(result_cstr); } @@ -156,18 +153,18 @@ void LLDir_Linux::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; - mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + mSkinBaseDir = add(mAppRODataDir, "skins"); } mAppName = app_name; std::string upper_app_name(app_name); LLStringUtil::toUpper(upper_app_name); - char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */ + auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR")); if (app_home_env) { // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR - mOSUserAppDir = app_home_env; + mOSUserAppDir = *app_home_env; } else { diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index 79c4362747..87dc1b9795 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -171,9 +171,9 @@ void LLDir_Mac::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; - mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + mSkinBaseDir = add(mAppRODataDir, "skins"); } - mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "../Resources", "ca-bundle.crt"); + mCAFile = add(mAppRODataDir, "ca-bundle.crt"); } std::string LLDir_Mac::getCurPath() diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp index d3536a12ee..f18560ff20 100644 --- a/indra/llvfs/lldir_solaris.cpp +++ b/indra/llvfs/lldir_solaris.cpp @@ -29,6 +29,7 @@ #include "lldir_solaris.h" #include "llerror.h" #include "llrand.h" +#include "llstring.h" #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> @@ -41,30 +42,28 @@ static std::string getCurrentUserHome(char* fallback) { + // fwiw this exactly duplicates getCurrentUserHome() in lldir_linux.cpp... + // we should either derive both from LLDir_Posix or just axe Solaris. const uid_t uid = getuid(); struct passwd *pw; - char *result_cstr = fallback; - + pw = getpwuid(uid); if ((pw != NULL) && (pw->pw_dir != NULL)) { - result_cstr = (char*) pw->pw_dir; + return pw->pw_dir; + } + + LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; + auto home_env = LLStringUtil::getoptenv("HOME"); + if (home_env) + { + return *home_env; } else { - LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; - const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */ - if (home_env) - { - result_cstr = (char*) home_env; - } - else - { - LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; - } + LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; + return fallback; } - - return std::string(result_cstr); } @@ -135,27 +134,15 @@ LLDir_Solaris::LLDir_Solaris() //NOTE: Why force people to cd into the package directory? // Look for SECONDLIFE env variable and use it, if set. - char *dcf = getenv("SECONDLIFE"); - if(dcf != NULL){ - (void)strcpy(path, dcf); - (void)strcat(path, "/bin"); //NOTE: make sure we point at the bin - mExecutableDir = strdup(path); + auto SECONDLIFE(LLDirUtil::getoptenv("SECONDLIFE")); + if(SECONDLIFE){ + mExecutableDir = add(*SECONDLIFE, "bin"); //NOTE: make sure we point at the bin }else{ - // plunk a null at last '/' to get exec dir - char *s = execpath + strlen(execpath) -1; - while(*s != '/' && s != execpath){ - --s; - } - - if(s != execpath){ - *s = (char)NULL; - - mExecutableDir = strdup(execpath); - LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL; - } + mExecutableDir = getDirName(execpath); + LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL; } - - mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; + + mLLPluginDir = add(mExecutableDir, "llplugin"); // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something. mTempDir = "/tmp"; @@ -175,17 +162,18 @@ void LLDir_Solaris::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; + mSkinBaseDir = add(mAppRODataDir, "skins"); } mAppName = app_name; std::string upper_app_name(app_name); LLStringUtil::toUpper(upper_app_name); - char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */ + auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR")); if (app_home_env) { // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR - mOSUserAppDir = app_home_env; + mOSUserAppDir = *app_home_env; } else { diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 9836fa28f2..b3b3afb37e 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -30,7 +30,9 @@ #include "lldir_win32.h" #include "llerror.h" -#include "llrand.h" // for gLindenLabRandomNumber +#include "llstring.h" +#include "stringize.h" +#include "llfile.h" #include <shlobj.h> #include <fstream> @@ -43,15 +45,87 @@ #define PACKVERSION(major,minor) MAKELONG(minor,major) DWORD GetDllVersion(LPCTSTR lpszDllName); +namespace +{ // anonymous + enum class prst { INIT, OPEN, SKIP } state = prst::INIT; + // This is called so early that we can't count on static objects being + // properly constructed yet, so declare a pointer instead of an instance. + std::ofstream* prelogf = nullptr; + + void prelog(const std::string& message) + { + boost::optional<std::string> prelog_name; + + switch (state) + { + case prst::INIT: + // assume we failed, until we succeed + state = prst::SKIP; + + prelog_name = LLStringUtil::getoptenv("PRELOG"); + if (! prelog_name) + // no PRELOG variable set, carry on + return; + prelogf = new llofstream(*prelog_name, std::ios_base::app); + if (! (prelogf && prelogf->is_open())) + // can't complain to anybody; how? + return; + // got the log file open, cool! + state = prst::OPEN; + (*prelogf) << "========================================================================" + << std::endl; + // fall through, don't break + + case prst::OPEN: + (*prelogf) << message << std::endl; + break; + + case prst::SKIP: + // either PRELOG isn't set, or we failed to open that pathname + break; + } + } +} // anonymous namespace + +#define PRELOG(expression) prelog(STRINGIZE(expression)) + LLDir_Win32::LLDir_Win32() { // set this first: used by append() and add() methods mDirDelimiter = "\\"; + WCHAR w_str[MAX_PATH]; // Application Data is where user settings go. We rely on $APPDATA being - // correct; in fact the VMP makes a point of setting it properly, since - // Windows itself botches the job for non-ASCII usernames (MAINT-8087). - mOSUserDir = ll_safe_string(getenv("APPDATA")); + // correct. + auto APPDATA = LLStringUtil::getoptenv("APPDATA"); + if (APPDATA) + { + mOSUserDir = *APPDATA; + } + PRELOG("APPDATA='" << mOSUserDir << "'"); + // On Windows, we could have received a plain-ASCII pathname in which + // non-ASCII characters have been munged to '?', or the pathname could + // have been badly encoded and decoded such that we now have garbage + // instead of a valid path. Check that mOSUserDir actually exists. + if (mOSUserDir.empty() || ! fileExists(mOSUserDir)) + { + PRELOG("APPDATA does not exist"); + //HRESULT okay = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, w_str); + wchar_t *pwstr = NULL; + HRESULT okay = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &pwstr); + PRELOG("SHGetKnownFolderPath(FOLDERID_RoamingAppData) returned " << okay); + if (SUCCEEDED(okay) && pwstr) + { + // But of course, only update mOSUserDir if SHGetKnownFolderPath() works. + mOSUserDir = ll_convert_wide_to_string(pwstr); + // Not only that: update our environment so that child processes + // will see a reasonable value as well. + _wputenv_s(L"APPDATA", pwstr); + // SHGetKnownFolderPath() contract requires us to free pwstr + CoTaskMemFree(pwstr); + PRELOG("mOSUserDir='" << mOSUserDir << "'"); + } + } // We want cache files to go on the local disk, even if the // user is on a network with a "roaming profile". @@ -61,9 +135,34 @@ LLDir_Win32::LLDir_Win32() // // We used to store the cache in AppData\Roaming, and the installer // cleans up that version on upgrade. JC - mOSCacheDir = ll_safe_string(getenv("LOCALAPPDATA")); + auto LOCALAPPDATA = LLStringUtil::getoptenv("LOCALAPPDATA"); + if (LOCALAPPDATA) + { + mOSCacheDir = *LOCALAPPDATA; + } + PRELOG("LOCALAPPDATA='" << mOSCacheDir << "'"); + // Windows really does not deal well with pathnames containing non-ASCII + // characters. See above remarks about APPDATA. + if (mOSCacheDir.empty() || ! fileExists(mOSCacheDir)) + { + PRELOG("LOCALAPPDATA does not exist"); + //HRESULT okay = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, w_str); + wchar_t *pwstr = NULL; + HRESULT okay = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pwstr); + PRELOG("SHGetKnownFolderPath(FOLDERID_LocalAppData) returned " << okay); + if (SUCCEEDED(okay) && pwstr) + { + // But of course, only update mOSCacheDir if SHGetKnownFolderPath() works. + mOSCacheDir = ll_convert_wide_to_string(pwstr); + // Update our environment so that child processes will see a + // reasonable value as well. + _wputenv_s(L"LOCALAPPDATA", pwstr); + // SHGetKnownFolderPath() contract requires us to free pwstr + CoTaskMemFree(pwstr); + PRELOG("mOSCacheDir='" << mOSCacheDir << "'"); + } + } - WCHAR w_str[MAX_PATH]; if (GetTempPath(MAX_PATH, w_str)) { if (wcslen(w_str)) /* Flawfinder: ignore */ |