summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/CMakeLists.txt2
-rw-r--r--indra/cmake/LLBase.cmake4
-rw-r--r--indra/newview/CMakeLists.txt57
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/installers/windows/installer_template.nsi10
-rw-r--r--indra/newview/llappviewer.cpp378
-rw-r--r--indra/newview/llappviewer.h20
-rw-r--r--indra/newview/llappviewerwin32.cpp11
-rw-r--r--indra/newview/llfloaterabout.cpp83
-rw-r--r--indra/newview/lllogininstance.cpp570
-rw-r--r--indra/newview/lllogininstance.h13
-rw-r--r--indra/newview/llstartup.cpp1
-rw-r--r--indra/newview/llviewercontrol.cpp15
-rw-r--r--indra/newview/llviewermenu.cpp17
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp142
-rwxr-xr-xindra/newview/viewer_manifest.py52
-rw-r--r--indra/newview/vmp_icons/SL_Logo.gifbin0 -> 1322 bytes
-rw-r--r--indra/newview/vmp_icons/SL_Logo.pngbin0 -> 1484 bytes
-rw-r--r--indra/newview/vmp_icons/head-sl-logo.gifbin0 -> 960 bytes
-rw-r--r--indra/newview/vmp_icons/head-sl-logo.pngbin0 -> 2316 bytes
-rw-r--r--indra/viewer_components/CMakeLists.txt1
-rw-r--r--indra/viewer_components/Resources/README9
-rw-r--r--indra/viewer_components/Resources/summary.json1
-rw-r--r--indra/viewer_components/updater/CMakeLists.txt106
-rw-r--r--indra/viewer_components/updater/llupdatechecker.cpp187
-rw-r--r--indra/viewer_components/updater/llupdatechecker.h119
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.cpp604
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.h96
-rw-r--r--indra/viewer_components/updater/llupdateinstaller.cpp100
-rw-r--r--indra/viewer_components/updater/llupdateinstaller.h58
-rw-r--r--indra/viewer_components/updater/llupdaterservice.cpp763
-rw-r--r--indra/viewer_components/updater/llupdaterservice.h113
-rw-r--r--indra/viewer_components/updater/scripts/darwin/janitor.py133
-rw-r--r--indra/viewer_components/updater/scripts/darwin/messageframe.py66
-rwxr-xr-xindra/viewer_components/updater/scripts/darwin/update_install.py412
-rwxr-xr-xindra/viewer_components/updater/scripts/linux/update_install220
-rw-r--r--indra/viewer_components/updater/scripts/windows/update_install.bat3
-rw-r--r--indra/viewer_components/updater/tests/llupdaterservice_test.cpp220
38 files changed, 136 insertions, 4452 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 1afcb118bc..84c2a14c6e 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -63,7 +63,7 @@ if (LINUX)
include(LLAppearanceUtility)
add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
endif (INSTALL_PROPRIETARY)
- add_dependencies(viewer linux-crash-logger-strip-target linux-updater)
+ add_dependencies(viewer linux-crash-logger-strip-target)
elseif (DARWIN)
add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
add_dependencies(viewer mac-crash-logger)
diff --git a/indra/cmake/LLBase.cmake b/indra/cmake/LLBase.cmake
new file mode 100644
index 0000000000..76e3c688a3
--- /dev/null
+++ b/indra/cmake/LLBase.cmake
@@ -0,0 +1,4 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+use_prebuilt_binary(llbase)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c4ded8c5ae..394a9c8578 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -16,6 +16,7 @@ include(GLOD)
include(Hunspell)
include(JsonCpp)
include(LLAppearance)
+include(LLBase)
include(LLAudio)
include(LLCharacter)
include(LLCommon)
@@ -81,7 +82,6 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLLOGIN_INCLUDE_DIRS}
- ${UPDATER_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILD_DIR}/include/hunspell
${OPENAL_LIB_INCLUDE_DIRS}
@@ -1756,6 +1756,58 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
)
endif (FMODEX)
+
+ get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY)
+
+ # http://pythonhosted.org/PyInstaller/#options
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SL_Launcher.exe
+ COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe
+ ARGS
+ --onefile
+ --log-level WARN
+ --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+ ${CMAKE_SOURCE_DIR}/viewer_components/manager/SL_Launcher
+ COMMENT "Performing pyinstaller compile of SL_Launcher"
+)
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/apply_update.exe
+ COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe
+ ARGS
+ --onefile
+ --log-level WARN
+ --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+ ${CMAKE_SOURCE_DIR}/viewer_components/manager/apply_update.py
+ COMMENT "Performing pyinstaller compile of updater"
+)
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/download_update.exe
+ COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe
+ ARGS
+ --onefile
+ --log-level WARN
+ --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+ ${CMAKE_SOURCE_DIR}/viewer_components/manager/download_update.py
+ COMMENT "Performing pyinstaller compile of update downloader"
+)
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/update_manager.exe
+ COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe
+ ARGS
+ --onefile
+ --log-level WARN
+ --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+ ${CMAKE_SOURCE_DIR}/viewer_components/manager/update_manager.py
+ COMMENT "Performing pyinstaller compile of update manager"
+)
+
+add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/SL_Launcher.exe)
+add_custom_target(compile_w_viewer_updater ALL DEPENDS ${CMAKE_CFG_INTDIR}/apply_update.exe)
+add_custom_target(compile_w_viewer_downloader ALL DEPENDS ${CMAKE_CFG_INTDIR}/download_update.exe)
+add_custom_target(compile_w_viewer_update_manager ALL DEPENDS ${CMAKE_CFG_INTDIR}/update_manager.exe)
add_custom_command(
OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat
@@ -1901,7 +1953,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${PNG_PRELOAD_ARCHIVES}
${ZLIB_PRELOAD_ARCHIVES}
${URIPARSER_PRELOAD_ARCHIVES}
- ${UPDATER_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
${LLAUDIO_LIBRARIES}
${LLCHARACTER_LIBRARIES}
@@ -2022,6 +2073,8 @@ endif (LINUX)
if (DARWIN)
# These all get set with PROPERTIES
set(product "Second Life")
+ # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
+ set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 9b8136a827..8aabd6818b 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
- <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <string>${MACOSX_WRAPPER_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index eb07b54d8d..fe1b35767e 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -278,7 +278,7 @@ StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)"
CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT"
SetOutPath "$INSTDIR"
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
- "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
+ "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico"
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \
@@ -296,15 +296,15 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \
# Other shortcuts
SetOutPath "$INSTDIR"
CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
- "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
+ "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico"
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
- "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
+ "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico"
CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
'"$INSTDIR\uninst.exe"' ''
-# Create *.bat file to specify lang params on first run from installer - see MAINT-5259
+# Create *.bat file to specify lang params on first run from installer - see MAINT-5259S
FileOpen $9 "$INSTDIR\autorun.bat" w
-FileWrite $9 'start "$INSTDIR\$INSTEXE" "$INSTDIR\$INSTEXE" $SHORTCUT_LANG_PARAM$\r$\n'
+FileWrite $9 'start "$INSTDIR\$INSTEXE" /d "$INSTDIR" "$INSTDIR\$INSTEXE" $SHORTCUT_LANG_PARAM$\r$\n'
FileClose $9
# Write registry
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 616e084119..242266eac5 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -93,7 +93,6 @@
#include "llvocache.h"
#include "llvopartgroup.h"
#include "llweb.h"
-#include "llupdaterservice.h"
#include "llfloatertexturefetchdebugger.h"
#include "llspellcheck.h"
#include "llscenemonitor.h"
@@ -268,7 +267,6 @@ 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
@@ -294,9 +292,7 @@ S32 gLastExecDuration = -1; // (<0 indicates unknown)
# define LL_PLATFORM_KEY "mac"
#elif LL_LINUX
# define LL_PLATFORM_KEY "lnx"
-#elif LL_SOLARIS
-# define LL_PLATFORM_KEY "sol"
-#else
+else
# error "Unknown Platform"
#endif
const char* gPlatform = LL_PLATFORM_KEY;
@@ -473,8 +469,6 @@ struct SettingsFiles : public LLInitParam::Block<SettingsFiles>
static std::string gWindowTitle;
-LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
-
//----------------------------------------------------------------------------
// Metrics logging control constants
//----------------------------------------------------------------------------
@@ -701,7 +695,6 @@ 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)
{
@@ -731,7 +724,6 @@ 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());
}
@@ -885,14 +877,6 @@ 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;
- }
-
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -2912,224 +2896,6 @@ 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.
@@ -5734,142 +5500,20 @@ void LLAppViewer::handleLoginComplete()
mSavePerAccountSettings=true;
}
-void LLAppViewer::launchUpdater()
+/**
+* Check if user is running a new version of the viewer.
+* Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting.
+*/
+void LLAppViewer::showReleaseNotesIfRequired()
{
- 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))
+ if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion
+ && gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
+ && !gSavedSettings.getBOOL("FirstLoginThisInstall"))
{
- delete LLAppViewer::sUpdaterInfo ;
- LLAppViewer::sUpdaterInfo = NULL ;
-
- LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL;
-
- return;
+ LLSD info(getViewerInfo());
+ LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
}
-
- 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/llappviewer.h b/indra/newview/llappviewer.h
index 16a00c8cee..702f7efa21 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -55,7 +55,6 @@ class LLTextureCache;
class LLImageDecodeThread;
class LLTextureFetch;
class LLWatchdogTimeout;
-class LLUpdaterService;
class LLViewerJoystick;
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
@@ -228,7 +227,6 @@ private:
bool initThreads(); // Initialize viewer threads, return false on failure.
bool initConfiguration(); // Initialize settings from the command line/config file.
void initStrings(); // Initialize LLTrans machinery
- void initUpdater(); // Initialize the updater service.
bool initCache(); // Initialize local client cache.
void checkMemory() ;
@@ -309,28 +307,10 @@ private:
LLAllocator mAlloc;
LLFrameTimer mMemCheckTimer;
-
- boost::scoped_ptr<LLUpdaterService> mUpdater;
// llcorehttp library init/shutdown helper
LLAppCoreHttp mAppCoreHttp;
- bool mIsFirstRun;
- //---------------------------------------------
- //*NOTE: Mani - legacy updater stuff
- // Still useable?
-public:
-
- //some information for updater
- typedef struct
- {
- std::string mUpdateExePath;
- std::ostringstream mParams;
- }LLUpdaterInfo ;
- static LLUpdaterInfo *sUpdaterInfo ;
-
- void launchUpdater();
- //---------------------------------------------
};
// consts from viewer.h
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 5107030476..c81733d107 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -361,17 +361,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
delete viewer_app_ptr;
viewer_app_ptr = NULL;
- //start updater
- if(LLAppViewer::sUpdaterInfo)
- {
- _spawnl(_P_NOWAIT, LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), LLAppViewer::sUpdaterInfo->mParams.str().c_str(), NULL);
-
- delete LLAppViewer::sUpdaterInfo ;
- LLAppViewer::sUpdaterInfo = NULL ;
- }
-
-
-
// (NVAPI) (6) We clean up. This is analogous to doing a free()
if (hSession)
{
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index c2d0d9f06b..de2d595fb1 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -39,7 +39,6 @@
#include "llslurl.h"
#include "llvoiceclient.h"
#include "lluictrlfactory.h"
-#include "llupdaterservice.h"
#include "llviewertexteditor.h"
#include "llviewercontrol.h"
#include "llviewerstats.h"
@@ -91,10 +90,6 @@ public:
void onClickCopyToClipboard();
void onClickUpdateCheck();
- // checks state of updater service and starts a check outside of schedule.
- // subscribes callback for closest state update
- static void setUpdateListener();
-
private:
void setSupportText(const std::string& server_release_notes_url);
@@ -103,9 +98,6 @@ private:
// callback method for manual checks
static bool callbackCheckUpdate(LLSD const & event);
-
- // listener name for update checks
- static const std::string sCheckUpdateListenerName;
static void startFetchServerReleaseNotes();
static void fetchServerReleaseNotesCoro(const std::string& cap_url);
@@ -140,9 +132,6 @@ BOOL LLFloaterAbout::postBuild()
getChild<LLUICtrl>("copy_btn")->setCommitCallback(
boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this));
- getChild<LLUICtrl>("update_btn")->setCommitCallback(
- boost::bind(&LLFloaterAbout::onClickUpdateCheck, this));
-
static const LLUIColor about_color = LLUIColorTable::instance().getColor("TextFgReadOnlyColor");
if (gAgent.getRegion())
@@ -317,11 +306,6 @@ void LLFloaterAbout::onClickCopyToClipboard()
support_widget->deselect();
}
-void LLFloaterAbout::onClickUpdateCheck()
-{
- setUpdateListener();
-}
-
void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)
{
#if LL_WINDOWS
@@ -343,68 +327,6 @@ void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)
}
///----------------------------------------------------------------------------
-/// Floater About Update-check related functions
-///----------------------------------------------------------------------------
-
-const std::string LLFloaterAbout::sCheckUpdateListenerName = "LLUpdateNotificationListener";
-
-void LLFloaterAbout::showCheckUpdateNotification(S32 state)
-{
- switch (state)
- {
- case LLUpdaterService::UP_TO_DATE:
- LLNotificationsUtil::add("UpdateViewerUpToDate");
- break;
- case LLUpdaterService::DOWNLOADING:
- case LLUpdaterService::INSTALLING:
- LLNotificationsUtil::add("UpdateDownloadInProgress");
- break;
- case LLUpdaterService::TERMINAL:
- // download complete, user triggered check after download pop-up appeared
- LLNotificationsUtil::add("UpdateDownloadComplete");
- break;
- default:
- LLNotificationsUtil::add("UpdateCheckError");
- break;
- }
-}
-
-bool LLFloaterAbout::callbackCheckUpdate(LLSD const & event)
-{
- if (!event.has("payload"))
- {
- return false;
- }
-
- LLSD payload = event["payload"];
- if (payload.has("type") && payload["type"].asInteger() == LLUpdaterService::STATE_CHANGE)
- {
- LLEventPumps::instance().obtain("mainlooprepeater").stopListening(sCheckUpdateListenerName);
- showCheckUpdateNotification(payload["state"].asInteger());
- }
- return false;
-}
-
-void LLFloaterAbout::setUpdateListener()
-{
- LLUpdaterService update_service;
- S32 service_state = update_service.getState();
- // Note: Do not set state listener before forceCheck() since it set's new state
- if (update_service.forceCheck() || service_state == LLUpdaterService::CHECKING_FOR_UPDATE)
- {
- LLEventPump& mainloop(LLEventPumps::instance().obtain("mainlooprepeater"));
- if (mainloop.getListener(sCheckUpdateListenerName) == LLBoundListener()) // dummy listener
- {
- mainloop.listen(sCheckUpdateListenerName, boost::bind(&callbackCheckUpdate, _1));
- }
- }
- else
- {
- showCheckUpdateNotification(service_state);
- }
-}
-
-///----------------------------------------------------------------------------
/// LLFloaterAboutUtil
///----------------------------------------------------------------------------
void LLFloaterAboutUtil::registerFloater()
@@ -414,8 +336,3 @@ void LLFloaterAboutUtil::registerFloater()
}
-void LLFloaterAboutUtil::checkUpdatesAndNotify()
-{
- LLFloaterAbout::setUpdateListener();
-}
-
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index b4d0bb6823..374efa2986 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -50,13 +50,12 @@
#include "llwindow.h"
#include "llviewerwindow.h"
#include "llprogressview.h"
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
#include "lltrans.h"
#endif
#include "llsecapi.h"
#include "llstartup.h"
#include "llmachineid.h"
-#include "llupdaterservice.h"
#include "llevents.h"
#include "llappviewer.h"
@@ -68,406 +67,11 @@ public:
virtual ~Disposable() {}
};
-namespace {
- class MandatoryUpdateMachine:
- public LLLoginInstance::Disposable
- {
- public:
- MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService);
-
- void start(void);
-
- LLNotificationsInterface& getNotificationsInterface() const
- {
- return mLoginInstance.getNotificationsInterface();
- }
-
- private:
- class State;
- class CheckingForUpdate;
- class Error;
- class ReadyToInstall;
- class StartingUpdaterService;
- class WaitingForDownload;
-
- boost::scoped_ptr<State> mState;
- LLLoginInstance & mLoginInstance;
- LLUpdaterService & mUpdaterService;
-
- void setCurrentState(State * newState);
- };
-
-
- class MandatoryUpdateMachine::State {
- public:
- virtual ~State() {}
- virtual void enter(void) {}
- virtual void exit(void) {}
- };
-
-
- class MandatoryUpdateMachine::CheckingForUpdate:
- public MandatoryUpdateMachine::State
- {
- public:
- CheckingForUpdate(MandatoryUpdateMachine & machine);
-
- virtual void enter(void);
- virtual void exit(void);
-
- private:
- LLTempBoundListener mConnection;
- MandatoryUpdateMachine & mMachine;
- LLProgressView * mProgressView;
-
- bool onEvent(LLSD const & event);
- };
-
-
- class MandatoryUpdateMachine::Error:
- public MandatoryUpdateMachine::State
- {
- public:
- Error(MandatoryUpdateMachine & machine);
-
- virtual void enter(void);
- virtual void exit(void);
- void onButtonClicked(const LLSD &, const LLSD &);
-
- private:
- MandatoryUpdateMachine & mMachine;
- };
-
-
- class MandatoryUpdateMachine::ReadyToInstall:
- public MandatoryUpdateMachine::State
- {
- public:
- ReadyToInstall(MandatoryUpdateMachine & machine);
-
- virtual void enter(void);
- virtual void exit(void);
-
- private:
- //MandatoryUpdateMachine & mMachine;
- };
-
-
- class MandatoryUpdateMachine::StartingUpdaterService:
- public MandatoryUpdateMachine::State
- {
- public:
- StartingUpdaterService(MandatoryUpdateMachine & machine);
-
- virtual void enter(void);
- virtual void exit(void);
- void onButtonClicked(const LLSD & uiform, const LLSD & result);
- private:
- MandatoryUpdateMachine & mMachine;
- };
-
-
- class MandatoryUpdateMachine::WaitingForDownload:
- public MandatoryUpdateMachine::State
- {
- public:
- WaitingForDownload(MandatoryUpdateMachine & machine);
-
- virtual void enter(void);
- virtual void exit(void);
-
- private:
- LLTempBoundListener mConnection;
- MandatoryUpdateMachine & mMachine;
- LLProgressView * mProgressView;
-
- bool onEvent(LLSD const & event);
- };
-}
-
static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";
static const char * const TOS_LISTENER_NAME = "lllogininstance_tos";
std::string construct_start_string();
-
-
-// MandatoryUpdateMachine
-//-----------------------------------------------------------------------------
-
-
-MandatoryUpdateMachine::MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService):
- mLoginInstance(loginInstance),
- mUpdaterService(updaterService)
-{
- ; // No op.
-}
-
-
-void MandatoryUpdateMachine::start(void)
-{
- LL_INFOS() << "starting mandatory update machine" << LL_ENDL;
-
- if(mUpdaterService.isChecking()) {
- switch(mUpdaterService.getState()) {
- case LLUpdaterService::UP_TO_DATE:
- mUpdaterService.stopChecking();
- mUpdaterService.startChecking();
- // Fall through.
- case LLUpdaterService::INITIAL:
- case LLUpdaterService::CHECKING_FOR_UPDATE:
- setCurrentState(new CheckingForUpdate(*this));
- break;
- case LLUpdaterService::TEMPORARY_ERROR:
- setCurrentState(new Error(*this));
- break;
- case LLUpdaterService::DOWNLOADING:
- setCurrentState(new WaitingForDownload(*this));
- break;
- case LLUpdaterService::TERMINAL:
- if(LLUpdaterService::updateReadyToInstall()) {
- setCurrentState(new ReadyToInstall(*this));
- } else {
- setCurrentState(new Error(*this));
- }
- break;
- case LLUpdaterService::FAILURE:
- setCurrentState(new Error(*this));
- break;
- default:
- llassert(!"unpossible case");
- break;
- }
- } else {
- setCurrentState(new StartingUpdaterService(*this));
- }
-}
-
-
-void MandatoryUpdateMachine::setCurrentState(State * newStatePointer)
-{
- {
- boost::scoped_ptr<State> newState(newStatePointer);
- if(mState != 0) mState->exit();
- mState.swap(newState);
-
- // Old state will be deleted on exit from this block before the new state
- // is entered.
- }
- if(mState != 0) mState->enter();
-}
-
-
-
-// MandatoryUpdateMachine::CheckingForUpdate
-//-----------------------------------------------------------------------------
-
-
-MandatoryUpdateMachine::CheckingForUpdate::CheckingForUpdate(MandatoryUpdateMachine & machine):
- mMachine(machine)
-{
- ; // No op.
-}
-
-
-void MandatoryUpdateMachine::CheckingForUpdate::enter(void)
-{
- LL_INFOS() << "entering checking for update" << LL_ENDL;
-
- mProgressView = gViewerWindow->getProgressView();
- mProgressView->setMessage("Looking for update...");
- mProgressView->setText("There is a required update for your Second Life installation.");
- mProgressView->setPercent(0);
- mProgressView->setVisible(true);
- mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).
- listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::CheckingForUpdate::onEvent, this, _1));
-}
-
-
-void MandatoryUpdateMachine::CheckingForUpdate::exit(void)
-{
-}
-
-
-bool MandatoryUpdateMachine::CheckingForUpdate::onEvent(LLSD const & event)
-{
- if(event["type"].asInteger() == LLUpdaterService::STATE_CHANGE) {
- switch(event["state"].asInteger()) {
- case LLUpdaterService::DOWNLOADING:
- mMachine.setCurrentState(new WaitingForDownload(mMachine));
- break;
- case LLUpdaterService::TEMPORARY_ERROR:
- case LLUpdaterService::UP_TO_DATE:
- case LLUpdaterService::TERMINAL:
- case LLUpdaterService::FAILURE:
- mProgressView->setVisible(false);
- mMachine.setCurrentState(new Error(mMachine));
- break;
- case LLUpdaterService::INSTALLING:
- llassert(!"can't possibly be installing");
- break;
- default:
- break;
- }
- } else {
- ; // Ignore.
- }
-
- return false;
-}
-
-
-
-// MandatoryUpdateMachine::Error
-//-----------------------------------------------------------------------------
-
-
-MandatoryUpdateMachine::Error::Error(MandatoryUpdateMachine & machine):
- mMachine(machine)
-{
- ; // No op.
-}
-
-
-void MandatoryUpdateMachine::Error::enter(void)
-{
- LL_INFOS() << "entering error" << LL_ENDL;
- mMachine.getNotificationsInterface().add("FailedRequiredUpdateInstall", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::Error::onButtonClicked, this, _1, _2));
-}
-
-
-void MandatoryUpdateMachine::Error::exit(void)
-{
- LLAppViewer::instance()->forceQuit();
-}
-
-
-void MandatoryUpdateMachine::Error::onButtonClicked(const LLSD &, const LLSD &)
-{
- mMachine.setCurrentState(0);
-}
-
-
-
-// MandatoryUpdateMachine::ReadyToInstall
-//-----------------------------------------------------------------------------
-
-
-MandatoryUpdateMachine::ReadyToInstall::ReadyToInstall(MandatoryUpdateMachine & machine) //:
- //mMachine(machine)
-{
- ; // No op.
-}
-
-
-void MandatoryUpdateMachine::ReadyToInstall::enter(void)
-{
- LL_INFOS() << "entering ready to install" << LL_ENDL;
- // Open update ready dialog.
-}
-
-
-void MandatoryUpdateMachine::ReadyToInstall::exit(void)
-{
- // Restart viewer.
-}
-
-
-
-// MandatoryUpdateMachine::StartingUpdaterService
-//-----------------------------------------------------------------------------
-
-
-MandatoryUpdateMachine::StartingUpdaterService::StartingUpdaterService(MandatoryUpdateMachine & machine):
- mMachine(machine)
-{
- ; // No op.
-}
-
-
-void MandatoryUpdateMachine::StartingUpdaterService::enter(void)
-{
- LL_INFOS() << "entering start update service" << LL_ENDL;
- mMachine.getNotificationsInterface().add("UpdaterServiceNotRunning", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked, this, _1, _2));
-}
-
-
-void MandatoryUpdateMachine::StartingUpdaterService::exit(void)
-{
- ; // No op.
-}
-
-
-void MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked(const LLSD & uiform, const LLSD & result)
-{
- if(result["OK_okcancelbuttons"].asBoolean()) {
- mMachine.mUpdaterService.startChecking(false);
- mMachine.setCurrentState(new CheckingForUpdate(mMachine));
- } else {
- LLAppViewer::instance()->forceQuit();
- }
-}
-
-
-
-// MandatoryUpdateMachine::WaitingForDownload
-//-----------------------------------------------------------------------------
-
-
-MandatoryUpdateMachine::WaitingForDownload::WaitingForDownload(MandatoryUpdateMachine & machine):
- mMachine(machine),
- mProgressView(0)
-{
- ; // No op.
-}
-
-
-void MandatoryUpdateMachine::WaitingForDownload::enter(void)
-{
- LL_INFOS() << "entering waiting for download" << LL_ENDL;
- mProgressView = gViewerWindow->getProgressView();
- mProgressView->setMessage("Downloading update...");
- std::ostringstream stream;
- stream << "There is a required update for your Second Life installation." << std::endl <<
- "Version " << mMachine.mUpdaterService.updatedVersion();
- mProgressView->setText(stream.str());
- mProgressView->setPercent(0);
- mProgressView->setVisible(true);
- mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).
- listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::WaitingForDownload::onEvent, this, _1));
-}
-
-
-void MandatoryUpdateMachine::WaitingForDownload::exit(void)
-{
- mProgressView->setVisible(false);
-}
-
-
-bool MandatoryUpdateMachine::WaitingForDownload::onEvent(LLSD const & event)
-{
- switch(event["type"].asInteger()) {
- case LLUpdaterService::DOWNLOAD_COMPLETE:
- mMachine.setCurrentState(new ReadyToInstall(mMachine));
- break;
- case LLUpdaterService::DOWNLOAD_ERROR:
- mMachine.setCurrentState(new Error(mMachine));
- break;
- case LLUpdaterService::PROGRESS: {
- double downloadSize = event["download_size"].asReal();
- double bytesDownloaded = event["bytes_downloaded"].asReal();
- mProgressView->setPercent(100. * bytesDownloaded / downloadSize);
- break;
- }
- default:
- break;
- }
-
- return false;
-}
-
-
-
// LLLoginInstance
//-----------------------------------------------------------------------------
@@ -476,11 +80,9 @@ LLLoginInstance::LLLoginInstance() :
mLoginModule(new LLLogin()),
mNotifications(NULL),
mLoginState("offline"),
- mSkipOptionalUpdate(false),
mAttemptComplete(false),
mTransferRate(0.0f),
- mDispatcher("LLLoginInstance", "change"),
- mUpdaterService(0)
+ mDispatcher("LLLoginInstance", "change")
{
mLoginModule->getEventPump().listen("lllogininstance",
boost::bind(&LLLoginInstance::handleLoginEvent, this, _1));
@@ -590,13 +192,14 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
// (re)initialize the request params with creds.
LLSD request_params = user_credential->getLoginParams();
- unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE];
- if ( ! llHashedUniqueID(hashed_unique_id_string) )
- {
+ unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE];
+ if ( ! llHashedUniqueID(hashed_unique_id_string) )
+ {
+
LL_WARNS() << "Not providing a unique id in request params" << LL_ENDL;
+
}
request_params["start"] = construct_start_string();
- request_params["skipoptional"] = mSkipOptionalUpdate;
request_params["agree_to_tos"] = false; // Always false here. Set true in
request_params["read_critical"] = false; // handleTOSResponse
request_params["last_exec_event"] = mLastExecEvent;
@@ -698,19 +301,6 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
boost::bind(&LLLoginInstance::handleTOSResponse,
this, _1, "read_critical"));
}
- else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))
- {
- LL_INFOS() << "LLLoginInstance::handleLoginFailure update" << LL_ENDL;
-
- gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
- updateApp(true, message_response);
- }
- else if(reason_response == "optional")
- {
- LL_INFOS() << "LLLoginInstance::handleLoginFailure optional" << LL_ENDL;
-
- updateApp(false, message_response);
- }
else
{
LL_INFOS() << "LLLoginInstance::handleLoginFailure attemptComplete" << LL_ENDL;
@@ -722,22 +312,7 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)
{
LL_INFOS() << "LLLoginInstance::handleLoginSuccess" << LL_ENDL;
- if(gSavedSettings.getBOOL("ForceMandatoryUpdate"))
- {
- LLSD response = event["data"];
- std::string message_response = response["message"].asString();
-
- // Testing update...
- gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
-
- // Don't confuse startup by leaving login "online".
- mLoginModule->disconnect();
- updateApp(true, message_response);
- }
- else
- {
- attemptComplete();
- }
+ attemptComplete();
}
void LLLoginInstance::handleDisconnect(const LLSD& event)
@@ -787,135 +362,6 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
return true;
}
-
-void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)
-{
- if(mandatory)
- {
- gViewerWindow->setShowProgress(false);
- MandatoryUpdateMachine * machine = new MandatoryUpdateMachine(*this, *mUpdaterService);
- mUpdateStateMachine.reset(machine);
- machine->start();
- return;
- }
-
- // store off config state, as we might quit soon
- gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
- LLUIColorTable::instance().saveUserSettings();
-
- std::ostringstream message;
- std::string msg;
- if (!auth_msg.empty())
- {
- msg = "(" + auth_msg + ") \n";
- }
-
- LLSD args;
- args["MESSAGE"] = msg;
-
- LLSD payload;
- payload["mandatory"] = mandatory;
-
- /*
- * We're constructing one of the following 9 strings here:
- * "DownloadWindowsMandatory"
- * "DownloadWindowsReleaseForDownload"
- * "DownloadWindows"
- * "DownloadMacMandatory"
- * "DownloadMacReleaseForDownload"
- * "DownloadMac"
- * "DownloadLinuxMandatory"
- * "DownloadLinuxReleaseForDownload"
- * "DownloadLinux"
- *
- * I've called them out explicitly in this comment so that they can be grepped for.
- */
- std::string notification_name = "Download";
-
-#if LL_WINDOWS
- notification_name += "Windows";
-#elif LL_DARWIN
- notification_name += "Mac";
-#else
- notification_name += "Linux";
-#endif
-
- if (mandatory)
- {
- notification_name += "Mandatory";
- }
- else
- {
-#if LL_RELEASE_FOR_DOWNLOAD
- notification_name += "ReleaseForDownload";
-#endif
- }
-
- if(mNotifications)
- {
- mNotifications->add(notification_name, args, payload,
- boost::bind(&LLLoginInstance::updateDialogCallback, this, _1, _2));
-
- gViewerWindow->setShowProgress(false);
- }
-}
-
-bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- std::string update_exe_path;
- bool mandatory = notification["payload"]["mandatory"].asBoolean();
-
-#if !LL_RELEASE_FOR_DOWNLOAD
- if (option == 2)
- {
- // This condition attempts to skip the
- // update if using a dev build.
- // The relog probably won't work if the
- // update is mandatory. :)
-
- // *REMOVE:Mani - Saving for reference...
- //LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
- mSkipOptionalUpdate = true;
- reconnect();
- return false;
- }
-#endif
-
- if (option == 1)
- {
- // ...user doesn't want to do it
- if (mandatory)
- {
- // Mandatory update, user chose to not to update...
- // The login attemp is complete, startup should
- // quit when detecting this.
- attemptComplete();
-
- // *REMOVE:Mani - Saving for reference...
- //LLAppViewer::instance()->forceQuit();
- // // Bump them back to the login screen.
- // //reset_login();
- }
- else
- {
- // Optional update, user chose to skip
- mSkipOptionalUpdate = true;
- reconnect();
- }
- return false;
- }
-
- if(mUpdaterLauncher)
- {
- mUpdaterLauncher();
- }
-
- attemptComplete();
-
- return false;
-}
-
std::string construct_start_string()
{
std::string start;
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index 282ddc1cea..67d0f01ba6 100644
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -34,7 +34,6 @@
class LLLogin;
class LLEventStream;
class LLNotificationsInterface;
-class LLUpdaterService;
// This class hosts the login module and is used to
// negotiate user authentication attempts.
@@ -60,10 +59,6 @@ public:
// Only valid when authSuccess == true.
const F64 getLastTransferRateBPS() { return mTransferRate; }
-
- // Whether to tell login to skip optional update request.
- // False by default.
- void setSkipOptionalUpdate(bool state) { mSkipOptionalUpdate = state; }
void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }
void setLastExecEvent(int lee) { mLastExecEvent = lee; }
void setLastExecDuration(S32 duration) { mLastExecDuration = duration; }
@@ -72,10 +67,6 @@ public:
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
- typedef boost::function<void()> UpdaterLauncherCallback;
- void setUpdaterLauncher(const UpdaterLauncherCallback& ulc) { mUpdaterLauncher = ulc; }
-
- void setUpdaterService(LLUpdaterService * updaterService) { mUpdaterService = updaterService; }
private:
void constructAuthParams(LLPointer<LLCredential> user_credentials);
void updateApp(bool mandatory, const std::string& message);
@@ -97,7 +88,6 @@ private:
std::string mLoginState;
LLSD mRequestData;
LLSD mResponseData;
- bool mSkipOptionalUpdate;
bool mAttemptComplete;
F64 mTransferRate;
std::string mSerialNumber;
@@ -105,10 +95,7 @@ private:
S32 mLastExecDuration;
std::string mPlatform;
std::string mPlatformVersion;
- UpdaterLauncherCallback mUpdaterLauncher;
LLEventDispatcher mDispatcher;
- LLUpdaterService * mUpdaterService;
- boost::scoped_ptr<Disposable> mUpdateStateMachine;
};
#endif
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index b762b2ae1c..19ec03f837 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1026,7 +1026,6 @@ bool idle_startup()
login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
login->setLastExecEvent(gLastExecEvent);
login->setLastExecDuration(gLastExecDuration);
- login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance()));
// This call to LLLoginInstance::connect() starts the
// authentication process.
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 7c1921b143..d9d66ef254 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -75,7 +75,6 @@
#include "llspellcheck.h"
#include "llslurl.h"
#include "llstartup.h"
-#include "llupdaterservice.h"
// Third party library includes
#include <boost/algorithm/string.hpp>
@@ -583,19 +582,6 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
return true;
}
-void toggle_updater_service_active(const LLSD& new_value)
-{
- if(new_value.asInteger())
- {
- LLUpdaterService update_service;
- if(!update_service.isChecking()) update_service.startChecking();
- }
- else
- {
- LLUpdaterService().stopChecking();
- }
-}
-
////////////////////////////////////////////////////////////////////////////
void settings_setup_listeners()
@@ -743,7 +729,6 @@ void settings_setup_listeners()
gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2));
gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
- gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(boost::bind(&toggle_updater_service_active, _2));
gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 9bd4e12761..b00caf5592 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -2124,22 +2124,6 @@ class LLAdvancedCheckShowObjectUpdates : public view_listener_t
-///////////////////////
-// CHECK FOR UPDATES //
-///////////////////////
-
-
-
-class LLAdvancedCheckViewerUpdates : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterAboutUtil::checkUpdatesAndNotify();
- return true;
- }
-};
-
-
////////////////////
// COMPRESS IMAGE //
////////////////////
@@ -9032,7 +9016,6 @@ void initialize_menus()
// Advanced (toplevel)
view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates");
view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
- view_listener_t::addMenu(new LLAdvancedCheckViewerUpdates(), "Advanced.CheckViewerUpdates");
view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index b603157ca7..55dcb83567 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -187,35 +187,7 @@ void LLUIColorTable::saveUserSettings(void)const {}
#include "../llversioninfo.h"
const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; }
const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }
-
-//-----------------------------------------------------------------------------
-#include "../llappviewer.h"
-void LLAppViewer::forceQuit(void) {}
-LLAppViewer * LLAppViewer::sInstance = 0;
-
-//-----------------------------------------------------------------------------
-#include "llupdaterservice.h"
-
-std::string const & LLUpdaterService::pumpName(void)
-{
- static std::string wakka = "wakka wakka wakka";
- return wakka;
-}
-bool LLUpdaterService::updateReadyToInstall(void) { return false; }
-void LLUpdaterService::initialize(const std::string& channel,
- const std::string& version,
- const std::string& platform,
- const std::string& platform_version,
- const unsigned char uniqueid[MD5HEX_STR_SIZE],
- const bool& willing_to_test
- ) {}
-
-void LLUpdaterService::setCheckPeriod(unsigned int seconds) {}
-void LLUpdaterService::startChecking(bool install_if_ready) {}
-void LLUpdaterService::stopChecking() {}
-bool LLUpdaterService::isChecking() { return false; }
-LLUpdaterService::eUpdaterState LLUpdaterService::getState() { return INITIAL; }
-std::string LLUpdaterService::updatedVersion() { return ""; }
+const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null
bool llHashedUniqueID(unsigned char* id)
{
@@ -224,6 +196,11 @@ bool llHashedUniqueID(unsigned char* id)
}
//-----------------------------------------------------------------------------
+#include "../llappviewer.h"
+void LLAppViewer::forceQuit(void) {}
+LLAppViewer * LLAppViewer::sInstance = 0;
+
+//-----------------------------------------------------------------------------
#include "llnotifications.h"
#include "llfloaterreg.h"
static std::string gTOSType;
@@ -339,7 +316,6 @@ namespace tut
gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", LLControlVariable::PERSIST_NO);
- gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO);
@@ -477,110 +453,4 @@ namespace tut
logininstance->connect(test_uri, agentCredential);
ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false);
}
-
- template<> template<>
- void lllogininstance_object::test<3>()
- {
- set_test_name("Test Mandatory Update User Accepts");
-
- // Part 1 - Mandatory Update, with User accepts response.
- // Test connect with update needed.
- logininstance->connect(agentCredential);
-
- ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
-
- // Update needed failure response.
- LLSD response;
- response["state"] = "offline";
- response["change"] = "fail.login";
- response["progress"] = 0.0;
- response["transfer_rate"] = 7;
- response["data"]["reason"] = "update";
- gTestPump.post(response);
-
- ensure_equals("Notification added", notifications.addedCount(), 1);
-
- notifications.sendYesResponse();
-
- ensure("Disconnected", !(logininstance->authSuccess()));
- }
-
- template<> template<>
- void lllogininstance_object::test<4>()
- {
- set_test_name("Test Mandatory Update User Decline");
-
- // Test connect with update needed.
- logininstance->connect(agentCredential);
-
- ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
-
- // Update needed failure response.
- LLSD response;
- response["state"] = "offline";
- response["change"] = "fail.login";
- response["progress"] = 0.0;
- response["transfer_rate"] = 7;
- response["data"]["reason"] = "update";
- gTestPump.post(response);
-
- ensure_equals("Notification added", notifications.addedCount(), 1);
- notifications.sendNoResponse();
-
- ensure("Disconnected", !(logininstance->authSuccess()));
- }
-
- template<> template<>
- void lllogininstance_object::test<6>()
- {
- set_test_name("Test Optional Update User Accept");
-
- // Part 3 - Mandatory Update, with bogus response.
- // Test connect with update needed.
- logininstance->connect(agentCredential);
-
- ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
-
- // Update needed failure response.
- LLSD response;
- response["state"] = "offline";
- response["change"] = "fail.login";
- response["progress"] = 0.0;
- response["transfer_rate"] = 7;
- response["data"]["reason"] = "optional";
- gTestPump.post(response);
-
- ensure_equals("Notification added", notifications.addedCount(), 1);
- notifications.sendYesResponse();
-
- ensure("Disconnected", !(logininstance->authSuccess()));
- }
-
- template<> template<>
- void lllogininstance_object::test<7>()
- {
- set_test_name("Test Optional Update User Denies");
-
- // Part 3 - Mandatory Update, with bogus response.
- // Test connect with update needed.
- logininstance->connect(agentCredential);
-
- ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
-
- // Update needed failure response.
- LLSD response;
- response["state"] = "offline";
- response["change"] = "fail.login";
- response["progress"] = 0.0;
- response["transfer_rate"] = 7;
- response["data"]["reason"] = "optional";
- gTestPump.post(response);
-
- ensure_equals("Notification added", notifications.addedCount(), 1);
- notifications.sendNoResponse();
-
- // User skips, should be reconnecting.
- ensure_equals("reconnect uri", gLoginURI, VIEWERLOGIN_URI);
- ensure_equals("skipping optional update", gLoginCreds["params"]["skipoptional"].asBoolean(), true);
- }
}
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 743df609aa..0506fc553e 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -27,6 +27,7 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
import sys
+import os
import os.path
import shutil
import errno
@@ -345,13 +346,15 @@ class WindowsManifest(ViewerManifest):
if self.is_packaging_viewer():
# Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.
self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
+ # include the compiled launcher script so that it gets included in the file_list
+ self.path(src='%s/SL_Launcher.exe' % self.args['configuration'], dst="SL_Launcher.exe")
# Plugin host application
self.path2basename(os.path.join(os.pardir,
'llplugin', 'slplugin', self.args['configuration']),
"slplugin.exe")
- self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat")
+ #note, launcher and friends do not need viewer_manifest in Windows as the scripts are compiled into executables
# Get shared libs from the shared libs staging directory
if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
dst=""):
@@ -612,7 +615,7 @@ class WindowsManifest(ViewerManifest):
substitution_strings['installer_file'] = installer_file
version_vars = """
- !define INSTEXE "%(final_exe)s"
+ !define INSTEXE "SL_Launcher.exe"
!define VERSION "%(version_short)s"
!define VERSION_LONG "%(version)s"
!define VERSION_DASHES "%(version_dashes)s"
@@ -713,6 +716,7 @@ class DarwinManifest(ViewerManifest):
pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
relpkgdir = os.path.join(pkgdir, "lib", "release")
debpkgdir = os.path.join(pkgdir, "lib", "debug")
+ llbasedir = os.path.join(pkgdir, os.pardir)
if self.prefix(src="", dst="Contents"): # everything goes in Contents
self.path("Info.plist", dst="Info.plist")
@@ -723,7 +727,17 @@ class DarwinManifest(ViewerManifest):
if self.prefix(dst="MacOS"):
self.path2basename("../viewer_components/updater/scripts/darwin", "*.py")
- self.end_prefix()
+ #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
+ self.path2basename("../viewer_components/manager","SL_Launcher")
+ self.path2basename("../viewer_components/manager","*.py")
+ llbase_path = os.path.join(self.get_dst_prefix(),'llbase')
+ if not os.path.exists(llbase_path):
+ os.makedirs(llbase_path)
+ if self.prefix(dst="llbase"):
+ self.path2basename("../packages/llbase","*.py")
+ self.path2basename("../packages/llbase","_cllsd.so")
+ self.end_prefix()
+ self.end_prefix()
# most everything goes in the Resources directory
if self.prefix(src="", dst="Resources"):
@@ -766,6 +780,12 @@ class DarwinManifest(ViewerManifest):
self.path("uk.lproj")
self.path("zh-Hans.lproj")
+ #VMP icons
+ if self.prefix("vmp_icons"):
+ self.path("*.png")
+ self.path("*.gif")
+ self.end_prefix("vmp_icons")
+
def path_optional(src, dst):
"""
For a number of our self.path() calls, not only do we want
@@ -954,12 +974,6 @@ class DarwinManifest(ViewerManifest):
self.run_command('strip -S %(viewer_binary)r' %
{ 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
- def copy_finish(self):
- # Force executable permissions to be set for scripts
- # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
- for script in 'Contents/MacOS/update_install.py',:
- self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
-
def package_finish(self):
global CHANNEL_VENDOR_BASE
# MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning.
@@ -1145,7 +1159,16 @@ class LinuxManifest(ViewerManifest):
self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
self.path2basename("../llplugin/slplugin", "SLPlugin")
- self.path2basename("../viewer_components/updater/scripts/linux", "update_install")
+ #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
+ self.path2basename("../viewer_components/manager","SL_Launcher")
+ self.path2basename("../viewer_components/manager","*.py")
+ llbase_path = os.path.join(self.get_dst_prefix(),'llbase')
+ if not os.path.exists(llbase_path):
+ os.makedirs(llbase_path)
+ if self.prefix(dst="llbase"):
+ self.path2basename("../packages/llbase","*.py")
+ self.path2basename("../packages/llbase","_cllsd.so")
+ self.end_prefix()
self.end_prefix("bin")
if self.prefix("res-sdl"):
@@ -1184,12 +1207,6 @@ class LinuxManifest(ViewerManifest):
self.path("featuretable_linux.txt")
- def copy_finish(self):
- # Force executable permissions to be set for scripts
- # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
- for script in 'secondlife', 'bin/update_install':
- self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
-
def package_finish(self):
installer_name = self.installer_base_name()
@@ -1231,7 +1248,8 @@ class LinuxManifest(ViewerManifest):
def strip_binaries(self):
if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"
- self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install \! -name *.dat | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
+ # makes some small assumptions about our packaged dir structure
+ self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name \*.py \! -name SL_Launcher \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} )
class Linux_i686_Manifest(LinuxManifest):
def construct(self):
diff --git a/indra/newview/vmp_icons/SL_Logo.gif b/indra/newview/vmp_icons/SL_Logo.gif
new file mode 100644
index 0000000000..c24d6b08cb
--- /dev/null
+++ b/indra/newview/vmp_icons/SL_Logo.gif
Binary files differ
diff --git a/indra/newview/vmp_icons/SL_Logo.png b/indra/newview/vmp_icons/SL_Logo.png
new file mode 100644
index 0000000000..5e376c72f9
--- /dev/null
+++ b/indra/newview/vmp_icons/SL_Logo.png
Binary files differ
diff --git a/indra/newview/vmp_icons/head-sl-logo.gif b/indra/newview/vmp_icons/head-sl-logo.gif
new file mode 100644
index 0000000000..d635348dcc
--- /dev/null
+++ b/indra/newview/vmp_icons/head-sl-logo.gif
Binary files differ
diff --git a/indra/newview/vmp_icons/head-sl-logo.png b/indra/newview/vmp_icons/head-sl-logo.png
new file mode 100644
index 0000000000..5c214e96d1
--- /dev/null
+++ b/indra/newview/vmp_icons/head-sl-logo.png
Binary files differ
diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt
index 74c9b4568d..642dada7b2 100644
--- a/indra/viewer_components/CMakeLists.txt
+++ b/indra/viewer_components/CMakeLists.txt
@@ -1,4 +1,3 @@
# -*- cmake -*-
add_subdirectory(login)
-add_subdirectory(updater)
diff --git a/indra/viewer_components/Resources/README b/indra/viewer_components/Resources/README
new file mode 100644
index 0000000000..e1b35730d4
--- /dev/null
+++ b/indra/viewer_components/Resources/README
@@ -0,0 +1,9 @@
+This directory only exists as a place for the summary.json file to exist when the unit tests are run on a Mac, where the file goes to a sibling directory of the scripts dir. In Linux and Windows, the JSON file goes into the same directory as the script.
+
+See:
+
+test_get_summary.py
+update_manager.get_summary()
+
+for more details
+- coyot 201606.02
diff --git a/indra/viewer_components/Resources/summary.json b/indra/viewer_components/Resources/summary.json
new file mode 100644
index 0000000000..b78859d427
--- /dev/null
+++ b/indra/viewer_components/Resources/summary.json
@@ -0,0 +1 @@
+{"Type":"viewer","Version":"4.0.5.315117","Channel":"Second Life Release"}
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
deleted file mode 100644
index 73e18aacb3..0000000000
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- cmake -*-
-
-project(updater_service)
-
-include(00-Common)
-if(LL_TESTS)
- include(LLAddBuildTest)
-endif(LL_TESTS)
-include(Boost)
-include(CMakeCopyIfDifferent)
-include(CURL)
-include(LLCommon)
-include(LLCoreHttp)
-include(LLMessage)
-include(LLPlugin)
-include(LLVFS)
-
-include_directories(
- ${LLCOMMON_INCLUDE_DIRS}
- ${LLCOREHTTP_INCLUDE_DIRS}
- ${LLMESSAGE_INCLUDE_DIRS}
- ${LLPLUGIN_INCLUDE_DIRS}
- ${LLVFS_INCLUDE_DIRS}
- ${CURL_INCLUDE_DIRS}
- ${CMAKE_SOURCE_DIR}/newview
- )
-include_directories(SYSTEM
- ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
- )
-
-set(updater_service_SOURCE_FILES
- llupdaterservice.cpp
- llupdatechecker.cpp
- llupdatedownloader.cpp
- llupdateinstaller.cpp
- )
-
-set(updater_service_HEADER_FILES
- llupdaterservice.h
- llupdatechecker.h
- llupdatedownloader.h
- llupdateinstaller.h
- )
-
-set_source_files_properties(${updater_service_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
-set_source_files_properties(
- llupdaterservice.cpp
- PROPERTIES
- COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
- )
-
-list(APPEND
- updater_service_SOURCE_FILES
- ${updater_service_HEADER_FILES}
- )
-
-add_library(llupdaterservice
- ${updater_service_SOURCE_FILES}
- )
-
-target_link_libraries(llupdaterservice
- ${LLCOMMON_LIBRARIES}
- ${LLMESSAGE_LIBRARIES}
- ${LLCOREHTTP_LIBRARIES}
- ${LLPLUGIN_LIBRARIES}
- ${LLVFS_LIBRARIES}
- )
-
-if(LL_TESTS)
-if (NOT LINUX)
- SET(llupdater_service_TEST_SOURCE_FILES
- llupdaterservice.cpp
- )
-
-set(test_libs
- ${LLCOMMON_LIBRARIES}
- ${BOOST_COROUTINE_LIBRARY}
- ${BOOST_CONTEXT_LIBRARY}
- ${BOOST_THREAD_LIBRARY}
- ${BOOST_SYSTEM_LIBRARY})
-
-set_source_files_properties(
- llupdaterservice.cpp
- PROPERTIES
- LL_TEST_ADDITIONAL_LIBRARIES ${test_libs}
-# *NOTE:Mani - I was trying to use the preprocessor seam to mock out
-# llifstream (and other) llcommon classes. It didn't work
-# because of the windows declspec(dllimport)attribute.
-# LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream"
- )
-
- LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}" ${test_libs})
-endif (NOT LINUX)
-endif(LL_TESTS)
-
-set(UPDATER_INCLUDE_DIRS
- ${LIBS_OPEN_DIR}/viewer_components/updater
- CACHE INTERNAL ""
-)
-
-set(UPDATER_LIBRARIES
- llupdaterservice
- CACHE INTERNAL ""
-)
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
deleted file mode 100644
index 1bb5e95740..0000000000
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/**
- * @file llupdaterservice.cpp
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include <stdexcept>
-#include <boost/format.hpp>
-#include "llsd.h"
-#include "llupdatechecker.h"
-#include "lluri.h"
-#include "llcorehttputil.h"
-#if LL_DARWIN
-#include <CoreServices/CoreServices.h>
-#endif
-
-#if LL_WINDOWS
-#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
-#endif
-
-
-class LLUpdateChecker::CheckError:
- public std::runtime_error
-{
-public:
- CheckError(const char * message):
- std::runtime_error(message)
- {
- ; // No op.
- }
-};
-
-
-// LLUpdateChecker
-//-----------------------------------------------------------------------------
-LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
- mImplementation(new LLUpdateChecker::Implementation(client))
-{
- ; // No op.
-}
-
-void LLUpdateChecker::checkVersion(std::string const & urlBase,
- std::string const & channel,
- std::string const & version,
- std::string const & platform,
- std::string const & platform_version,
- unsigned char uniqueid[MD5HEX_STR_SIZE],
- bool willing_to_test)
-{
- mImplementation->checkVersion(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
-}
-
-
-// LLUpdateChecker::Implementation
-//-----------------------------------------------------------------------------
-const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.1";
-
-
-LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
- mClient(client),
- mInProgress(false),
- mProtocol(sProtocolVersion)
-{
- ; // No op.
-}
-
-
-LLUpdateChecker::Implementation::~Implementation()
-{
- ; // No op.
-}
-
-
-void LLUpdateChecker::Implementation::checkVersion(std::string const & urlBase,
- std::string const & channel,
- std::string const & version,
- std::string const & platform,
- std::string const & platform_version,
- unsigned char uniqueid[MD5HEX_STR_SIZE],
- bool willing_to_test)
-{
- if (!mInProgress)
- {
- mInProgress = true;
-
- mUrlBase = urlBase;
- mChannel = channel;
- mVersion = version;
- mPlatform = platform;
- mPlatformVersion = platform_version;
- memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE);
- mWillingToTest = willing_to_test;
-
- mProtocol = sProtocolVersion;
-
- std::string checkUrl = buildUrl(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
- LL_INFOS("UpdaterService") << "checking for updates at " << checkUrl << LL_ENDL;
-
- LLCoros::instance().launch("LLUpdateChecker::Implementation::checkVersionCoro",
- boost::bind(&Implementation::checkVersionCoro, this, checkUrl));
-
- }
- else
- {
- LL_WARNS("UpdaterService") << "attempting to restart a check when one is in progress; ignored" << LL_ENDL;
- }
-}
-
-void LLUpdateChecker::Implementation::checkVersionCoro(std::string url)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("checkVersionCoro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
- LL_INFOS("checkVersionCoro") << "Getting update information from " << url << LL_ENDL;
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- mInProgress = false;
-
- if (status != LLCore::HttpStatus(HTTP_OK))
- {
- std::string server_error;
- if (result.has("error_code"))
- {
- server_error += result["error_code"].asString();
- }
- if (result.has("error_text"))
- {
- server_error += server_error.empty() ? "" : ": ";
- server_error += result["error_text"].asString();
- }
-
- LL_WARNS("UpdaterService") << "response error " << status.getStatus()
- << " " << status.toString()
- << " (" << server_error << ")"
- << LL_ENDL;
- mClient.error(status.toString());
- return;
- }
-
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- mClient.response(result);
-}
-
-std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBase,
- std::string const & channel,
- std::string const & version,
- std::string const & platform,
- std::string const & platform_version,
- unsigned char uniqueid[MD5HEX_STR_SIZE],
- bool willing_to_test)
-{
- LLSD path;
- path.append(mProtocol);
- path.append(channel);
- path.append(version);
- path.append(platform);
- path.append(platform_version);
- path.append(willing_to_test ? "testok" : "testno");
- path.append((char*)uniqueid);
- return LLURI::buildHTTP(urlBase, path).asString();
-}
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
deleted file mode 100644
index d10ea4cf42..0000000000
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * @file llupdatechecker.h
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_UPDATERCHECKER_H
-#define LL_UPDATERCHECKER_H
-
-
-#include <boost/shared_ptr.hpp>
-
-#include "llmd5.h"
-#include "lleventcoro.h"
-#include "llcoros.h"
-
-//
-// Implements asynchronous checking for updates.
-//
-class LLUpdateChecker {
-public:
- //
- // The client interface implemented by a requestor checking for an update.
- //
- class Client
- {
- public:
- // An error occurred while checking for an update.
- virtual void error(std::string const & message) = 0;
-
- // A successful response was received from the viewer version manager
- virtual void response(LLSD const & content) = 0;
- };
-
- // An exception that may be raised on check errors.
- class CheckError;
-
- LLUpdateChecker(Client & client);
-
- // Check status of current app on the given host for the channel and version provided.
- void checkVersion(std::string const & urlBase,
- std::string const & channel,
- std::string const & version,
- std::string const & platform,
- std::string const & platform_version,
- unsigned char uniqueid[MD5HEX_STR_SIZE],
- bool willing_to_test);
-
-private:
- class Implementation
- {
- public:
- typedef boost::shared_ptr<Implementation> ptr_t;
-
- Implementation(Client & client);
- ~Implementation();
- void checkVersion(std::string const & urlBase,
- std::string const & channel,
- std::string const & version,
- std::string const & platform,
- std::string const & platform_version,
- unsigned char uniqueid[MD5HEX_STR_SIZE],
- bool willing_to_test
- );
-
-
- private:
- static const char * sLegacyProtocolVersion;
- static const char * sProtocolVersion;
- const char* mProtocol;
-
- Client & mClient;
- bool mInProgress;
- std::string mVersion;
- std::string mUrlBase;
- std::string mChannel;
- std::string mPlatform;
- std::string mPlatformVersion;
- unsigned char mUniqueId[MD5HEX_STR_SIZE];
- bool mWillingToTest;
-
- std::string buildUrl(std::string const & urlBase,
- std::string const & channel,
- std::string const & version,
- std::string const & platform,
- std::string const & platform_version,
- unsigned char uniqueid[MD5HEX_STR_SIZE],
- bool willing_to_test);
-
- void checkVersionCoro(std::string url);
-
- LOG_CLASS(LLUpdateChecker::Implementation);
- };
-
-
- Implementation::ptr_t mImplementation;
- //LLPointer<Implementation> mImplementation;
-};
-
-#endif
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
deleted file mode 100644
index 04e0395c50..0000000000
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/**
- * @file llupdatedownloader.cpp
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llupdatedownloader.h"
-#include "httpcommon.h"
-#include "llexception.h"
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-#include <curl/curl.h>
-#include "lldir.h"
-#include "llevents.h"
-#include "llfile.h"
-#include "llmd5.h"
-#include "llsd.h"
-#include "llsdserialize.h"
-#include "llthread.h"
-#include "llupdaterservice.h"
-
-class LLUpdateDownloader::Implementation:
- public LLThread
-{
-public:
- Implementation(LLUpdateDownloader::Client & client);
- ~Implementation();
- void cancel(void);
- void download(LLURI const & uri,
- std::string const & hash,
- std::string const & updateChannel,
- std::string const & updateVersion,
- std::string const & info_url,
- bool required);
- bool isDownloading(void);
- size_t onHeader(void * header, size_t size);
- size_t onBody(void * header, size_t size);
- int onProgress(curl_off_t downloadSize, curl_off_t bytesDownloaded);
- void resume(void);
- void setBandwidthLimit(U64 bytesPerSecond);
-
-private:
- curl_off_t mBandwidthLimit;
- bool mCancelled;
- LLUpdateDownloader::Client & mClient;
- LLCore::LLHttp::CURL_ptr mCurl;
- LLSD mDownloadData;
- llofstream mDownloadStream;
- unsigned char mDownloadPercent;
- std::string mDownloadRecordPath;
- curl_slist * mHeaderList;
-
- void initializeCurlGet(std::string const & url, bool processHeader);
- void resumeDownloading(size_t startByte);
- void run(void);
- void startDownloading(LLURI const & uri, std::string const & hash);
- void throwOnCurlError(CURLcode code);
- bool validateDownload(const std::string& filePath);
- bool validateOrRemove(const std::string& filePath);
-
- LOG_CLASS(LLUpdateDownloader::Implementation);
-};
-
-
-namespace {
- class DownloadError:
- public LLException
- {
- public:
- DownloadError(const char * message):
- LLException(message)
- {
- ; // No op.
- }
- };
-
-
- const char * gSecondLifeUpdateRecord = "SecondLifeUpdateDownload.xml";
-};
-
-
-
-// LLUpdateDownloader
-//-----------------------------------------------------------------------------
-
-
-
-std::string LLUpdateDownloader::downloadMarkerPath(void)
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, gSecondLifeUpdateRecord);
-}
-
-
-LLUpdateDownloader::LLUpdateDownloader(Client & client):
- mImplementation(new LLUpdateDownloader::Implementation(client))
-{
- ; // No op.
-}
-
-
-void LLUpdateDownloader::cancel(void)
-{
- mImplementation->cancel();
-}
-
-
-void LLUpdateDownloader::download(LLURI const & uri,
- std::string const & hash,
- std::string const & updateChannel,
- std::string const & updateVersion,
- std::string const & info_url,
- bool required)
-{
- mImplementation->download(uri, hash, updateChannel, updateVersion, info_url, required);
-}
-
-
-bool LLUpdateDownloader::isDownloading(void)
-{
- return mImplementation->isDownloading();
-}
-
-
-void LLUpdateDownloader::resume(void)
-{
- mImplementation->resume();
-}
-
-
-void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond)
-{
- mImplementation->setBandwidthLimit(bytesPerSecond);
-}
-
-
-
-// LLUpdateDownloader::Implementation
-//-----------------------------------------------------------------------------
-
-
-namespace {
- size_t write_function(void * data, size_t blockSize, size_t blocks, void * downloader)
- {
- size_t bytes = blockSize * blocks;
- return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onBody(data, bytes);
- }
-
-
- size_t header_function(void * data, size_t blockSize, size_t blocks, void * downloader)
- {
- size_t bytes = blockSize * blocks;
- return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes);
- }
-
-
- int xferinfo_callback(void * downloader,
- curl_off_t dowloadTotal,
- curl_off_t downloadNow,
- curl_off_t uploadTotal,
- curl_off_t uploadNow)
- {
- return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->
- onProgress(dowloadTotal, downloadNow);
- }
-}
-
-
-LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client):
- LLThread("LLUpdateDownloader"),
- mBandwidthLimit(0),
- mCancelled(false),
- mClient(client),
- mCurl(),
- mDownloadPercent(0),
- mHeaderList(0)
-{
- CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
- llverify(code == CURLE_OK); // TODO: real error handling here.
-}
-
-
-LLUpdateDownloader::Implementation::~Implementation()
-{
- if(isDownloading())
- {
- cancel();
- shutdown();
- }
- else
- {
- ; // No op.
- }
- mCurl.reset();
-}
-
-
-void LLUpdateDownloader::Implementation::cancel(void)
-{
- mCancelled = true;
-}
-
-
-void LLUpdateDownloader::Implementation::download(LLURI const & uri,
- std::string const & hash,
- std::string const & updateChannel,
- std::string const & updateVersion,
- std::string const & info_url,
- bool required)
-{
- if(isDownloading()) mClient.downloadError("download in progress");
-
- mDownloadRecordPath = downloadMarkerPath();
- mDownloadData = LLSD();
- mDownloadData["required"] = required;
- mDownloadData["update_channel"] = updateChannel;
- mDownloadData["update_version"] = updateVersion;
- if (!info_url.empty())
- {
- mDownloadData["info_url"] = info_url;
- }
- try
- {
- startDownloading(uri, hash);
- }
- catch(DownloadError const & e)
- {
- mClient.downloadError(e.what());
- }
-}
-
-
-bool LLUpdateDownloader::Implementation::isDownloading(void)
-{
- return !isStopped();
-}
-
-
-void LLUpdateDownloader::Implementation::resume(void)
-{
- mCancelled = false;
-
- if(isDownloading())
- {
- mClient.downloadError("download in progress");
- }
-
- mDownloadRecordPath = downloadMarkerPath();
- llifstream dataStream(mDownloadRecordPath.c_str());
- if(!dataStream)
- {
- mClient.downloadError("no download marker");
- return;
- }
-
- LLSDSerialize::fromXMLDocument(mDownloadData, dataStream);
-
- if(!mDownloadData.asBoolean())
- {
- mClient.downloadError("no download information in marker");
- return;
- }
-
- std::string filePath = mDownloadData["path"].asString();
- try
- {
- if(LLFile::isfile(filePath))
- {
- llstat fileStatus;
- LLFile::stat(filePath, &fileStatus);
- if(fileStatus.st_size != mDownloadData["size"].asInteger())
- {
- resumeDownloading(fileStatus.st_size);
- }
- else if(!validateOrRemove(filePath))
- {
- download(LLURI(mDownloadData["url"].asString()),
- mDownloadData["hash"].asString(),
- mDownloadData["update_channel"].asString(),
- mDownloadData["update_version"].asString(),
- mDownloadData["info_url"].asString(),
- mDownloadData["required"].asBoolean());
- }
- else
- {
- mClient.downloadComplete(mDownloadData);
- }
- }
- else
- {
- download(LLURI(mDownloadData["url"].asString()),
- mDownloadData["hash"].asString(),
- mDownloadData["update_channel"].asString(),
- mDownloadData["update_version"].asString(),
- mDownloadData["info_url"].asString(),
- mDownloadData["required"].asBoolean());
- }
- }
- catch(DownloadError & e)
- {
- mClient.downloadError(e.what());
- }
-}
-
-
-void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond)
-{
- if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean())
- {
- llassert(static_cast<bool>(mCurl));
- mBandwidthLimit = bytesPerSecond;
- CURLcode code = curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit);
- if(code != CURLE_OK)
- {
- LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL;
- }
- }
- else
- {
- mBandwidthLimit = bytesPerSecond;
- }
-}
-
-
-size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
-{
- char const * headerPtr = reinterpret_cast<const char *> (buffer);
- std::string header(headerPtr, headerPtr + size);
- size_t colonPosition = header.find(':');
- if(colonPosition == std::string::npos) return size; // HTML response; ignore.
-
- if(header.substr(0, colonPosition) == "Content-Length") {
- try {
- size_t firstDigitPos = header.find_first_of("0123456789", colonPosition);
- size_t lastDigitPos = header.find_last_of("0123456789");
- std::string contentLength = header.substr(firstDigitPos, lastDigitPos - firstDigitPos + 1);
- size_t size = boost::lexical_cast<size_t>(contentLength);
- LL_INFOS("UpdaterService") << "download size is " << size << LL_ENDL;
-
- mDownloadData["size"] = LLSD(LLSD::Integer(size));
- llofstream odataStream(mDownloadRecordPath.c_str());
- LLSDSerialize::toPrettyXML(mDownloadData, odataStream);
- } catch (std::exception const & e) {
- LL_WARNS("UpdaterService") << "unable to read content length ("
- << e.what() << ")" << LL_ENDL;
- }
- } else {
- ; // No op.
- }
-
- return size;
-}
-
-
-size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
-{
- if(mCancelled) return 0; // Forces a write error which will halt curl thread.
- if((size == 0) || (buffer == 0)) return 0;
-
- mDownloadStream.write(static_cast<const char *>(buffer), size);
- if(mDownloadStream.bad()) {
- return 0;
- } else {
- return size;
- }
-}
-
-
-int LLUpdateDownloader::Implementation::onProgress(curl_off_t downloadSize, curl_off_t bytesDownloaded)
-{
- int downloadPercent = static_cast<int>(100.0 * ((double) bytesDownloaded / (double) downloadSize));
- if(downloadPercent > mDownloadPercent) {
- mDownloadPercent = downloadPercent;
-
- LLSD event;
- event["pump"] = LLUpdaterService::pumpName();
- LLSD payload;
- payload["type"] = LLSD(LLUpdaterService::PROGRESS);
- payload["download_size"] = (LLSD::Integer) downloadSize;
- payload["bytes_downloaded"] = (LLSD::Integer) bytesDownloaded;
- event["payload"] = payload;
- LLEventPumps::instance().obtain("mainlooprepeater").post(event);
-
- LL_INFOS("UpdaterService") << "progress event " << payload << LL_ENDL;
- } else {
- ; // Keep events to a reasonalbe number.
- }
-
- return 0;
-}
-
-
-void LLUpdateDownloader::Implementation::run(void)
-{
- CURLcode code = curl_easy_perform(mCurl.get());
- mDownloadStream.close();
- if(code == CURLE_OK)
- {
- LLFile::remove(mDownloadRecordPath);
- if(validateOrRemove(mDownloadData["path"]))
- {
- LL_INFOS("UpdaterService") << "download successful" << LL_ENDL;
- mClient.downloadComplete(mDownloadData);
- }
- else
- {
- mClient.downloadError("failed hash check");
- }
- }
- else if(mCancelled && (code == CURLE_WRITE_ERROR))
- {
- LL_INFOS("UpdaterService") << "download canceled by user" << LL_ENDL;
- // Do not call back client.
- }
- else
- {
- LL_WARNS("UpdaterService") << "download failed with error '" <<
- curl_easy_strerror(code) << "'" << LL_ENDL;
- LLFile::remove(mDownloadRecordPath);
- if(mDownloadData.has("path"))
- {
- std::string filePath = mDownloadData["path"].asString();
- LL_INFOS("UpdaterService") << "removing " << filePath << LL_ENDL;
- LLFile::remove(filePath);
- }
- mClient.downloadError("curl error");
- }
-
- if(mHeaderList)
- {
- curl_slist_free_all(mHeaderList);
- mHeaderList = 0;
- }
-}
-
-
-void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
-{
- if(!mCurl)
- {
- mCurl = LLCore::LLHttp::createEasyHandle();
- }
- else
- {
- curl_easy_reset(mCurl.get());
- }
-
- if(!mCurl)
- {
- LLTHROW(DownloadError("failed to initialize curl"));
- }
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOSIGNAL, true));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_FOLLOWLOCATION, true));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEFUNCTION, &write_function));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEDATA, this));
- if(processHeader)
- {
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERFUNCTION, &header_function));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERDATA, this));
- }
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPGET, true));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_URL, url.c_str()));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_XFERINFOFUNCTION, &xferinfo_callback));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_XFERINFODATA, this));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOPROGRESS, 0));
- // if it's a required update set the bandwidth limit to 0 (unlimited)
- curl_off_t limit = mDownloadData["required"].asBoolean() ? 0 : mBandwidthLimit;
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, limit));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_CAINFO, gDirUtilp->getCAFile().c_str()));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_SSL_VERIFYHOST, 2));
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_SSL_VERIFYPEER, 1));
-
- mDownloadPercent = 0;
-}
-
-
-void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)
-{
- LL_INFOS("UpdaterService") << "resuming download from " << mDownloadData["url"].asString()
- << " at byte " << startByte << LL_ENDL;
-
- initializeCurlGet(mDownloadData["url"].asString(), false);
-
- // The header 'Range: bytes n-' will request the bytes remaining in the
- // source begining with byte n and ending with the last byte.
- boost::format rangeHeaderFormat("Range: bytes=%u-");
- rangeHeaderFormat % startByte;
- mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str());
- if(mHeaderList == 0)
- {
- LLTHROW(DownloadError("cannot add Range header"));
- }
- throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPHEADER, mHeaderList));
-
- mDownloadStream.open(mDownloadData["path"].asString().c_str(),
- std::ios_base::out | std::ios_base::binary | std::ios_base::app);
- start();
-}
-
-
-void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std::string const & hash)
-{
- mDownloadData["url"] = uri.asString();
- mDownloadData["hash"] = hash;
- mDownloadData["current_version"] = ll_get_version();
- LLSD path = uri.pathArray();
- if(path.size() == 0) LLTHROW(DownloadError("no file path"));
- std::string fileName = path[path.size() - 1].asString();
- std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName);
- mDownloadData["path"] = filePath;
-
- LL_INFOS("UpdaterService") << "downloading " << filePath
- << " from " << uri.asString() << LL_ENDL;
- LL_INFOS("UpdaterService") << "hash of file is " << hash << LL_ENDL;
-
- llofstream dataStream(mDownloadRecordPath.c_str());
- LLSDSerialize::toPrettyXML(mDownloadData, dataStream);
-
- mDownloadStream.open(filePath.c_str(), std::ios_base::out | std::ios_base::binary);
- initializeCurlGet(uri.asString(), true);
- start();
-}
-
-
-void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code)
-{
- if(code != CURLE_OK) {
- const char * errorString = curl_easy_strerror(code);
- if(errorString != 0) {
- LLTHROW(DownloadError(curl_easy_strerror(code)));
- } else {
- LLTHROW(DownloadError("unknown curl error"));
- }
- } else {
- ; // No op.
- }
-}
-
-bool LLUpdateDownloader::Implementation::validateOrRemove(const std::string& filePath)
-{
- bool valid = validateDownload(filePath);
- if (! valid)
- {
- LL_INFOS("UpdaterService") << "removing " << filePath << LL_ENDL;
- LLFile::remove(filePath);
- }
- return valid;
-}
-
-bool LLUpdateDownloader::Implementation::validateDownload(const std::string& filePath)
-{
- llifstream fileStream(filePath.c_str(), std::ios_base::in | std::ios_base::binary);
- if(!fileStream)
- {
- LL_INFOS("UpdaterService") << "can't open " << filePath << ", invalid" << LL_ENDL;
- return false;
- }
-
- std::string hash = mDownloadData["hash"].asString();
- if (! hash.empty())
- {
- char digest[33];
- LLMD5(fileStream).hex_digest(digest);
- if (hash == digest)
- {
- LL_INFOS("UpdaterService") << "verified hash " << hash
- << " for downloaded " << filePath << LL_ENDL;
- return true;
- }
- else
- {
- LL_WARNS("UpdaterService") << "download hash mismatch for "
- << filePath << ": expected " << hash
- << " but computed " << digest << LL_ENDL;
- return false;
- }
- }
- else
- {
- LL_INFOS("UpdaterService") << "no hash specified for " << filePath
- << ", unverified" << LL_ENDL;
- return true; // No hash check provided.
- }
-}
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
deleted file mode 100644
index f759988f12..0000000000
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * @file llupdatedownloader.h
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_UPDATE_DOWNLOADER_H
-#define LL_UPDATE_DOWNLOADER_H
-
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-#include "lluri.h"
-
-
-//
-// An asynchronous download service for fetching updates.
-//
-class LLUpdateDownloader
-{
-public:
- class Client;
- class Implementation;
-
- // Returns the path to the download marker file containing details of the
- // latest download.
- static std::string downloadMarkerPath(void);
-
- LLUpdateDownloader(Client & client);
-
- // Cancel any in progress download; a no op if none is in progress. The
- // client will not receive a complete or error callback.
- void cancel(void);
-
- // Start a new download.
- void download(LLURI const & uri,
- std::string const & hash,
- std::string const & updateChannel,
- std::string const & updateVersion,
- std::string const & info_url,
- bool required=false);
-
- // Returns true if a download is in progress.
- bool isDownloading(void);
-
- // Resume a partial download.
- void resume(void);
-
- // Set a limit on the dowload rate.
- void setBandwidthLimit(U64 bytesPerSecond);
-
-private:
- boost::shared_ptr<Implementation> mImplementation;
-};
-
-
-//
-// An interface to be implemented by clients initiating a update download.
-//
-class LLUpdateDownloader::Client {
-public:
-
- // The download has completed successfully.
- // data is a map containing the following items:
- // url - source (remote) location
- // hash - the md5 sum that should match the installer file.
- // path - destination (local) location
- // required - boolean indicating if this is a required update.
- // size - the size of the installer in bytes
- virtual void downloadComplete(LLSD const & data) = 0;
-
- // The download failed.
- virtual void downloadError(std::string const & message) = 0;
-};
-
-
-#endif
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
deleted file mode 100644
index 1c7629da23..0000000000
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * @file llupdateinstaller.cpp
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include <apr_file_io.h>
-#include "llapr.h"
-#include "llprocess.h"
-#include "llupdateinstaller.h"
-#include "lldir.h"
-#include "llsd.h"
-#include "llexception.h"
-
-#if defined(LL_WINDOWS)
-#pragma warning(disable: 4702) // disable 'unreachable code' so we can use lexical_cast (really!).
-#endif
-#include <boost/lexical_cast.hpp>
-
-namespace {
- struct RelocateError: public LLException
- {
- RelocateError(): LLException("llupdateinstaller: RelocateError") {}
- };
-
- std::string copy_to_temp(std::string const & path)
- {
- std::string scriptFile = gDirUtilp->getBaseFileName(path);
- std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile);
- apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp);
- if(status != APR_SUCCESS) LLTHROW(RelocateError());
-
- return newPath;
- }
-}
-
-
-int ll_install_update(std::string const & script,
- std::string const & updatePath,
- bool required,
- LLInstallScriptMode mode)
-{
- std::string actualScriptPath;
- switch(mode) {
- case LL_COPY_INSTALL_SCRIPT_TO_TEMP:
- try {
- actualScriptPath = copy_to_temp(script);
- }
- catch (RelocateError &) {
- return -1;
- }
- break;
- case LL_RUN_INSTALL_SCRIPT_IN_PLACE:
- actualScriptPath = script;
- break;
- default:
- llassert(!"unpossible copy mode");
- }
-
- LL_INFOS("Updater") << "UpdateInstaller: installing " << updatePath << " using " <<
- actualScriptPath << LL_ENDL;
-
- LLProcess::Params params;
- params.executable = actualScriptPath;
- params.args.add(updatePath);
- params.args.add(ll_install_failed_marker_path());
- params.args.add(boost::lexical_cast<std::string>(required));
- params.autokill = false;
- return LLProcess::create(params)? 0 : -1;
-}
-
-
-std::string const & ll_install_failed_marker_path(void)
-{
- static std::string path;
- if(path.empty()) {
- path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLifeInstallFailed.marker");
- }
- return path;
-}
diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h
deleted file mode 100644
index fe5b1d19b5..0000000000
--- a/indra/viewer_components/updater/llupdateinstaller.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file llupdateinstaller.h
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_UPDATE_INSTALLER_H
-#define LL_UPDATE_INSTALLER_H
-
-
-#include <string>
-
-
-enum LLInstallScriptMode {
- LL_RUN_INSTALL_SCRIPT_IN_PLACE,
- LL_COPY_INSTALL_SCRIPT_TO_TEMP
-};
-
-//
-// Launch the installation script.
-//
-// The updater will overwrite the current installation, so it is highly recommended
-// that the current application terminate once this function is called.
-//
-int ll_install_update(
- std::string const & script, // Script to execute.
- std::string const & updatePath, // Path to update file.
- bool required, // Is the update required.
- LLInstallScriptMode mode=LL_COPY_INSTALL_SCRIPT_TO_TEMP); // Run in place or copy to temp?
-
-
-//
-// Returns the path which points to the failed install marker file, should it
-// exist.
-//
-std::string const & ll_install_failed_marker_path(void);
-
-
-#endif
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
deleted file mode 100644
index df021948c3..0000000000
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ /dev/null
@@ -1,763 +0,0 @@
-/**
- * @file llupdaterservice.cpp
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llupdaterservice.h"
-
-#include "llupdatedownloader.h"
-#include "llevents.h"
-#include "lltimer.h"
-#include "llupdatechecker.h"
-#include "llupdateinstaller.h"
-#include "llexception.h"
-
-#include <boost/scoped_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include "lldir.h"
-#include "llsdserialize.h"
-#include "llfile.h"
-#include "llviewernetwork.h"
-
-#if LL_WINDOWS
-#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
-#endif
-
-#if ! defined(LL_VIEWER_VERSION_MAJOR) \
- || ! defined(LL_VIEWER_VERSION_MINOR) \
- || ! defined(LL_VIEWER_VERSION_PATCH) \
- || ! defined(LL_VIEWER_VERSION_BUILD)
-#error "Version information is undefined"
-#endif
-
-namespace
-{
- boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
-
- const std::string UPDATE_MARKER_FILENAME("SecondLifeUpdateReady.xml");
- std::string update_marker_path()
- {
- return gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- UPDATE_MARKER_FILENAME);
- }
-
- std::string install_script_path(void)
- {
-#ifdef LL_WINDOWS
- std::string scriptFile = "update_install.bat";
-#elif LL_DARWIN
- std::string scriptFile = "update_install.py";
-#else
- std::string scriptFile = "update_install";
-#endif
- return gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, scriptFile);
- }
-
- LLInstallScriptMode install_script_mode(void)
- {
-#ifdef LL_WINDOWS
- return LL_COPY_INSTALL_SCRIPT_TO_TEMP;
-#else
- // This is important on Mac because update_install.py looks at its own
- // script pathname to discover the viewer app bundle to update.
- return LL_RUN_INSTALL_SCRIPT_IN_PLACE;
-#endif
- };
-
-}
-
-class LLUpdaterServiceImpl :
- public LLUpdateChecker::Client,
- public LLUpdateDownloader::Client
-{
- static const std::string sListenerName;
-
- std::string mProtocolVersion;
- std::string mChannel;
- std::string mVersion;
- std::string mPlatform;
- std::string mPlatformVersion;
- unsigned char mUniqueId[MD5HEX_STR_SIZE];
- bool mWillingToTest;
-
- unsigned int mCheckPeriod;
- bool mIsChecking;
- bool mIsDownloading;
-
- LLUpdateChecker mUpdateChecker;
- LLUpdateDownloader mUpdateDownloader;
- LLTimer mTimer;
-
- LLUpdaterService::app_exit_callback_t mAppExitCallback;
-
- LLUpdaterService::eUpdaterState mState;
-
- LOG_CLASS(LLUpdaterServiceImpl);
-
-public:
- LLUpdaterServiceImpl();
- virtual ~LLUpdaterServiceImpl();
-
- void initialize(const std::string& channel,
- const std::string& version,
- const std::string& platform,
- const std::string& platform_version,
- const unsigned char uniqueid[MD5HEX_STR_SIZE],
- const bool& willing_to_test
- );
-
- void setCheckPeriod(unsigned int seconds);
- void setBandwidthLimit(U64 bytesPerSecond);
-
- void startChecking(bool install_if_ready);
- void stopChecking();
- bool forceCheck();
- bool isChecking();
- LLUpdaterService::eUpdaterState getState();
-
- void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;}
- std::string updatedVersion(void);
-
- bool checkForInstall(bool launchInstaller); // Test if a local install is ready.
- bool checkForResume(); // Test for resumeable d/l.
-
- // LLUpdateChecker::Client:
- virtual void error(std::string const & message);
-
- // A successful response was received from the viewer version manager
- virtual void response(LLSD const & content);
-
- // LLUpdateDownloader::Client
- void downloadComplete(LLSD const & data);
- void downloadError(std::string const & message);
-
- bool onMainLoop(LLSD const & event);
-
-private:
- std::string mNewChannel;
- std::string mNewVersion;
- LLTempBoundListener mMainLoopConnection;
-
- void restartTimer(unsigned int seconds);
- void setState(LLUpdaterService::eUpdaterState state);
- void stopTimer();
-};
-
-const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
-
-LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
- mIsChecking(false),
- mIsDownloading(false),
- mCheckPeriod(0),
- mUpdateChecker(*this),
- mUpdateDownloader(*this),
- mState(LLUpdaterService::INITIAL)
-{
-}
-
-LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
-{
- LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL;
- // Destroying an LLTempBoundListener implicitly disconnects. That's its
- // whole purpose.
-}
-
-void LLUpdaterServiceImpl::initialize(const std::string& channel,
- const std::string& version,
- const std::string& platform,
- const std::string& platform_version,
- const unsigned char uniqueid[MD5HEX_STR_SIZE],
- const bool& willing_to_test)
-{
- if(mIsChecking || mIsDownloading)
- {
- LLTHROW(LLUpdaterService::UsageError("LLUpdaterService::initialize call "
- "while updater is running."));
- }
-
- mChannel = channel;
- mVersion = version;
- mPlatform = platform;
- mPlatformVersion = platform_version;
- memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE);
- mWillingToTest = willing_to_test;
- LL_DEBUGS("UpdaterService")
- << "\n channel: " << mChannel
- << "\n version: " << mVersion
- << "\n uniqueid: " << mUniqueId
- << "\n willing: " << ( mWillingToTest ? "testok" : "testno" )
- << LL_ENDL;
-}
-
-void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
-{
- mCheckPeriod = seconds;
-}
-
-void LLUpdaterServiceImpl::setBandwidthLimit(U64 bytesPerSecond)
-{
- mUpdateDownloader.setBandwidthLimit(bytesPerSecond);
-}
-
-void LLUpdaterServiceImpl::startChecking(bool install_if_ready)
-{
- if(mChannel.empty() || mVersion.empty())
- {
- LLTHROW(LLUpdaterService::UsageError("Set params before call to "
- "LLUpdaterService::startCheck()."));
- }
-
- mIsChecking = true;
-
- // Check to see if an install is ready.
- bool has_install = checkForInstall(install_if_ready);
- if(!has_install)
- {
- checkForResume(); // will set mIsDownloading to true if resuming
-
- if(!mIsDownloading)
- {
- setState(LLUpdaterService::CHECKING_FOR_UPDATE);
-
- // Checking can only occur during the mainloop.
- // reset the timer to 0 so that the next mainloop event
- // triggers a check;
- restartTimer(0);
- }
- else
- {
- setState(LLUpdaterService::DOWNLOADING);
- }
- }
-}
-
-void LLUpdaterServiceImpl::stopChecking()
-{
- if(mIsChecking)
- {
- mIsChecking = false;
- stopTimer();
- }
-
- if(mIsDownloading)
- {
- mUpdateDownloader.cancel();
- mIsDownloading = false;
- }
-
- setState(LLUpdaterService::TERMINAL);
-}
-
-bool LLUpdaterServiceImpl::forceCheck()
-{
- if (!mIsDownloading && getState() != LLUpdaterService::CHECKING_FOR_UPDATE)
- {
- if (mIsChecking)
- {
- // Service is running, just reset the timer
- if (mTimer.getStarted())
- {
- mTimer.setTimerExpirySec(0);
- setState(LLUpdaterService::CHECKING_FOR_UPDATE);
- return true;
- }
- }
- else if (!mChannel.empty() && !mVersion.empty())
- {
- // one time check
- bool has_install = checkForInstall(false);
- if (!has_install)
- {
- std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL();
- if (!query_url.empty())
- {
- setState(LLUpdaterService::CHECKING_FOR_UPDATE);
- mUpdateChecker.checkVersion(query_url, mChannel, mVersion,
- mPlatform, mPlatformVersion, mUniqueId,
- mWillingToTest);
- return true;
- }
- else
- {
- LL_WARNS("UpdaterService")
- << "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid() << LL_ENDL;
- }
- }
- }
- }
- return false;
-}
-
-bool LLUpdaterServiceImpl::isChecking()
-{
- return mIsChecking;
-}
-
-LLUpdaterService::eUpdaterState LLUpdaterServiceImpl::getState()
-{
- return mState;
-}
-
-std::string LLUpdaterServiceImpl::updatedVersion(void)
-{
- return mNewVersion;
-}
-
-bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)
-{
- bool foundInstall = false; // return true if install is found.
-
- llifstream update_marker(update_marker_path().c_str(),
- std::ios::in | std::ios::binary);
-
- if(update_marker.is_open())
- {
- // Found an update info - now lets see if its valid.
- LLSD update_info;
- LLSDSerialize::fromXMLDocument(update_info, update_marker);
- update_marker.close();
-
- // Get the path to the installer file.
- std::string path(update_info.get("path"));
- std::string downloader_version(update_info["current_version"]);
- if (downloader_version != ll_get_version())
- {
- // This viewer is not the same version as the one that downloaded
- // the update. Do not install this update.
- LL_INFOS("UpdaterService") << "ignoring update downloaded by "
- << "different viewer version "
- << downloader_version << LL_ENDL;
- if (! path.empty())
- {
- LL_INFOS("UpdaterService") << "removing " << path << LL_ENDL;
- LLFile::remove(path);
- LLFile::remove(update_marker_path());
- }
-
- foundInstall = false;
- }
- else if (path.empty())
- {
- LL_WARNS("UpdaterService") << "Marker file " << update_marker_path()
- << " 'path' entry empty, ignoring" << LL_ENDL;
- foundInstall = false;
- }
- else if (! LLFile::isfile(path))
- {
- LL_WARNS("UpdaterService") << "Nonexistent installer " << path
- << ", ignoring" << LL_ENDL;
- foundInstall = false;
- }
- else
- {
- if(launchInstaller)
- {
- setState(LLUpdaterService::INSTALLING);
-
- LLFile::remove(update_marker_path());
-
- int result = ll_install_update(install_script_path(),
- path,
- update_info["required"].asBoolean(),
- install_script_mode());
-
- if((result == 0) && mAppExitCallback)
- {
- mAppExitCallback();
- }
- else if(result != 0)
- {
- LL_WARNS("UpdaterService") << "failed to run update install script" << LL_ENDL;
- }
- else
- {
- ; // No op.
- }
- }
-
- foundInstall = true;
- }
- }
- return foundInstall;
-}
-
-bool LLUpdaterServiceImpl::checkForResume()
-{
- bool result = false;
- std::string download_marker_path = mUpdateDownloader.downloadMarkerPath();
- if(LLFile::isfile(download_marker_path))
- {
- llifstream download_marker_stream(download_marker_path.c_str(),
- std::ios::in | std::ios::binary);
- if(download_marker_stream.is_open())
- {
- LLSD download_info;
- LLSDSerialize::fromXMLDocument(download_info, download_marker_stream);
- download_marker_stream.close();
- std::string downloader_version(download_info["current_version"]);
- if (downloader_version == ll_get_version())
- {
- mIsDownloading = true;
- mNewVersion = download_info["update_version"].asString();
- mNewChannel = download_info["update_channel"].asString();
- mUpdateDownloader.resume();
- result = true;
- }
- else
- {
- // The viewer that started this download is not the same as this viewer; ignore.
- LL_INFOS("UpdaterService") << "ignoring partial download "
- << "from different viewer version "
- << downloader_version << LL_ENDL;
- std::string path = download_info["path"].asString();
- if(!path.empty())
- {
- LL_INFOS("UpdaterService") << "removing " << path << LL_ENDL;
- LLFile::remove(path);
- }
- LLFile::remove(download_marker_path);
- }
- }
- }
- return result;
-}
-
-void LLUpdaterServiceImpl::error(std::string const & message)
-{
- setState(LLUpdaterService::TEMPORARY_ERROR);
- if(mIsChecking)
- {
- restartTimer(mCheckPeriod);
- }
-}
-
-// A successful response was received from the viewer version manager
-void LLUpdaterServiceImpl::response(LLSD const & content)
-{
- if(!content.asBoolean()) // an empty response means "no update"
- {
- LL_INFOS("UpdaterService") << "up to date" << LL_ENDL;
- if(mIsChecking)
- {
- restartTimer(mCheckPeriod);
- }
-
- setState(LLUpdaterService::UP_TO_DATE);
- }
- else if ( content.isMap() && content.has("url") )
- {
- // there is an update available...
- stopTimer();
- mNewChannel = content["channel"].asString();
- if (mNewChannel.empty())
- {
- LL_INFOS("UpdaterService") << "no channel supplied, assuming current channel" << LL_ENDL;
- mNewChannel = mChannel;
- }
- mNewVersion = content["version"].asString();
- mIsDownloading = true;
- setState(LLUpdaterService::DOWNLOADING);
- BOOL required = content["required"].asBoolean();
- LLURI url(content["url"].asString());
- std::string more_info = content["more_info"].asString();
- LL_DEBUGS("UpdaterService")
- << "Starting download of "
- << ( required ? "required" : "optional" ) << " update"
- << " to channel '" << mNewChannel << "' version " << mNewVersion
- << " more info '" << more_info << "'"
- << LL_ENDL;
- mUpdateDownloader.download(url, content["hash"].asString(), mNewChannel, mNewVersion, more_info, required);
- }
- else
- {
- LL_WARNS("UpdaterService") << "Invalid update query response ignored; retry in "
- << mCheckPeriod << " seconds" << LL_ENDL;
- setState(LLUpdaterService::TEMPORARY_ERROR);
- if (mIsChecking)
- {
- restartTimer(mCheckPeriod);
- }
- }
-}
-
-void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)
-{
- mIsDownloading = false;
-
- // Save out the download data to the SecondLifeUpdateReady
- // marker file.
- llofstream update_marker(update_marker_path().c_str());
- LLSDSerialize::toPrettyXML(data, update_marker);
-
- LLSD event;
- event["pump"] = LLUpdaterService::pumpName();
- LLSD payload;
- payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE);
- payload["required"] = data["required"];
- payload["version"] = mNewVersion;
- payload["channel"] = mNewChannel;
- payload["info_url"] = data["info_url"];
- event["payload"] = payload;
- LL_DEBUGS("UpdaterService")
- << "Download complete "
- << ( data["required"].asBoolean() ? "required" : "optional" )
- << " channel " << mNewChannel
- << " version " << mNewVersion
- << " info " << data["info_url"].asString()
- << LL_ENDL;
-
- LLEventPumps::instance().obtain("mainlooprepeater").post(event);
-
- setState(LLUpdaterService::TERMINAL);
-}
-
-void LLUpdaterServiceImpl::downloadError(std::string const & message)
-{
- LL_INFOS("UpdaterService") << "Error downloading: " << message << LL_ENDL;
-
- mIsDownloading = false;
-
- // Restart the timer on error
- if(mIsChecking)
- {
- restartTimer(mCheckPeriod);
- }
-
- LLSD event;
- event["pump"] = LLUpdaterService::pumpName();
- LLSD payload;
- payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_ERROR);
- payload["message"] = message;
- event["payload"] = payload;
- LLEventPumps::instance().obtain("mainlooprepeater").post(event);
-
- setState(LLUpdaterService::FAILURE);
-}
-
-void LLUpdaterServiceImpl::restartTimer(unsigned int seconds)
-{
- LL_INFOS("UpdaterService") << "will check for update again in " <<
- seconds << " seconds" << LL_ENDL;
- mTimer.start();
- mTimer.setTimerExpirySec((F32)seconds);
- mMainLoopConnection = LLEventPumps::instance().obtain("mainloop").listen(
- sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
-}
-
-void LLUpdaterServiceImpl::setState(LLUpdaterService::eUpdaterState state)
-{
- if(state != mState)
- {
- mState = state;
-
- LLSD event;
- event["pump"] = LLUpdaterService::pumpName();
- LLSD payload;
- payload["type"] = LLSD(LLUpdaterService::STATE_CHANGE);
- payload["state"] = state;
- event["payload"] = payload;
- LLEventPumps::instance().obtain("mainlooprepeater").post(event);
-
- LL_INFOS("UpdaterService") << "setting state to " << state << LL_ENDL;
- }
- else
- {
- ; // State unchanged; noop.
- }
-}
-
-void LLUpdaterServiceImpl::stopTimer()
-{
- mTimer.stop();
- mMainLoopConnection.disconnect();
-}
-
-bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
-{
- if(mTimer.getStarted() && mTimer.hasExpired())
- {
- stopTimer();
-
- // Check for failed install.
- if(LLFile::isfile(ll_install_failed_marker_path()))
- {
- LL_DEBUGS("UpdaterService") << "found marker " << ll_install_failed_marker_path() << LL_ENDL;
- int requiredValue = 0;
- {
- llifstream stream(ll_install_failed_marker_path().c_str());
- stream >> requiredValue;
- if(stream.fail())
- {
- requiredValue = 0;
- }
- }
- // TODO: notify the user.
- LL_WARNS("UpdaterService") << "last install attempt failed" << LL_ENDL;;
- LLFile::remove(ll_install_failed_marker_path());
-
- LLSD event;
- event["type"] = LLSD(LLUpdaterService::INSTALL_ERROR);
- event["required"] = LLSD(requiredValue);
- LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).post(event);
-
- setState(LLUpdaterService::TERMINAL);
- }
- else
- {
- std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL();
- if ( !query_url.empty() )
- {
- mUpdateChecker.checkVersion(query_url, mChannel, mVersion,
- mPlatform, mPlatformVersion, mUniqueId,
- mWillingToTest);
- setState(LLUpdaterService::CHECKING_FOR_UPDATE);
- }
- else
- {
- LL_WARNS("UpdaterService")
- << "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid()
- << "' will check again in " << mCheckPeriod << " seconds"
- << LL_ENDL;
- // Because the grid can be changed after the viewer is started (when the first check takes place)
- // but before the user logs in, the next check may be on a different grid, so set the retry timer
- // even though this check did not happen. The default time is once an hour, and if we're not
- // doing the check anyway the performance impact is completely insignificant.
- restartTimer(mCheckPeriod);
- }
- }
- }
- else
- {
- // Keep on waiting...
- }
-
- return false;
-}
-
-
-//-----------------------------------------------------------------------
-// Facade interface
-
-std::string const & LLUpdaterService::pumpName(void)
-{
- static std::string name("updater_service");
- return name;
-}
-
-bool LLUpdaterService::updateReadyToInstall(void)
-{
- return LLFile::isfile(update_marker_path());
-}
-
-LLUpdaterService::LLUpdaterService()
-{
- if(gUpdater.expired())
- {
- mImpl =
- boost::shared_ptr<LLUpdaterServiceImpl>(new LLUpdaterServiceImpl());
- gUpdater = mImpl;
- }
- else
- {
- mImpl = gUpdater.lock();
- }
-}
-
-LLUpdaterService::~LLUpdaterService()
-{
-}
-
-void LLUpdaterService::initialize(const std::string& channel,
- const std::string& version,
- const std::string& platform,
- const std::string& platform_version,
- const unsigned char uniqueid[MD5HEX_STR_SIZE],
- const bool& willing_to_test
-)
-{
- mImpl->initialize(channel, version, platform, platform_version, uniqueid, willing_to_test);
-}
-
-void LLUpdaterService::setCheckPeriod(unsigned int seconds)
-{
- mImpl->setCheckPeriod(seconds);
-}
-
-void LLUpdaterService::setBandwidthLimit(U64 bytesPerSecond)
-{
- mImpl->setBandwidthLimit(bytesPerSecond);
-}
-
-void LLUpdaterService::startChecking(bool install_if_ready)
-{
- mImpl->startChecking(install_if_ready);
-}
-
-void LLUpdaterService::stopChecking()
-{
- mImpl->stopChecking();
-}
-
-bool LLUpdaterService::forceCheck()
-{
- return mImpl->forceCheck();
-}
-
-bool LLUpdaterService::isChecking()
-{
- return mImpl->isChecking();
-}
-
-LLUpdaterService::eUpdaterState LLUpdaterService::getState()
-{
- return mImpl->getState();
-}
-
-void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callback_t aecb)
-{
- return mImpl->setAppExitCallback(aecb);
-}
-
-std::string LLUpdaterService::updatedVersion(void)
-{
- return mImpl->updatedVersion();
-}
-
-
-std::string const & ll_get_version(void) {
- static std::string version("");
-
- if (version.empty()) {
- std::ostringstream stream;
- stream << LL_VIEWER_VERSION_MAJOR << "."
- << LL_VIEWER_VERSION_MINOR << "."
- << LL_VIEWER_VERSION_PATCH << "."
- << LL_VIEWER_VERSION_BUILD;
- version = stream.str();
- }
-
- return version;
-}
-
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
deleted file mode 100644
index 78e8c6b290..0000000000
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * @file llupdaterservice.h
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_UPDATERSERVICE_H
-#define LL_UPDATERSERVICE_H
-
-#include <boost/shared_ptr.hpp>
-#include <boost/function.hpp>
-#include "llhasheduniqueid.h"
-#include "llexception.h"
-
-class LLUpdaterServiceImpl;
-
-class LLUpdaterService
-{
-public:
- class UsageError: public LLException
- {
- public:
- UsageError(const std::string& msg) : LLException(msg) {}
- };
-
- // Name of the event pump through which update events will be delivered.
- static std::string const & pumpName(void);
-
- // Returns true if an update has been completely downloaded and is now ready to install.
- static bool updateReadyToInstall(void);
-
- // Type codes for events posted by this service. Stored the event's 'type' element.
- enum eUpdaterEvent {
- INVALID,
- DOWNLOAD_COMPLETE,
- DOWNLOAD_ERROR,
- INSTALL_ERROR,
- PROGRESS,
- STATE_CHANGE
- };
-
- enum eUpdaterState {
- INITIAL,
- CHECKING_FOR_UPDATE,
- TEMPORARY_ERROR,
- DOWNLOADING,
- INSTALLING,
- UP_TO_DATE,
- TERMINAL,
- FAILURE
- };
-
- LLUpdaterService();
- ~LLUpdaterService();
-
- void initialize(const std::string& channel,
- const std::string& version,
- const std::string& platform,
- const std::string& platform_version,
- const unsigned char uniqueid[MD5HEX_STR_SIZE],
- const bool& willing_to_test
- );
-
- void setCheckPeriod(unsigned int seconds);
- void setBandwidthLimit(U64 bytesPerSecond);
-
- void startChecking(bool install_if_ready = false);
- void stopChecking();
- bool forceCheck();
- bool isChecking();
- eUpdaterState getState();
-
- typedef boost::function<void (void)> app_exit_callback_t;
- template <typename F>
- void setAppExitCallback(F const &callable)
- {
- app_exit_callback_t aecb = callable;
- setImplAppExitCallback(aecb);
- }
-
- // If an update is or has been downloaded, this method will return the
- // version string for that update. An empty string will be returned
- // otherwise.
- std::string updatedVersion(void);
-
-private:
- boost::shared_ptr<LLUpdaterServiceImpl> mImpl;
- void setImplAppExitCallback(app_exit_callback_t aecb);
-};
-
-// Returns the full version as a string.
-std::string const & ll_get_version(void);
-
-#endif // LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/scripts/darwin/janitor.py b/indra/viewer_components/updater/scripts/darwin/janitor.py
deleted file mode 100644
index cdf33df731..0000000000
--- a/indra/viewer_components/updater/scripts/darwin/janitor.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/python
-"""\
-@file janitor.py
-@author Nat Goodspeed
-@date 2011-09-14
-@brief Janitor class to clean up arbitrary resources
-
-2013-01-04 cloned from vita because it's exactly what update_install.py needs.
-
-$LicenseInfo:firstyear=2011&license=viewerlgpl$
-Copyright (c) 2011, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import sys
-import functools
-import itertools
-
-class Janitor(object):
- """
- Usage:
-
- Basic:
- self.janitor = Janitor(sys.stdout) # report cleanup actions on stdout
- ...
- self.janitor.later(os.remove, some_temp_file)
- self.janitor.later(os.remove, some_other_file)
- ...
- self.janitor.cleanup() # perform cleanup actions
-
- Context Manager:
- with Janitor() as janitor: # clean up quietly
- ...
- janitor.later(shutil.rmtree, some_temp_directory)
- ...
- # exiting 'with' block performs cleanup
-
- Test Class:
- class TestMySoftware(unittest.TestCase, Janitor):
- def __init__(self):
- Janitor.__init__(self) # quiet cleanup
- ...
-
- def setUp(self):
- ...
- self.later(os.rename, saved_file, original_location)
- ...
-
- def tearDown(self):
- Janitor.tearDown(self) # calls cleanup()
- ...
- # Or, if you have no other tearDown() logic for
- # TestMySoftware, you can omit the TestMySoftware.tearDown()
- # def entirely and let it inherit Janitor.tearDown().
- """
- def __init__(self, stream=None):
- """
- If you pass stream= (e.g.) sys.stdout or sys.stderr, Janitor will
- report its cleanup operations as it performs them. If you don't, it
- will perform them quietly -- unless one or more of the actions throws
- an exception, in which case you'll get output on stderr.
- """
- self.stream = stream
- self.cleanups = []
-
- def later(self, func, *args, **kwds):
- """
- Pass the callable you want to call at cleanup() time, plus any
- positional or keyword args you want to pass it.
- """
- # Get a name string for 'func'
- try:
- # A free function has a __name__
- name = func.__name__
- except AttributeError:
- try:
- # A class object (even builtin objects like ints!) support
- # __class__.__name__
- name = func.__class__.__name__
- except AttributeError:
- # Shrug! Just use repr() to get a string describing this func.
- name = repr(func)
- # Construct a description of this operation in Python syntax from
- # args, kwds.
- desc = "%s(%s)" % \
- (name, ", ".join(itertools.chain((repr(a) for a in args),
- ("%s=%r" % (k, v) for (k, v) in kwds.iteritems()))))
- # Use functools.partial() to bind passed args and keywords to the
- # passed func so we get a nullary callable that does what caller
- # wants.
- bound = functools.partial(func, *args, **kwds)
- self.cleanups.append((desc, bound))
-
- def cleanup(self):
- """
- Perform all the actions saved with later() calls.
- """
- # Typically one allocates resource A, then allocates resource B that
- # depends on it. In such a scenario it's appropriate to delete B
- # before A -- so perform cleanup actions in reverse order. (This is
- # the same strategy used by atexit().)
- while self.cleanups:
- # Until our list is empty, pop the last pair.
- desc, bound = self.cleanups.pop(-1)
-
- # If requested, report the action.
- if self.stream is not None:
- print >>self.stream, desc
-
- try:
- # Call the bound callable
- bound()
- except Exception, err:
- # This is cleanup. Report the problem but continue.
- print >>(self.stream or sys.stderr), "Calling %s\nraised %s: %s" % \
- (desc, err.__class__.__name__, err)
-
- def tearDown(self):
- """
- If a unittest.TestCase subclass (or a nose test class) adds Janitor as
- one of its base classes, and has no other tearDown() logic, let it
- inherit Janitor.tearDown().
- """
- self.cleanup()
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, tb):
- # Perform cleanup no matter how we exit this 'with' statement
- self.cleanup()
- # Propagate any exception from the 'with' statement, don't swallow it
- return False
diff --git a/indra/viewer_components/updater/scripts/darwin/messageframe.py b/indra/viewer_components/updater/scripts/darwin/messageframe.py
deleted file mode 100644
index 8f58848882..0000000000
--- a/indra/viewer_components/updater/scripts/darwin/messageframe.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/python
-"""\
-@file messageframe.py
-@author Nat Goodspeed
-@date 2013-01-03
-@brief Define MessageFrame class for popping up messages from a command-line
- script.
-
-$LicenseInfo:firstyear=2013&license=viewerlgpl$
-Copyright (c) 2013, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import Tkinter as tk
-import os
-
-# Tricky way to obtain the filename of the main script (default title string)
-import __main__
-
-# This class is intended for displaying messages from a command-line script.
-# Getting the base class right took a bit of trial and error.
-# If you derive from tk.Frame, the destroy() method doesn't actually close it.
-# If you derive from tk.Toplevel, it pops up a separate Tk frame too. destroy()
-# closes this frame, but not that one.
-# Deriving from tk.Tk appears to do the right thing.
-class MessageFrame(tk.Tk):
- def __init__(self, text="", title=os.path.splitext(os.path.basename(__main__.__file__))[0],
- width=320, height=120):
- tk.Tk.__init__(self)
- self.grid()
- self.title(title)
- self.var = tk.StringVar()
- self.var.set(text)
- self.msg = tk.Label(self, textvariable=self.var)
- self.msg.grid()
- # from http://stackoverflow.com/questions/3352918/how-to-center-a-window-on-the-screen-in-tkinter :
- self.update_idletasks()
-
- # The constants below are to adjust for typical overhead from the
- # frame borders.
- xp = (self.winfo_screenwidth() / 2) - (width / 2) - 8
- yp = (self.winfo_screenheight() / 2) - (height / 2) - 20
- self.geometry('{0}x{1}+{2}+{3}'.format(width, height, xp, yp))
- self.update()
-
- def set(self, text):
- self.var.set(text)
- self.update()
-
-if __name__ == "__main__":
- # When run as a script, just test the MessageFrame.
- import sys
- import time
-
- frame = MessageFrame("something in the way she moves....")
- time.sleep(3)
- frame.set("smaller")
- time.sleep(3)
- frame.set("""this has
-several
-lines""")
- time.sleep(3)
- frame.destroy()
- print "Destroyed!"
- sys.stdout.flush()
- time.sleep(3)
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install.py b/indra/viewer_components/updater/scripts/darwin/update_install.py
deleted file mode 100755
index 08f4f0ebb9..0000000000
--- a/indra/viewer_components/updater/scripts/darwin/update_install.py
+++ /dev/null
@@ -1,412 +0,0 @@
-#!/usr/bin/python
-"""\
-@file update_install.py
-@author Nat Goodspeed
-@date 2012-12-20
-@brief Update the containing Second Life application bundle to the version in
- the specified disk image file.
-
- This Python implementation is derived from the previous mac-updater
- application, a funky mix of C++, classic C and Objective-C.
-
-$LicenseInfo:firstyear=2012&license=viewerlgpl$
-Copyright (c) 2012, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import os
-import sys
-import cgitb
-from contextlib import contextmanager
-import errno
-import glob
-import plistlib
-import re
-import shutil
-import subprocess
-import tempfile
-import time
-from janitor import Janitor
-from messageframe import MessageFrame
-import Tkinter, tkMessageBox
-
-TITLE = "Second Life Viewer Updater"
-# Magic bundle identifier used by all Second Life viewer bundles
-BUNDLE_IDENTIFIER = "com.secondlife.indra.viewer"
-# Magic OS directory name that causes Cocoa viewer to crash on OS X 10.7.5
-# (see MAINT-3331)
-STATE_DIR = os.path.join(
- os.environ["HOME"], "Library", "Saved Application State",
- BUNDLE_IDENTIFIER + ".savedState")
-
-# Global handle to the MessageFrame so we can update message
-FRAME = None
-# Global handle to logfile, once it's open
-LOGF = None
-
-# ****************************************************************************
-# Logging and messaging
-#
-# This script is normally run implicitly by the old viewer to update to the
-# new viewer. Its UI consists of a MessageFrame and possibly a Tk error box.
-# Log details to updater.log -- especially uncaught exceptions!
-# ****************************************************************************
-def log(message):
- """write message only to LOGF (also called by status() and fail())"""
- # If we don't even have LOGF open yet, at least write to Console log
- logf = LOGF or sys.stderr
- logf.writelines((time.strftime("%Y-%m-%dT%H:%M:%SZ ", time.gmtime()), message, '\n'))
- logf.flush()
-
-def status(message):
- """display and log normal progress message"""
- log(message)
-
- global FRAME
- if not FRAME:
- FRAME = MessageFrame(message, TITLE)
- else:
- FRAME.set(message)
-
-def fail(message):
- """log message, produce error box, then terminate with nonzero rc"""
- log(message)
-
- # If we haven't yet called status() (we don't yet have a FRAME), perform a
- # bit of trickery to bypass the spurious "main window" that Tkinter would
- # otherwise pop up if the first call is showerror().
- if not FRAME:
- root = Tkinter.Tk()
- root.withdraw()
-
- # If we do have a LOGF available, mention it in the error box.
- if LOGF:
- message = "%s\n(Updater log in %s)" % (message, LOGF.name)
-
- # We explicitly specify the WARNING icon because, at least on the Tkinter
- # bundled with the system-default Python 2.7 on Mac OS X 10.7.4, the
- # ERROR, QUESTION and INFO icons are all the silly Tk rocket ship. At
- # least WARNING has an exclamation in a yellow triangle, even though
- # overlaid by a smaller image of the rocket ship.
- tkMessageBox.showerror(TITLE,
-"""An error occurred while updating Second Life:
-%s
-Please download the latest viewer from www.secondlife.com.""" % message,
- icon=tkMessageBox.WARNING)
- sys.exit(1)
-
-def exception(err):
- """call fail() with an exception instance"""
- fail("%s exception: %s" % (err.__class__.__name__, str(err)))
-
-def excepthook(type, value, traceback):
- """
- Store this hook function into sys.excepthook until we have a logfile.
- """
- # At least in older Python versions, it could be tricky to produce a
- # string from 'type' and 'value'. For instance, an OSError exception would
- # pass type=OSError and value=some_tuple. Empirically, this funky
- # expression seems to work.
- exception(type(*value))
-sys.excepthook = excepthook
-
-class ExceptHook(object):
- """
- Store an instance of this class into sys.excepthook once we have a logfile
- open.
- """
- def __init__(self, logfile):
- # There's no magic to the cgitb.enable() function -- it merely stores
- # an instance of cgitb.Hook into sys.excepthook, passing enable()'s
- # params into Hook.__init__(). Sadly, enable() doesn't forward all its
- # params using (*args, **kwds) syntax -- another story. But the point
- # is that all the goodness is in the cgitb.Hook class. Capture an
- # instance.
- self.hook = cgitb.Hook(file=logfile, format="text")
-
- def __call__(self, type, value, traceback):
- # produce nice text traceback to logfile
- self.hook(type, value, traceback)
- # Now display an error box.
- excepthook(type, value, traceback)
-
-def write_marker(markerfile, markertext):
- log("writing %r to %s" % (markertext, markerfile))
- try:
- with open(markerfile, "w") as markerf:
- markerf.write(markertext)
- except IOError, err:
- # write_marker() is invoked by fail(), and fail() is invoked by other
- # error-handling functions. If we try to invoke any of those, we'll
- # get infinite recursion. If for any reason we can't write markerfile,
- # try to log it -- otherwise shrug.
- log("%s exception: %s" % (err.__class__.__name__, err))
-
-# ****************************************************************************
-# Utility
-# ****************************************************************************
-@contextmanager
-def allow_errno(errn):
- """
- Execute body of 'with' statement, accepting OSError with specific errno
- 'errn'. Propagate any other exception, or an OSError with any other errno.
- """
- try:
- # run the body of the 'with' statement
- yield
- except OSError, err:
- # unless errno == passed errn, re-raise the exception
- if err.errno != errn:
- raise
-
-# ****************************************************************************
-# Main script logic
-# ****************************************************************************
-def main(dmgfile, markerfile, markertext):
- # Should we fail, we're supposed to write 'markertext' to 'markerfile'.
- # Wrap the fail() function so we do that.
- global fail
- oldfail = fail
- def fail(message):
- write_marker(markerfile, markertext)
- oldfail(message)
-
- try:
- # Starting with the Cocoafied viewer, we'll find viewer logs in
- # ~/Library/Application Support/$CFBundleIdentifier/logs rather than in
- # ~/Library/Application Support/SecondLife/logs as before. This could be
- # obnoxious -- but we Happen To Know that markerfile is a path specified
- # within the viewer's logs directory. Use that.
- logsdir = os.path.dirname(markerfile)
-
- # Move the old updater.log file out of the way
- logname = os.path.join(logsdir, "updater.log")
- # Nonexistence is okay. Anything else, not so much.
- with allow_errno(errno.ENOENT):
- os.rename(logname, logname + ".old")
-
- # Open new updater.log.
- global LOGF
- LOGF = open(logname, "w")
-
- # Now that LOGF is in fact open for business, use it to log any further
- # uncaught exceptions.
- sys.excepthook = ExceptHook(LOGF)
-
- # log how this script was invoked
- log(' '.join(repr(arg) for arg in sys.argv))
-
- # prepare for other cleanup
- with Janitor(LOGF) as janitor:
-
- # Under some circumstances, this script seems to be invoked with a
- # nonexistent pathname. Check for that.
- if not os.path.isfile(dmgfile):
- fail(dmgfile + " has been deleted")
-
- # Try to derive the name of the running viewer app bundle from our
- # own pathname. (Hopefully the old viewer won't copy this script
- # to a temp dir before running!)
- # Somewhat peculiarly, this script is currently packaged in
- # Appname.app/Contents/MacOS with the viewer executable. But even
- # if we decide to move it to Appname.app/Contents/Resources, we'll
- # still find Appname.app two levels up from dirname(__file__).
- appdir = os.path.abspath(os.path.join(os.path.dirname(__file__),
- os.pardir, os.pardir))
- if not appdir.endswith(".app"):
- # This can happen if either this script has been copied before
- # being executed, or if it's in an unexpected place in the app
- # bundle.
- fail(appdir + " is not an application directory")
-
- # We need to install into appdir's parent directory -- can we?
- installdir = os.path.abspath(os.path.join(appdir, os.pardir))
- if not os.access(installdir, os.W_OK):
- fail("Can't modify " + installdir)
-
- # invent a temporary directory
- tempdir = tempfile.mkdtemp()
- log("created " + tempdir)
- # clean it up when we leave
- janitor.later(shutil.rmtree, tempdir)
-
- status("Mounting image...")
-
- mntdir = os.path.join(tempdir, "mnt")
- log("mkdir " + mntdir)
- os.mkdir(mntdir)
- command = ["hdiutil", "attach", dmgfile, "-mountpoint", mntdir]
- log(' '.join(command))
- # Instantiating subprocess.Popen launches a child process with the
- # specified command line. stdout=PIPE passes a pipe to its stdout.
- hdiutil = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=LOGF)
- # Popen.communicate() reads that pipe until the child process
- # terminates, returning (stdout, stderr) output. Select just stdout.
- hdiutil_out = hdiutil.communicate()[0]
- if hdiutil.returncode != 0:
- fail("Couldn't mount " + dmgfile)
- # hdiutil should report the devnode. Find that.
- found = re.search(r"/dev/[^ ]*\b", hdiutil_out)
- if not found:
- # If we don't spot the devnode, log it and continue -- we only
- # use it to detach it. Don't fail the whole update if we can't
- # clean up properly.
- log("Couldn't spot devnode in hdiutil output:\n" + hdiutil_out)
- else:
- # If we do spot the devnode, detach it when done.
- janitor.later(subprocess.call, ["hdiutil", "detach", found.group(0)],
- stdout=LOGF, stderr=subprocess.STDOUT)
-
- status("Searching for app bundle...")
-
- for candidate in glob.glob(os.path.join(mntdir, "*.app")):
- log("Considering " + candidate)
- try:
- # By convention, a valid Mac app bundle has a
- # Contents/Info.plist file containing at least
- # CFBundleIdentifier.
- CFBundleIdentifier = \
- plistlib.readPlist(os.path.join(candidate, "Contents",
- "Info.plist"))["CFBundleIdentifier"]
- except Exception, err:
- # might be IOError, xml.parsers.expat.ExpatError, KeyError
- # Any of these means it's not a valid app bundle. Instead
- # of aborting, just skip this candidate and continue.
- log("%s not a valid app bundle: %s: %s" %
- (candidate, err.__class__.__name__, err))
- continue
-
- if CFBundleIdentifier == BUNDLE_IDENTIFIER:
- break
-
- log("unrecognized CFBundleIdentifier: " + CFBundleIdentifier)
-
- else:
- fail("Could not find Second Life viewer in " + dmgfile)
-
- # Here 'candidate' is the new viewer to install
- log("Found " + candidate)
-
- # This logic was changed to make Mac updates behave more like
- # Windows. Most of the time, the user doesn't change the name of
- # the app bundle on our .dmg installer (e.g. "Second Life Beta
- # Viewer.app"). Most of the time, the version manager directs a
- # given viewer to update to another .dmg containing an app bundle
- # with THE SAME name. In that case, everything behaves as usual.
-
- # The case that was changed is when the version manager offers (or
- # mandates) an update to a .dmg containing a different app bundle
- # name. This can happen, for instance, to a user who's downloaded
- # a "project beta" viewer, and the project subsequently publishes
- # a Release Candidate viewer. Say the project beta's app bundle
- # name is something like "Second Life Beta Neato.app". Anyone
- # launching that viewer will be offered an update to the
- # corresponding Release Candidate viewer -- which will be built as
- # a release viewer, with app bundle name "Second Life Viewer.app".
-
- # On Windows, we run the NSIS installer, which will update/replace
- # the embedded install directory name, e.g. Second Life Viewer.
- # But the Mac installer used to locate the app bundle name in the
- # mounted .dmg file, then ignore that name, copying its contents
- # into the app bundle directory of the running viewer. That is,
- # we'd install the Release Candidate from the .dmg's "Second
- # Life.app" into "/Applications/Second Life Beta Neato.app". This
- # is undesired behavior.
-
- # Instead, having found the app bundle name on the mounted .dmg,
- # we try to install that app bundle name into the parent directory
- # of the running app bundle.
-
- # Are we installing a different app bundle name? If so, call it
- # out, both in the log and for the user -- this is an odd case.
- # (Presumably they've already agreed to a similar notification in
- # the viewer before the viewer launched this script, but still.)
- bundlename = os.path.basename(candidate)
- if os.path.basename(appdir) == bundlename:
- # updating the running app bundle, which we KNOW exists
- appexists = True
- else:
- # installing some other app bundle
- newapp = os.path.join(installdir, bundlename)
- appexists = os.path.exists(newapp)
- message = "Note: %s %s %s" % \
- (appdir, "updating" if appexists else "installing new", newapp)
- status(message)
- # okay, we have no further need of the name of the running app
- # bundle.
- appdir = newapp
-
- status("Preparing to copy files...")
-
- if appexists:
- # move old viewer to temp location in case copy from .dmg fails
- aside = os.path.join(tempdir, os.path.basename(appdir))
- log("mv %r %r" % (appdir, aside))
- # Use shutil.move() instead of os.rename(). move() first tries
- # os.rename(), but falls back to shutil.copytree() if the dest is
- # on a different filesystem.
- shutil.move(appdir, aside)
-
- status("Copying files...")
-
- # shutil.copytree()'s target must not already exist. But we just
- # moved appdir out of the way.
- log("cp -p %r %r" % (candidate, appdir))
- try:
- # The viewer app bundle does include internal symlinks. Keep them
- # as symlinks.
- shutil.copytree(candidate, appdir, symlinks=True)
- except Exception, err:
- # copy failed -- try to restore previous viewer before crumping
- type, value, traceback = sys.exc_info()
- if appexists:
- log("exception response: mv %r %r" % (aside, appdir))
- shutil.move(aside, appdir)
- # let our previously-set sys.excepthook handle this
- raise type, value, traceback
-
- status("Cleaning up...")
-
- log("touch " + appdir)
- os.utime(appdir, None) # set to current time
-
- # MAINT-3331: remove STATE_DIR. Empirically, this resolves a
- # persistent, mysterious crash after updating our viewer on an OS
- # X 10.7.5 system.
- log("rm -rf '%s'" % STATE_DIR)
- with allow_errno(errno.ENOENT):
- shutil.rmtree(STATE_DIR)
-
- command = ["open", appdir]
- log(' '.join(command))
- subprocess.check_call(command, stdout=LOGF, stderr=subprocess.STDOUT)
-
- # If all the above succeeded, delete the .dmg file. We don't do this
- # as a janitor.later() operation because we only want to do it if we
- # get this far successfully. Note that this is out of the scope of the
- # Janitor: we must detach the .dmg before removing it!
- log("rm " + dmgfile)
- os.remove(dmgfile)
-
- except Exception, err:
- # Because we carefully set sys.excepthook -- and even modify it to log
- # the problem once we have our log file open -- you might think we
- # could just let exceptions propagate. But when we do that, on
- # exception in this block, we FIRST restore the no-side-effects fail()
- # and THEN implicitly call sys.excepthook(), which calls the (no-side-
- # effects) fail(). Explicitly call sys.excepthook() BEFORE restoring
- # fail(). Only then do we get the enriched fail() behavior.
- sys.excepthook(*sys.exc_info())
-
- finally:
- # When we leave main() -- for whatever reason -- reset fail() the way
- # it was before, because the bound markerfile, markertext params
- # passed to this main() call are no longer applicable.
- fail = oldfail
-
-if __name__ == "__main__":
- # We expect this script to be invoked with:
- # - the pathname to the .dmg we intend to install;
- # - the pathname to an update-error marker file to create on failure;
- # - the content to write into the marker file.
- main(*sys.argv[1:])
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
deleted file mode 100755
index 03089f192e..0000000000
--- a/indra/viewer_components/updater/scripts/linux/update_install
+++ /dev/null
@@ -1,220 +0,0 @@
-#! /bin/bash
-
-# @file update_install
-# @author Nat Goodspeed
-# @date 2013-01-09
-# @brief Update the containing Second Life application bundle to the version in
-# the specified tarball.
-#
-# This bash implementation is derived from the previous linux-updater.bin
-# application.
-#
-# $LicenseInfo:firstyear=2013&license=viewerlgpl$
-# Copyright (c) 2013, Linden Research, Inc.
-# $/LicenseInfo$
-
-# ****************************************************************************
-# script parameters
-# ****************************************************************************
-tarball="$1" # the file to install
-markerfile="$2" # create this file on failure
-mandatory="$3" # what to write to markerfile on failure
-
-# ****************************************************************************
-# helper functions
-# ****************************************************************************
-# empty array
-cleanups=()
-
-# add a cleanup action to execute on exit
-function cleanup {
- # wacky bash syntax for appending to array
- cleanups[${#cleanups[*]}]="$*"
-}
-
-# called implicitly on exit
-function onexit {
- for action in "${cleanups[@]}"
- do # don't quote, support actions consisting of multiple words
- $action
- done
-}
-trap 'onexit' EXIT
-
-# write to log file
-function log {
- # our log file will be open as stderr -- but until we set up that
- # redirection, logging to stderr is better than nothing
- echo "$*" 1>&2
-}
-
-# We display status by leaving one background xmessage process running. This
-# is the pid of that process.
-statuspid=""
-
-function clear_message {
- [ -n "$statuspid" ] && kill $statuspid
- statuspid=""
-}
-
-# make sure we remove any message box we might have put up
-cleanup clear_message
-
-# can we use zenity, or must we fall back to xmessage?
-zenpath="$(which zenity)"
-if [ -n "$zenpath" ]
-then # zenity on PATH and is executable
- # display a message box and continue
- function status {
- # clear any previous message
- clear_message
- # put up a new zenity box and capture its pid
-## "$zenpath" --info --title "Second Life Viewer Updater" \
-## --width=320 --height=120 --text="$*" &
- # MAINT-2333: use bouncing progress bar
- "$zenpath" --progress --pulsate --no-cancel --title "Second Life Viewer Updater" \
- --width=320 --height=120 --text "$*" </dev/null &
- statuspid=$!
- }
-
- # display an error box and wait for user
- function errorbox {
- "$zenpath" --error --title "Second Life Viewer Updater" \
- --width=320 --height=120 --text="$*"
- }
-
-else # no zenity, use xmessage instead
- # display a message box and continue
- function status {
- # clear any previous message
- clear_message
- # put up a new xmessage and capture its pid
- xmessage -buttons OK:2 -center "$*" &
- statuspid=$!
- }
-
- # display an error box and wait for user
- function errorbox {
- xmessage -buttons OK:2 -center "$*"
- }
-fi
-
-# display an error box and terminate
-function fail {
- # Log the message
- log "$@"
- # tell subsequent viewer things went south
- echo "$mandatory" > "$markerfile"
- # add boilerplate
- errorbox "An error occurred while updating Second Life:
-$*
-Please download the latest viewer from www.secondlife.com."
- exit 1
-}
-
-# Find a graphical sudo program and define mysudo function. On error, $? is
-# nonzero; output is in $err instead of being written to stdout/stderr.
-gksudo="$(which gksudo)"
-kdesu="$(which kdesu)"
-if [ -n "$gksudo" ]
-then function mysudo {
- # gksudo allows you to specify description
- err="$("$gksudo" --description "Second Life Viewer Updater" "$@" 2>&1)"
- }
-elif [ -n "$kdesu" ]
-then function mysudo {
- err="$("$kdesu" "$@" 2>&1)"
- }
-else # couldn't find either one, just try it anyway
- function mysudo {
- err="$("$@" 2>&1)"
- }
-fi
-
-# Move directories, using mysudo if we think it necessary. On error, $? is
-# nonzero; output is in $err instead of being written to stdout/stderr.
-function sudo_mv {
- # If we have write permission to both parent directories, shouldn't need
- # sudo.
- if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ]
- then err="$(mv "$@" 2>&1)"
- else # use available sudo program; mysudo sets $? and $err
- mysudo mv "$@"
- fi
-}
-
-# ****************************************************************************
-# main script logic
-# ****************************************************************************
-mydir="$(dirname "$0")"
-# We happen to know that the viewer specifies a marker-file pathname within
-# the logs directory.
-logsdir="$(dirname "$markerfile")"
-logname="$logsdir/updater.log"
-
-# move aside old updater.log; we're about to create a new one
-[ -f "$logname" ] && mv "$logname" "$logname.old"
-
-# Set up redirections for this script such that stderr is logged. (But first
-# move the previous stderr to file descriptor 3.)
-exec 3>&2- 2> "$logname"
-
-# Rather than setting up a special pipeline to timestamp every line of stderr,
-# produce header lines into log file indicating timestamp and the arguments
-# with which we were invoked.
-date 1>&2
-log "$0 $*"
-
-# Log every command we execute, along with any stderr it might produce
-set -x
-
-status 'Installing Second Life...'
-
-# Creating tempdir under /tmp means it's possible that tempdir is on a
-# different filesystem than INSTALL_DIR. One is tempted to create tempdir on a
-# path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can
-# handle moving across filesystems??
-tempdir="$(mktemp -d)"
-tempinstall="$tempdir/install"
-# capture the actual error message, if any
-err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err"
-cleanup rm -rf "$tempdir"
-
-# If we already knew the name of the tarball's top-level directory, we could
-# just move that when all was said and done. Since we don't, untarring to the
-# 'install' subdir with --strip 1 effectively renames that top-level
-# directory.
-# untar failures tend to be voluminous -- don't even try to capture, just log
-tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed"
-
-INSTALL_DIR="$(cd "$mydir/.." ; pwd)"
-
-# Considering we're launched from a subdirectory of INSTALL_DIR, would be
-# surprising if it did NOT already exist...
-if [ -e "$INSTALL_DIR" ]
-then backup="$INSTALL_DIR.backup"
- backupn=1
- while [ -e "$backup" ]
- do backup="$INSTALL_DIR.backup.$backupn"
- ((backupn += 1))
- done
- # on error, fail with actual error message from sudo_mv: permissions,
- # cross-filesystem mv, ...?
- sudo_mv "$INSTALL_DIR" "$backup" || fail "$err"
-fi
-# We unpacked the tarball into tempinstall. Move that.
-if ! sudo_mv "$tempinstall" "$INSTALL_DIR"
-then # If we failed to move the temp install to INSTALL_DIR, try to restore
- # INSTALL_DIR from backup. Save $err because next sudo_mv will trash it!
- realerr="$err"
- sudo_mv "$backup" "$INSTALL_DIR"
- fail "$realerr"
-fi
-
-# Removing the tarball here, rather than with a 'cleanup' action, means we
-# only remove it if we succeeded.
-rm -f "$tarball"
-
-# Launch the updated viewer. Restore original stderr from file descriptor 3,
-# though -- otherwise updater.log gets cluttered with the viewer log!
-"$INSTALL_DIR/secondlife" 2>&3- &
diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat
deleted file mode 100644
index 96687226a8..0000000000
--- a/indra/viewer_components/updater/scripts/windows/update_install.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-start /WAIT %1 /SKIP_DIALOGS
-IF ERRORLEVEL 1 ECHO %3 > %2
-DEL %1
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
deleted file mode 100644
index 759e41ef4c..0000000000
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- * @file llupdaterservice_test.cpp
- * @brief Tests of llupdaterservice.cpp.
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "../llupdaterservice.h"
-#include "../llupdatechecker.h"
-#include "../llupdatedownloader.h"
-#include "../llupdateinstaller.h"
-
-#include "../../../test/lltut.h"
-//#define DEBUG_ON
-#include "../../../test/debug.h"
-
-#include "llevents.h"
-#include "lldir.h"
-
-/*****************************************************************************
-* MOCK'd
-*****************************************************************************/
-LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
-{}
-void LLUpdateChecker::checkVersion(std::string const & urlBase,
- std::string const & channel,
- std::string const & version,
- std::string const & platform,
- std::string const & platform_version,
- unsigned char uniqueid[MD5HEX_STR_SIZE],
- bool willing_to_test)
-{}
-LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
-void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, std::string const &, std::string const &, bool){}
-
-class LLDir_Mock : public LLDir
-{
- void initAppDirs(const std::string &app_name,
- const std::string& app_read_only_data_dir = "") {}
- U32 countFilesInDir(const std::string &dirname, const std::string &mask)
- {
- return 0;
- }
-
- void getRandomFileInDir(const std::string &dirname,
- const std::string &mask,
- std::string &fname) {}
- std::string getCurPath() { return ""; }
- bool fileExists(const std::string &filename) const { return false; }
- std::string getLLPluginLauncher() { return ""; }
- std::string getLLPluginFilename(std::string base_name) { return ""; }
-
-} gDirUtil;
-LLDir* gDirUtilp = &gDirUtil;
-LLDir::LLDir() {}
-LLDir::~LLDir() {}
-S32 LLDir::deleteFilesInDir(const std::string &dirname,
- const std::string &mask)
-{ return 0; }
-
-void LLDir::setChatLogsDir(const std::string &path){}
-void LLDir::setPerAccountChatLogsDir(const std::string &username){}
-void LLDir::setLindenUserDir(const std::string &username){}
-void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language){}
-std::string LLDir::getSkinFolder() const { return "default"; }
-std::string LLDir::getLanguage() const { return "en"; }
-bool LLDir::setCacheDir(const std::string &path){ return true; }
-void LLDir::dumpCurrentDirectories() {}
-void LLDir::updatePerAccountChatLogsDir() {}
-
-#include "llviewernetwork.h"
-LLGridManager::LLGridManager() :
- mGrid("test.grid.lindenlab.com"),
- mIsInProductionGrid(false)
-{
-}
-std::string LLGridManager::getUpdateServiceURL()
-{
- return "https://update.secondlife.com/update";
-}
-LLGridManager::~LLGridManager()
-{
-}
-
-
-std::string LLDir::getExpandedFilename(ELLPath location,
- const std::string &filename) const
-{
- return "";
-}
-
-std::string LLUpdateDownloader::downloadMarkerPath(void)
-{
- return "";
-}
-
-void LLUpdateDownloader::resume(void) {}
-void LLUpdateDownloader::cancel(void) {}
-void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) {}
-
-int ll_install_update(std::string const &, std::string const &, bool, LLInstallScriptMode)
-{
- return 0;
-}
-
-std::string const & ll_install_failed_marker_path()
-{
- static std::string wubba;
- return wubba;
-}
-
-/*
-#pragma warning(disable: 4273)
-llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename,
- ios_base::openmode _Mode,
- int _Prot) :
- std::basic_istream<char,std::char_traits< char > >(NULL,true)
-{}
-
-llus_mock_llifstream::~llus_mock_llifstream() {}
-bool llus_mock_llifstream::is_open() const {return true;}
-void llus_mock_llifstream::close() {}
-*/
-
-/*****************************************************************************
-* TUT
-*****************************************************************************/
-namespace tut
-{
- struct llupdaterservice_data
- {
- llupdaterservice_data() :
- pumps(LLEventPumps::instance()),
- test_url("dummy_url"),
- test_channel("dummy_channel"),
- test_version("dummy_version")
- {}
- LLEventPumps& pumps;
- std::string test_url;
- std::string test_channel;
- std::string test_version;
- };
-
- typedef test_group<llupdaterservice_data> llupdaterservice_group;
- typedef llupdaterservice_group::object llupdaterservice_object;
- llupdaterservice_group llupdaterservicegrp("LLUpdaterService");
-
- template<> template<>
- void llupdaterservice_object::test<1>()
- {
- DEBUG;
- LLUpdaterService updater;
- bool got_usage_error = false;
- try
- {
- updater.startChecking();
- }
- catch(LLUpdaterService::UsageError)
- {
- got_usage_error = true;
- }
- ensure("Caught start before params", got_usage_error);
- }
-
- template<> template<>
- void llupdaterservice_object::test<2>()
- {
- DEBUG;
- LLUpdaterService updater;
- bool got_usage_error = false;
- try
- {
- unsigned char id1[MD5HEX_STR_SIZE] = "11111111111111111111111111111111";
- updater.initialize(test_channel, test_version, "win", "1.2.3", id1, true);
- updater.startChecking();
- unsigned char id2[MD5HEX_STR_SIZE] = "22222222222222222222222222222222";
- updater.initialize(test_channel, test_version, "win", "4.5.6", id2, true);
- }
- catch(LLUpdaterService::UsageError)
- {
- got_usage_error = true;
- }
- ensure("Caught params while running", got_usage_error);
- }
-
- template<> template<>
- void llupdaterservice_object::test<3>()
- {
- DEBUG;
- LLUpdaterService updater;
- unsigned char id[MD5HEX_STR_SIZE] = "33333333333333333333333333333333";
- updater.initialize(test_channel, test_version, "win", "7.8.9", id, true);
- updater.startChecking();
- ensure(updater.isChecking());
- updater.stopChecking();
- ensure(!updater.isChecking());
- }
-}