summaryrefslogtreecommitdiff
path: root/indra/newview/llappviewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llappviewer.cpp')
-rw-r--r--indra/newview/llappviewer.cpp303
1 files changed, 226 insertions, 77 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4de80037ed..aa465b7a75 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2012, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -116,6 +116,7 @@
#include "llnotificationsutil.h"
#include "llleap.h"
+#include "stringize.h"
// Third party library includes
#include <boost/bind.hpp>
@@ -123,7 +124,6 @@
#include <boost/algorithm/string.hpp>
-
#if LL_WINDOWS
# include <share.h> // For _SH_DENYWR in initMarkerFile
#else
@@ -219,6 +219,7 @@
#include "llmachineid.h"
#include "llmainlooprepeater.h"
+
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
// this app, or another 'component' of the viewer. App globals should be
@@ -322,7 +323,7 @@ BOOL gLogoutInProgress = FALSE;
////////////////////////////////////////////////////////////
// Internal globals... that should be removed.
static std::string gArgs;
-
+const int MAX_MARKER_LENGTH = 1024;
const std::string MARKER_FILE_NAME("SecondLife.exec_marker");
const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
@@ -379,6 +380,9 @@ void init_default_trans_args()
default_trans_args.insert("CAPITALIZED_APP_NAME");
default_trans_args.insert("SECOND_LIFE_GRID");
default_trans_args.insert("SUPPORT_SITE");
+ // This URL shows up in a surprising number of places in various skin
+ // files. We really only want to have to maintain a single copy of it.
+ default_trans_args.insert("create_account_url");
}
//----------------------------------------------------------------------------
@@ -622,7 +626,7 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
LLAppViewer::LLAppViewer() :
mMarkerFile(),
- mLogoutMarkerFile(NULL),
+ mLogoutMarkerFile(),
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
@@ -688,7 +692,7 @@ bool LLAppViewer::init()
gDirUtilp->initAppDirs("SecondLife");
// set skin search path to default, will be overridden later
// this allows simple skinned file lookups to work
- gDirUtilp->setSkinFolder("default");
+ gDirUtilp->setSkinFolder("default", "en");
initLogging();
@@ -706,7 +710,7 @@ bool LLAppViewer::init()
//set the max heap size.
initMaxHeapSize() ;
- LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")) ;
+ LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ;
// write Google Breakpad minidump files to our log directory
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
@@ -731,6 +735,10 @@ bool LLAppViewer::init()
LLViewerStatsRecorder::initClass();
#endif
+ // Initialize the non-LLCurl libcurl library. Should be called
+ // before consumers (LLTextureFetch).
+ mAppCoreHttp.init();
+
// *NOTE:Mani - LLCurl::initClass is not thread safe.
// Called before threads are created.
LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"),
@@ -772,12 +780,15 @@ bool LLAppViewer::init()
&LLUI::sGLScaleFactor);
LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
- // Setup paths and LLTrans after LLUI::initClass has been called.
- LLUI::setupPaths();
- LLTransUtil::parseStrings("strings.xml", default_trans_args);
- LLTransUtil::parseLanguageStrings("language_settings.xml");
+ // NOW LLUI::getLanguage() should work. gDirUtilp must know the language
+ // for this session ASAP so all the file-loading commands that follow,
+ // that use findSkinnedFilenames(), will include the localized files.
+ gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage());
- // Setup notifications after LLUI::setupPaths() has been called.
+ // Setup LLTrans after LLUI::initClass has been called.
+ initStrings();
+
+ // Setup notifications after LLUI::initClass() has been called.
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
@@ -1881,6 +1892,7 @@ bool LLAppViewer::cleanup()
// Delete workers first
// shotdown all worker threads before deleting them in case of co-dependencies
+ mAppCoreHttp.requestStop();
sTextureFetch->shutdown();
sTextureCache->shutdown();
sImageDecodeThread->shutdown();
@@ -1896,6 +1908,9 @@ bool LLAppViewer::cleanup()
LLCurl::cleanupClass();
LL_CHECK_MEMORY
+ // Non-LLCurl libcurl library
+ mAppCoreHttp.cleanup();
+
LLFilePickerThread::cleanupClass();
//MUST happen AFTER LLCurl::cleanupClass
@@ -2249,10 +2264,8 @@ bool LLAppViewer::initConfiguration()
OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
return false;
}
-
- LLUI::setupPaths(); // setup paths for LLTrans based on settings files only
- LLTransUtil::parseStrings("strings.xml", default_trans_args);
- LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+ initStrings(); // setup paths for LLTrans based on settings files only
// - set procedural settings
// Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet
gSavedSettings.setString("ClientSettingsFile",
@@ -2566,13 +2579,15 @@ bool LLAppViewer::initConfiguration()
LLStartUp::setStartSLURL(start_slurl);
}
- const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
- if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
- {
- // hack to force the skin to default.
- gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
- //gDirUtilp->setSkinFolder("default");
- }
+ const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
+ if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
+ {
+ // Examining "Language" may not suffice -- see LLUI::getLanguage()
+ // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
+ // good because we haven't yet called LLUI::initClass().
+ gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
+ gSavedSettings.getString("Language"));
+ }
if (gSavedSettings.getBOOL("SpellCheck"))
{
@@ -2744,6 +2759,52 @@ bool LLAppViewer::initConfiguration()
return true; // Config was successful.
}
+// The following logic is replicated in initConfiguration() (to be able to get
+// some initial strings before we've finished initializing enough to know the
+// current language) and also in init() (to initialize for real). Somehow it
+// keeps growing, necessitating a method all its own.
+void LLAppViewer::initStrings()
+{
+ LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+ // parseStrings() sets up the LLTrans substitution table. Add this one item.
+ LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid"));
+
+ // Now that we've set "[sourceid]", have to go back through
+ // default_trans_args and reinitialize all those other keys because some
+ // of them, in turn, reference "[sourceid]".
+ BOOST_FOREACH(std::string key, default_trans_args)
+ {
+ std::string brackets(key), nobrackets(key);
+ // Invalid to inspect key[0] if key is empty(). But then, the entire
+ // body of this loop is pointless if key is empty().
+ if (key.empty())
+ continue;
+
+ if (key[0] != '[')
+ {
+ // key was passed without brackets. That means that 'nobrackets'
+ // is correct but 'brackets' is not.
+ brackets = STRINGIZE('[' << brackets << ']');
+ }
+ else
+ {
+ // key was passed with brackets. That means that 'brackets' is
+ // correct but 'nobrackets' is not. Erase the left bracket.
+ nobrackets.erase(0, 1);
+ std::string::size_type length(nobrackets.length());
+ if (length && nobrackets[length - 1] == ']')
+ {
+ nobrackets.erase(length - 1);
+ }
+ }
+ // Calling LLTrans::getString() is what embeds the other default
+ // translation strings into this one.
+ LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets));
+ }
+}
+
namespace {
// *TODO - decide if there's a better place for these functions.
// do we need a file llupdaterui.cpp or something? -brad
@@ -3145,8 +3206,8 @@ void LLAppViewer::writeSystemInfo()
}
// Dump some debugging info
- LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME")
- << " version " << LLVersionInfo::getShortVersion() << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL;
// Dump the local time and time zone
time_t now;
@@ -3274,22 +3335,27 @@ void LLAppViewer::handleViewerCrash()
//we're already in a crash situation
if (gDirUtilp)
{
- std::string crash_file_name;
- if(gLLErrorActivated) crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME);
- else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
- llinfos << "Creating crash marker file " << crash_file_name << llendl;
+ std::string crash_file_name = ( gLLErrorActivated )
+ ? gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME)
+ : gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
+ LL_INFOS("MarkerFile") << "Creating crash marker file " << crash_file_name << LL_ENDL;
LLAPRFile crash_file ;
crash_file.open(crash_file_name, LL_APR_W);
if (crash_file.getFileHandle())
{
LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
+ recordMarkerVersion(crash_file);
}
else
{
LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL;
}
}
+ else
+ {
+ LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL;
+ }
if (gMessageSystem && gDirUtilp)
{
@@ -3341,7 +3407,7 @@ bool LLAppViewer::anotherInstanceRunning()
// If the file is currently locked, that means another process is already running.
std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
+ LL_DEBUGS("MarkerFile") << "Checking marker file '"<< marker_file << "' for lock..." << LL_ENDL;
//Freeze case checks
if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
@@ -3367,6 +3433,46 @@ bool LLAppViewer::anotherInstanceRunning()
return false;
}
+// static
+void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
+{
+ std::string marker_version(LLVersionInfo::getChannelAndVersion());
+ if ( marker_version.length() > MAX_MARKER_LENGTH )
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ") greater than maximum: marker matching may be incorrect" << LL_ENDL;
+ }
+
+ // record the viewer version in the marker file
+ marker_file.write(marker_version.data(), marker_version.length());
+}
+
+bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
+{
+ bool sameVersion = false;
+
+ std::string my_version(LLVersionInfo::getChannelAndVersion());
+ char marker_version[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
+
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
+ {
+ marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
+ LL_DEBUGS("MarkerFile") << "Compare markers: ";
+ std::string marker_string(marker_version, marker_version_length);
+ LL_CONT << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << LL_ENDL;
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
+ {
+ sameVersion = true;
+ }
+ marker_file.close();
+ }
+ return sameVersion;
+}
+
void LLAppViewer::initMarkerFile()
{
//First, check for the existence of other files.
@@ -3389,27 +3495,55 @@ void LLAppViewer::initMarkerFile()
if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
{
- gLastExecEvent = LAST_EXEC_FROZE;
- LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;
+ if ( markerIsSameVersion(mMarkerFileName) )
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found" << LL_ENDL;
+ gLastExecEvent = LAST_EXEC_FROZE;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
+ }
}
if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
{
- gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
- LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(logout_marker_file))
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
+ LL_INFOS("MarkerFile") << "Logout crashed '"<< logout_marker_file << "', setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(logout_marker_file);
}
if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
{
- if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- else gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(llerror_marker_file))
+ {
+ gLastExecEvent = ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
+ ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_LLERROR_CRASH;
+ LL_INFOS("MarkerFile") << "Last exec LLError '"<< llerror_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Last exec LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(llerror_marker_file);
}
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
- if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- else gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(error_marker_file))
+ {
+ gLastExecEvent = (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
+ ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_OTHER_CRASH;
+ LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(error_marker_file);
}
@@ -3425,35 +3559,48 @@ void LLAppViewer::initMarkerFile()
if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
{
- LL_DEBUGS("MarkerFile") << "Marker file created." << LL_ENDL;
+ LL_DEBUGS("MarkerFile") << "Marker file '"<< mMarkerFileName << "' created." << LL_ENDL;
+ if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))
+ {
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL;
+ }
}
else
{
- LL_INFOS("MarkerFile") << "Failed to create marker file." << LL_ENDL;
- return;
+ LL_INFOS("MarkerFile") << "Failed to create marker file '"<< mMarkerFileName << "'." << LL_ENDL;
}
- if (apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
- {
- mMarkerFile.close() ;
- LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL;
- return;
- }
-
- LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL;
}
void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
{
- LL_DEBUGS("MarkerFile") << "removeMarkerFile()" << LL_ENDL;
+ LL_DEBUGS("MarkerFile") << "removeMarkerFile("<<leave_logout_marker<<")" << LL_ENDL;
if (mMarkerFile.getFileHandle())
{
- mMarkerFile.close() ;
+ LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
+ mMarkerFile.close();
LLAPRFile::remove( mMarkerFileName );
}
- if (mLogoutMarkerFile != NULL && !leave_logout_marker)
+ else
{
+ LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
+ }
+ if (!leave_logout_marker)
+ {
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
+ mLogoutMarkerFile.close();
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
+ }
LLAPRFile::remove( mLogoutMarkerFileName );
- mLogoutMarkerFile = NULL;
}
}
@@ -3596,8 +3743,7 @@ void LLAppViewer::migrateCacheDirectory()
{
gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE);
- std::string delimiter = gDirUtilp->getDirDelimiter();
- std::string old_cache_dir = gDirUtilp->getOSUserAppDir() + delimiter + "cache";
+ std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache");
std::string new_cache_dir = gDirUtilp->getCacheDir(true);
if (gDirUtilp->fileExists(old_cache_dir))
@@ -3613,8 +3759,8 @@ void LLAppViewer::migrateCacheDirectory()
while (iter.next(file_name))
{
if (file_name == "." || file_name == "..") continue;
- std::string source_path = old_cache_dir + delimiter + file_name;
- std::string dest_path = new_cache_dir + delimiter + file_name;
+ std::string source_path = gDirUtilp->add(old_cache_dir, file_name);
+ std::string dest_path = gDirUtilp->add(new_cache_dir, file_name);
if (!LLFile::rename(source_path, dest_path))
{
file_count++;
@@ -3845,7 +3991,7 @@ bool LLAppViewer::initCache()
LLDirIterator iter(dir, mask);
if (iter.next(found_file))
{
- old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file;
+ old_vfs_data_file = gDirUtilp->add(dir, found_file);
S32 start_pos = found_file.find_last_of('.');
if (start_pos > 0)
@@ -4356,6 +4502,10 @@ void LLAppViewer::idle()
{
return;
}
+ if (gTeleportDisplay)
+ {
+ return;
+ }
gViewerWindow->updateUI();
@@ -4654,16 +4804,15 @@ void LLAppViewer::sendLogoutRequest()
mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
LLAPRFile outfile ;
- outfile.open(mLogoutMarkerFileName, LL_APR_W);
- mLogoutMarkerFile = outfile.getFileHandle() ;
- if (mLogoutMarkerFile)
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_W);
+ if (mLogoutMarkerFile.getFileHandle())
{
- llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl;
- apr_file_close(mLogoutMarkerFile);
+ LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << mLogoutMarkerFileName << LL_ENDL;
+ recordMarkerVersion(outfile);
}
else
{
- llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl;
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
}
}
}
@@ -5156,20 +5305,20 @@ void LLAppViewer::launchUpdater()
// we tell the updater where to find the xml containing string
// translations which it can use for its own UI
std::string xml_strings_file = "strings.xml";
- std::vector<std::string> xui_path_vec = LLUI::getXUIPaths();
+ std::vector<std::string> xui_path_vec =
+ gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_strings_file);
std::string xml_search_paths;
- std::vector<std::string>::const_iterator iter;
+ const char* delim = "";
// build comma-delimited list of xml paths to pass to updater
- for (iter = xui_path_vec.begin(); iter != xui_path_vec.end(); )
- {
- std::string this_skin_dir = gDirUtilp->getDefaultSkinDir()
- + gDirUtilp->getDirDelimiter()
- + (*iter);
- llinfos << "Got a XUI path: " << this_skin_dir << llendl;
- xml_search_paths.append(this_skin_dir);
- ++iter;
- if (iter != xui_path_vec.end())
- xml_search_paths.append(","); // comma-delimit
+ BOOST_FOREACH(std::string this_skin_path, xui_path_vec)
+ {
+ // Although we already have the full set of paths with the filename
+ // appended, the linux-updater.bin command-line switches require us to
+ // snip the filename OFF and pass it as a separate switch argument. :-P
+ llinfos << "Got a XUI path: " << this_skin_path << llendl;
+ xml_search_paths.append(delim);
+ xml_search_paths.append(gDirUtilp->getDirName(this_skin_path));
+ delim = ",";
}
// build the overall command-line to run the updater correctly
LLAppViewer::sUpdaterInfo->mUpdateExePath =