summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorGlenn Glazer <coyot@lindenlab.com>2017-07-27 10:32:47 -0700
committerGlenn Glazer <coyot@lindenlab.com>2017-07-27 10:32:47 -0700
commita25c541c0d0763d0dfb6b131ac02f70f9ba6cb99 (patch)
tree72fe4ae640e229508f7b974a2cb54396d70ff7bc /indra
parentb46697fcc155d026b5a951256d53581e7af20036 (diff)
MAINT-7643: add viewer bitness to crash log output
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llappviewer.cpp446
-rw-r--r--indra/newview/llversioninfo.h3
2 files changed, 410 insertions, 39 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 5a0cdd4f1a..31dc286724 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -93,6 +93,7 @@
#include "llvocache.h"
#include "llvopartgroup.h"
#include "llweb.h"
+#include "llupdaterservice.h"
#include "llfloatertexturefetchdebugger.h"
#include "llspellcheck.h"
#include "llscenemonitor.h"
@@ -124,8 +125,10 @@
#include "llcoros.h"
#include "llexception.h"
#if !LL_LINUX
-#include "cef/dullahan.h"
+#include "cef/llceflib.h"
+#if LL_WINDOWS
#include "vlc/libvlc_version.h"
+#endif // LL_WINDOWS
#endif // LL_LINUX
// Third party library includes
@@ -267,6 +270,7 @@ static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
// viewer.cpp - these are only used in viewer, should be easily moved.
#if LL_DARWIN
+const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
extern void init_apple_menu(const char* product);
#endif // LL_DARWIN
@@ -292,7 +296,9 @@ S32 gLastExecDuration = -1; // (<0 indicates unknown)
# define LL_PLATFORM_KEY "mac"
#elif LL_LINUX
# define LL_PLATFORM_KEY "lnx"
-else
+#elif LL_SOLARIS
+# define LL_PLATFORM_KEY "sol"
+#else
# error "Unknown Platform"
#endif
const char* gPlatform = LL_PLATFORM_KEY;
@@ -328,10 +334,10 @@ BOOL gDisconnected = FALSE;
// used to restore texture state after a mode switch
LLFrameTimer gRestoreGLTimer;
BOOL gRestoreGL = FALSE;
-bool gUseWireframe = FALSE;
+BOOL gUseWireframe = FALSE;
//use for remember deferred mode in wireframe switch
-bool gInitialDeferredModeForWireframe = FALSE;
+BOOL gInitialDeferredModeForWireframe = FALSE;
// VFS globals - see llappviewer.h
LLVFS* gStaticVFS = NULL;
@@ -469,6 +475,8 @@ struct SettingsFiles : public LLInitParam::Block<SettingsFiles>
static std::string gWindowTitle;
+LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
+
//----------------------------------------------------------------------------
// Metrics logging control constants
//----------------------------------------------------------------------------
@@ -695,6 +703,7 @@ LLAppViewer::LLAppViewer()
mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL),
+ mUpdater(new LLUpdaterService()),
mSettingsLocationList(NULL),
mIsFirstRun(false)
{
@@ -724,13 +733,17 @@ LLAppViewer::LLAppViewer()
// OK to write stuff to logs now, we've now crash reported if necessary
//
+ LLLoginInstance::instance().setUpdaterService(mUpdater.get());
LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString());
}
LLAppViewer::~LLAppViewer()
{
delete mSettingsLocationList;
+ LLViewerEventRecorder::deleteSingleton();
+ LLLoginInstance::instance().setUpdaterService(0);
+
destroyMainloopTimeout();
// If we got to this destructor somehow, the app didn't hang.
@@ -871,6 +884,14 @@ bool LLAppViewer::init()
writeSystemInfo();
+ // Initialize updater service (now that we have an io pump)
+ initUpdater();
+ if(isQuitting())
+ {
+ // Early out here because updater set the quitting flag.
+ return true;
+ }
+
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -1077,7 +1098,7 @@ bool LLAppViewer::init()
minSpecs += "\n";
unsupported = true;
}
- if(gSysMemory.getPhysicalMemoryKB() < minRAM)
+ if(gSysMemory.getPhysicalMemoryClamped() < minRAM)
{
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM");
minSpecs += "\n";
@@ -2085,15 +2106,20 @@ bool LLAppViewer::cleanup()
// realtime, or might throw an exception.
LLSingletonBase::cleanupAll();
- // The logging subsystem depends on an LLSingleton. Any logging after
- // LLSingletonBase::deleteAll() won't be recorded.
- LL_INFOS() << "Goodbye!" << LL_ENDL;
-
// This calls every remaining LLSingleton's deleteSingleton() method.
// No class destructor should perform any cleanup that might take
// significant realtime, or throw an exception.
+ // LLSingleton machinery includes a last-gasp implicit deleteAll() call,
+ // so this explicit call shouldn't strictly be necessary. However, by the
+ // time the runtime engages that implicit call, it may already have
+ // destroyed things like std::cerr -- so the implicit deleteAll() refrains
+ // from logging anything. Since both cleanupAll() and deleteAll() call
+ // their respective cleanup methods in computed dependency order, it's
+ // probably useful to be able to log that order.
LLSingletonBase::deleteAll();
+ LL_INFOS() << "Goodbye!" << LL_ENDL;
+
removeDumpDir();
// return 0;
@@ -2883,6 +2909,224 @@ void LLAppViewer::initStrings()
}
}
+namespace {
+ // *TODO - decide if there's a better place for these functions.
+ // do we need a file llupdaterui.cpp or something? -brad
+
+ void apply_update_callback(LLSD const & notification, LLSD const & response)
+ {
+ LL_DEBUGS() << "LLUpdate user response: " << response << LL_ENDL;
+ if(response["OK_okcancelbuttons"].asBoolean())
+ {
+ LL_INFOS() << "LLUpdate restarting viewer" << LL_ENDL;
+ static const bool install_if_ready = true;
+ // *HACK - this lets us launch the installer immediately for now
+ LLUpdaterService().startChecking(install_if_ready);
+ }
+ }
+
+ void apply_update_ok_callback(LLSD const & notification, LLSD const & response)
+ {
+ LL_INFOS() << "LLUpdate restarting viewer" << LL_ENDL;
+ static const bool install_if_ready = true;
+ // *HACK - this lets us launch the installer immediately for now
+ LLUpdaterService().startChecking(install_if_ready);
+ }
+
+ void on_update_downloaded(LLSD const & data)
+ {
+ std::string notification_name;
+ void (*apply_callback)(LLSD const &, LLSD const &) = NULL;
+
+ /* Build up the notification name...
+ * it can be any of these, which are included here for the sake of grep:
+ * RequiredUpdateDownloadedDialog
+ * RequiredUpdateDownloadedVerboseDialog
+ * OtherChannelRequiredUpdateDownloadedDialog
+ * OtherChannelRequiredUpdateDownloadedVerbose
+ * DownloadBackgroundTip
+ * DownloadBackgroundDialog
+ * OtherChannelDownloadBackgroundTip
+ * OtherChannelDownloadBackgroundDialog
+ */
+ {
+ LL_DEBUGS("UpdaterService") << "data = ";
+ std::ostringstream data_dump;
+ LLSDSerialize::toNotation(data, data_dump);
+ LL_CONT << data_dump.str() << LL_ENDL;
+ }
+ if(data["channel"].asString() != LLVersionInfo::getChannel())
+ {
+ notification_name.append("OtherChannel");
+ }
+ if(data["required"].asBoolean())
+ {
+ if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT)
+ {
+ // The user never saw the progress bar.
+ apply_callback = &apply_update_ok_callback;
+ notification_name += "RequiredUpdateDownloadedVerboseDialog";
+ }
+ else if(LLStartUp::getStartupState() < STATE_WORLD_INIT)
+ {
+ // The user is logging in but blocked.
+ apply_callback = &apply_update_ok_callback;
+ notification_name += "RequiredUpdateDownloadedDialog";
+ }
+ else
+ {
+ // The user is already logged in; treat like an optional update.
+ apply_callback = &apply_update_callback;
+ notification_name += "DownloadBackgroundTip";
+ }
+ }
+ else
+ {
+ apply_callback = &apply_update_callback;
+ if(LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ // CHOP-262 we need to use a different notification
+ // method prior to login.
+ notification_name += "DownloadBackgroundDialog";
+ }
+ else
+ {
+ notification_name += "DownloadBackgroundTip";
+ }
+ }
+
+ LLSD substitutions;
+ substitutions["VERSION"] = data["version"];
+ std::string new_channel = data["channel"].asString();
+ substitutions["NEW_CHANNEL"] = new_channel;
+ std::string info_url = data["info_url"].asString();
+ if ( !info_url.empty() )
+ {
+ substitutions["INFO_URL"] = info_url;
+ }
+ else
+ {
+ LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL;
+
+ // truncate version at the rightmost '.'
+ std::string version_short(data["version"]);
+ size_t short_length = version_short.rfind('.');
+ if (short_length != std::string::npos)
+ {
+ version_short.resize(short_length);
+ }
+
+ LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]");
+ relnotes_url.setArg("[VERSION_SHORT]", version_short);
+
+ // *TODO thread the update service's response through to this point
+ std::string const & channel = LLVersionInfo::getChannel();
+ boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free);
+
+ relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
+ relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
+ substitutions["INFO_URL"] = relnotes_url.getString();
+ }
+
+ LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);
+ }
+
+ void install_error_callback(LLSD const & notification, LLSD const & response)
+ {
+ LLAppViewer::instance()->forceQuit();
+ }
+
+ bool notify_update(LLSD const & evt)
+ {
+ std::string notification_name;
+ switch (evt["type"].asInteger())
+ {
+ case LLUpdaterService::DOWNLOAD_COMPLETE:
+ on_update_downloaded(evt);
+ break;
+ case LLUpdaterService::INSTALL_ERROR:
+ if(evt["required"].asBoolean()) {
+ LLNotificationsUtil::add("FailedRequiredUpdateInstall", LLSD(), LLSD(), &install_error_callback);
+ } else {
+ LLNotificationsUtil::add("FailedUpdateInstall");
+ }
+ break;
+ default:
+ break;
+ }
+
+ // let others also handle this event by default
+ return false;
+ }
+
+ bool on_bandwidth_throttle(LLUpdaterService * updater, LLSD const & evt)
+ {
+ updater->setBandwidthLimit(evt.asInteger() * (1024/8));
+ return false; // Let others receive this event.
+ };
+};
+
+void LLAppViewer::initUpdater()
+{
+ // Initialize the updater service.
+ // Get Channel
+ // Get Version
+
+ /*****************************************************************
+ * Previously, the url was derived from the settings
+ * UpdaterServiceURL
+ * UpdaterServicePath
+ * it is now obtained from the grid manager. The settings above
+ * are no longer used.
+ *****************************************************************/
+ std::string channel = LLVersionInfo::getChannel();
+ std::string version = LLVersionInfo::getVersion();
+
+ U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
+ bool willing_to_test;
+ LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL;
+
+ if (LLVersionInfo::TEST_VIEWER == LLVersionInfo::getViewerMaturity())
+ {
+ LL_INFOS("UpdaterService") << "Test build: overriding willing_to_test by sending testno" << LL_ENDL;
+ willing_to_test = false;
+ }
+ else
+ {
+ willing_to_test = gSavedSettings.getBOOL("UpdaterWillingToTest");
+ }
+ unsigned char unique_id[MD5HEX_STR_SIZE];
+ if ( ! llHashedUniqueID(unique_id) )
+ {
+ if ( willing_to_test )
+ {
+ LL_WARNS("UpdaterService") << "Unable to provide a unique id; overriding willing_to_test by sending testno" << LL_ENDL;
+ }
+ willing_to_test = false;
+ }
+
+ mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this));
+ mUpdater->initialize(channel,
+ version,
+ gPlatform,
+ getOSInfo().getOSVersionString(),
+ unique_id,
+ willing_to_test
+ );
+ mUpdater->setCheckPeriod(check_period);
+ mUpdater->setBandwidthLimit((int)gSavedSettings.getF32("UpdaterMaximumBandwidth") * (1024/8));
+ gSavedSettings.getControl("UpdaterMaximumBandwidth")->getSignal()->
+ connect(boost::bind(&on_bandwidth_throttle, mUpdater.get(), _2));
+ if(gSavedSettings.getU32("UpdaterServiceSetting"))
+ {
+ bool install_if_ready = true;
+ mUpdater->startChecking(install_if_ready);
+ }
+
+ LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName());
+ updater_pump.listen("notify_update", &notify_update);
+}
+
//
// This function decides whether the client machine meets the minimum requirements to
// run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011.
@@ -3051,7 +3295,6 @@ LLSD LLAppViewer::getViewerInfo() const
info["VIEWER_VERSION"] = version;
info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion();
info["CHANNEL"] = LLVersionInfo::getChannel();
- info["ADDRESS_SIZE"] = ADDRESS_SIZE;
std::string build_config = LLVersionInfo::getBuildConfig();
if (build_config != "Release")
{
@@ -3143,33 +3386,20 @@ LLSD LLAppViewer::getViewerInfo() const
}
#if !LL_LINUX
- std::ostringstream cef_ver_codec;
- cef_ver_codec << "Dullahan: ";
- cef_ver_codec << DULLAHAN_VERSION_MAJOR;
- cef_ver_codec << ".";
- cef_ver_codec << DULLAHAN_VERSION_MINOR;
- cef_ver_codec << ".";
- cef_ver_codec << DULLAHAN_VERSION_BUILD;
-
- cef_ver_codec << " / CEF: ";
- cef_ver_codec << CEF_VERSION;
-
- cef_ver_codec << " / Chrome: ";
- cef_ver_codec << CHROME_VERSION_MAJOR;
-
- info["LIBCEF_VERSION"] = cef_ver_codec.str();
+ info["LLCEFLIB_VERSION"] = LLCEFLIB_VERSION;
#else
- info["LIBCEF_VERSION"] = "Undefined";
+ info["LLCEFLIB_VERSION"] = "Undefined";
+
#endif
-#if !LL_LINUX
- std::ostringstream vlc_ver_codec;
- vlc_ver_codec << LIBVLC_VERSION_MAJOR;
- vlc_ver_codec << ".";
- vlc_ver_codec << LIBVLC_VERSION_MINOR;
- vlc_ver_codec << ".";
- vlc_ver_codec << LIBVLC_VERSION_REVISION;
- info["LIBVLC_VERSION"] = vlc_ver_codec.str();
+#if LL_WINDOWS
+ std::ostringstream ver_codec;
+ ver_codec << LIBVLC_VERSION_MAJOR;
+ ver_codec << ".";
+ ver_codec << LIBVLC_VERSION_MINOR;
+ ver_codec << ".";
+ ver_codec << LIBVLC_VERSION_REVISION;
+ info["LIBVLC_VERSION"] = ver_codec.str();
#else
info["LIBVLC_VERSION"] = "Undefined";
#endif
@@ -3343,6 +3573,7 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
+ gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::getAddressSize();
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
@@ -3496,10 +3727,11 @@ void LLAppViewer::handleViewerCrash()
{
gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL();
}
-
+
+
gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
- gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = LLSD::Integer(LLMemory::getCurrentRSS() / 1024);
-
+ gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
+
if(gLogoutInProgress)
{
gDebugInfo["Dynamic"]["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
@@ -4079,7 +4311,7 @@ void dumpVFSCaches()
U32 LLAppViewer::getTextureCacheVersion()
{
//viewer texture cache version, change if the texture cache format changes.
- const U32 TEXTURE_CACHE_VERSION = 8;
+ const U32 TEXTURE_CACHE_VERSION = 7;
return TEXTURE_CACHE_VERSION ;
}
@@ -4089,7 +4321,7 @@ U32 LLAppViewer::getObjectCacheVersion()
{
// Viewer object cache version, change if object update
// format changes. JC
- const U32 INDRA_OBJECT_CACHE_VERSION = 15;
+ const U32 INDRA_OBJECT_CACHE_VERSION = 14;
return INDRA_OBJECT_CACHE_VERSION;
}
@@ -5498,6 +5730,142 @@ void LLAppViewer::handleLoginComplete()
mSavePerAccountSettings=true;
}
+void LLAppViewer::launchUpdater()
+{
+ LLSD query_map = LLSD::emptyMap();
+ query_map["os"] = gPlatform;
+
+ // *TODO change userserver to be grid on both viewer and sim, since
+ // userserver no longer exists.
+ query_map["userserver"] = LLGridManager::getInstance()->getGridId();
+ query_map["channel"] = LLVersionInfo::getChannel();
+ // *TODO constantize this guy
+ // *NOTE: This URL is also used in win_setup/lldownloader.cpp
+ LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
+
+ if(LLAppViewer::sUpdaterInfo)
+ {
+ delete LLAppViewer::sUpdaterInfo;
+ }
+ LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ;
+
+ // if a sim name was passed in via command line parameter (typically through a SLURL)
+ if ( LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION )
+ {
+ // record the location to start at next time
+ gSavedSettings.setString( "NextLoginLocation", LLStartUp::getStartSLURL().getSLURLString());
+ };
+
+#if LL_WINDOWS
+ LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename();
+ if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty())
+ {
+ delete LLAppViewer::sUpdaterInfo ;
+ LLAppViewer::sUpdaterInfo = NULL ;
+
+ // We're hosed, bail
+ LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL;
+ return;
+ }
+
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe";
+
+ std::string updater_source = gDirUtilp->getAppRODataDir();
+ updater_source += gDirUtilp->getDirDelimiter();
+ updater_source += "updater.exe";
+
+ LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source
+ << " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath
+ << LL_ENDL;
+
+
+ if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE))
+ {
+ delete LLAppViewer::sUpdaterInfo ;
+ LLAppViewer::sUpdaterInfo = NULL ;
+
+ LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL;
+
+ return;
+ }
+
+ LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\"";
+
+ LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
+
+ //Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird.
+ LLAppViewer::instance()->removeMarkerFiles(); // In case updater fails
+
+ // *NOTE:Mani The updater is spawned as the last thing before the WinMain exit.
+ // see LLAppViewerWin32.cpp
+
+#elif LL_DARWIN
+ LLAppViewer::sUpdaterInfo->mUpdateExePath = "'";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \"";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \"";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -bundleid \"";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += LL_VERSION_BUNDLE_ID;
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &";
+
+ LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL;
+
+ // Run the auto-updater.
+ system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */
+
+#elif (LL_LINUX || LL_SOLARIS) && LL_GTK
+ // 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 =
+ gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_strings_file);
+ std::string xml_search_paths;
+ const char* delim = "";
+ // build comma-delimited list of xml paths to pass to updater
+ 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
+ LL_INFOS() << "Got a XUI path: " << this_skin_path << LL_ENDL;
+ 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 =
+ gDirUtilp->getExecutableDir() + "/" + "linux-updater.bin" +
+ " --url \"" + update_url.asString() + "\"" +
+ " --name \"" + LLAppViewer::instance()->getSecondLifeTitle() + "\"" +
+ " --dest \"" + gDirUtilp->getAppRODataDir() + "\"" +
+ " --stringsdir \"" + xml_search_paths + "\"" +
+ " --stringsfile \"" + xml_strings_file + "\"";
+
+ LL_INFOS("AppInit") << "Calling updater: "
+ << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL;
+
+ // *TODO: we could use the gdk equivalent to ensure the updater
+ // gets started on the same screen.
+ GError *error = NULL;
+ if (!g_spawn_command_line_async(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), &error))
+ {
+ LL_ERRS() << "Failed to launch updater: "
+ << error->message
+ << LL_ENDL;
+ }
+ if (error) {
+ g_error_free(error);
+ }
+#else
+ OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK);
+#endif
+
+ // *REMOVE:Mani - Saving for reference...
+ // LLAppViewer::instance()->forceQuit();
+}
+
//virtual
void LLAppViewer::setMasterSystemAudioMute(bool mute)
{
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index ec599c0cda..99f6c8e87f 100644
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -72,6 +72,9 @@ public:
/// reset the channel name used by the viewer.
static void resetChannel(const std::string& channel);
+ /// return the bit width of an address
+ static const U32 getAddressSize() { return ADDRESS_SIZE; }
+
typedef enum
{
TEST_VIEWER,