diff options
43 files changed, 234 insertions, 4461 deletions
| diff --git a/autobuild.xml b/autobuild.xml index 0c0b5b39c4..350e6831cc 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2113,6 +2113,58 @@          <key>version</key>          <string>0.0.1</string>        </map> +      <key>llbase</key> +      <map> +        <key>copyright</key> +        <string>Copyright (c) 2010, Linden Research, Inc.</string> +        <key>license</key> +        <string>mit</string> +        <key>license_file</key> +        <string>LICENSES/llbase-license.txt</string> +        <key>name</key> +        <string>llbase</string> +        <key>platforms</key> +        <map> +          <key>darwin</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>13998879705aa1af36c6ea8f480901e3</string> +              <key>url</key> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/Darwin/installer/llbase-0.8.6.318106-darwin-318106.tar.bz2</string> +            </map> +            <key>name</key> +            <string>darwin</string> +          </map> +          <key>linux</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>80ef3f9f6bde28787b02837ace2ad84c</string> +              <key>url</key> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/Linux/installer/llbase-0.8.6.318106-linux-318106.tar.bz2</string> +            </map> +            <key>name</key> +            <string>linux</string> +          </map> +          <key>windows</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>57837daafa60f98a4d9fa4dfe53d995e</string> +              <key>url</key> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/CYGWIN/installer/llbase-0.8.6.0-windows-318106.tar.bz2</string> +            </map> +            <key>name</key> +            <string>windows</string> +          </map> +        </map> +        <key>version</key> +        <string>0.8.6.318106</string> +      </map>        <key>llphysicsextensions_source</key>        <map>          <key>copyright</key> @@ -2955,6 +3007,64 @@          <key>version</key>          <string>0.8.0.1</string>        </map> +      <key>viewer-manager</key> +      <map> +        <key>copyright</key> +        <string>Copyright (c) 2000-2012, Linden Research, Inc.</string> +        <key>description</key> +        <string>Linden Lab Viewer Management Process suite.</string> +        <key>license</key> +        <string>Proprietary</string> +        <key>license_file</key> +        <string>LICENSE</string> +        <key>name</key> +        <string>viewer-manager</string> +        <key>platforms</key> +        <map> +          <key>darwin64</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>db1da9e5c06338c2f37d781b42d41e54</string> +              <key>url</key> +              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3525/9029/viewer_manager-1.0-darwin64-503513.tar.bz2</string> +            </map> +            <key>name</key> +            <string>darwin64</string> +          </map> +          <key>linux</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>8c7f32f85850248809ae811ba8e47d81</string> +              <key>url</key> +              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3428/8686/viewer_manager-1.0-linux-503417.tar.bz2</string> +            </map> +            <key>name</key> +            <string>linux</string> +          </map> +          <key>windows</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>a431b47b3d6fd8798ae6f99867d8f058</string> +              <key>url</key> +              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3526/9035/viewer_manager-1.0-windows-503513.tar.bz2</string> +            </map> +            <key>name</key> +            <string>windows</string> +          </map> +        </map> +        <key>source</key> +        <string>https://bitbucket.org/lindenlab/vmp-standalone</string> +        <key>source_type</key> +        <string>hg</string> +        <key>version</key> +        <string>1.0</string> +      </map>        <key>vlc-bin</key>        <map>          <key>copyright</key> 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/cmake/ViewerManager.cmake b/indra/cmake/ViewerManager.cmake new file mode 100644 index 0000000000..793ed78b6c --- /dev/null +++ b/indra/cmake/ViewerManager.cmake @@ -0,0 +1,2 @@ +include (Prebuilt) +use_prebuilt_binary(viewer-manager)
\ No newline at end of file diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index f02c5e98b4..210e43b232 100755 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -312,7 +312,7 @@ if __name__ == "__main__":      import argparse      parser = argparse.ArgumentParser()      parser.add_argument("-d", "--debug", dest="loglevel", action="store_const", -                        const=logging.DEBUG, default=logging.WARNING) +                        const=logging.DEBUG, default=logging.INFO)      parser.add_argument("-D", "--define", dest="vars", default=[], action="append",                          metavar="VAR=value",                          help="Add VAR=value to the env variables defined") diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c4ded8c5ae..7a62d8baec 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) @@ -46,6 +47,7 @@ include(TemplateCheck)  include(UI)  include(UnixInstall)  include(ViewerMiscLibs) +include(ViewerManager)  include(VisualLeakDetector)  include(ZLIB)  include(URIPARSER) @@ -81,7 +83,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} @@ -1901,7 +1902,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 +2022,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 204a19da7f..5e1658590d 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", ¬ify_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. @@ -5739,142 +5505,6 @@ void LLAppViewer::handleLoginComplete()  	mSavePerAccountSettings=true;  } -void LLAppViewer::launchUpdater() -{ -		LLSD query_map = LLSD::emptyMap(); -	query_map["os"] = gPlatform; - -	// *TODO change userserver to be grid on both viewer and sim, since -	// userserver no longer exists. -	query_map["userserver"] = LLGridManager::getInstance()->getGridId(); -	query_map["channel"] = LLVersionInfo::getChannel(); -	// *TODO constantize this guy -	// *NOTE: This URL is also used in win_setup/lldownloader.cpp -	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map); -	 -	if(LLAppViewer::sUpdaterInfo) -	{ -		delete LLAppViewer::sUpdaterInfo; -	} -	LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ; - -	// if a sim name was passed in via command line parameter (typically through a SLURL) -	if ( LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION ) -	{ -		// record the location to start at next time -		gSavedSettings.setString( "NextLoginLocation", LLStartUp::getStartSLURL().getSLURLString());  -	}; - -#if LL_WINDOWS -	LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename(); -	if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty()) -	{ -		delete LLAppViewer::sUpdaterInfo ; -		LLAppViewer::sUpdaterInfo = NULL ; - -		// We're hosed, bail -		LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL; -		return; -	} - -	LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe"; - -	std::string updater_source = gDirUtilp->getAppRODataDir(); -	updater_source += gDirUtilp->getDirDelimiter(); -	updater_source += "updater.exe"; - -	LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source -			<< " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath -			<< LL_ENDL; - - -	if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE)) -	{ -		delete LLAppViewer::sUpdaterInfo ; -		LLAppViewer::sUpdaterInfo = NULL ; - -		LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL; - -		return; -	} - -	LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\""; - -	LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL; - -	//Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird. -	LLAppViewer::instance()->removeMarkerFiles(); // In case updater fails - -	// *NOTE:Mani The updater is spawned as the last thing before the WinMain exit. -	// see LLAppViewerWin32.cpp -	 -#elif LL_DARWIN -	LLAppViewer::sUpdaterInfo->mUpdateExePath = "'"; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir(); -	LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \""; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString(); -	LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \""; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle(); -	LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -bundleid \""; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += LL_VERSION_BUNDLE_ID; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &"; - -	LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL; - -	// Run the auto-updater. -	system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */ - -#elif (LL_LINUX || LL_SOLARIS) && LL_GTK -	// we tell the updater where to find the xml containing string -	// translations which it can use for its own UI -	std::string xml_strings_file = "strings.xml"; -	std::vector<std::string> xui_path_vec = -		gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_strings_file); -	std::string xml_search_paths; -	const char* delim = ""; -	// build comma-delimited list of xml paths to pass to updater -	BOOST_FOREACH(std::string this_skin_path, xui_path_vec) -	{ -		// Although we already have the full set of paths with the filename -		// appended, the linux-updater.bin command-line switches require us to -		// snip the filename OFF and pass it as a separate switch argument. :-P -		LL_INFOS() << "Got a XUI path: " << this_skin_path << LL_ENDL; -		xml_search_paths.append(delim); -		xml_search_paths.append(gDirUtilp->getDirName(this_skin_path)); -		delim = ","; -	} -	// build the overall command-line to run the updater correctly -	LLAppViewer::sUpdaterInfo->mUpdateExePath =  -		gDirUtilp->getExecutableDir() + "/" + "linux-updater.bin" +  -		" --url \"" + update_url.asString() + "\"" + -		" --name \"" + LLAppViewer::instance()->getSecondLifeTitle() + "\"" + -		" --dest \"" + gDirUtilp->getAppRODataDir() + "\"" + -		" --stringsdir \"" + xml_search_paths + "\"" + -		" --stringsfile \"" + xml_strings_file + "\""; - -	LL_INFOS("AppInit") << "Calling updater: "  -			    << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL; - -	// *TODO: we could use the gdk equivalent to ensure the updater -	// gets started on the same screen. -	GError *error = NULL; -	if (!g_spawn_command_line_async(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), &error)) -	{ -		LL_ERRS() << "Failed to launch updater: " -		       << error->message -		       << LL_ENDL; -	} -	if (error) { -		g_error_free(error); -	} -#else -	OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK); -#endif - -	// *REMOVE:Mani - Saving for reference... -	// LLAppViewer::instance()->forceQuit(); -} -  //virtual  void LLAppViewer::setMasterSystemAudioMute(bool mute)  { diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 16a00c8cee..c4782ed216 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,12 @@ 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 ; +        bool mIsFirstRun; -	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/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 375dce485d..bf9d98ee91 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -64,6 +64,7 @@ S32 LLVersionInfo::getPatch()  //static  S32 LLVersionInfo::getBuild()  { +    std::cout << "What we have IN llversioninfo: " << LL_VIEWER_VERSION_BUILD << std::endl;  	return LL_VIEWER_VERSION_BUILD;  } 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..3b7ec48d61 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -31,6 +31,9 @@  #include "../llviewernetwork.h"  #include "../lllogininstance.h" + // Needed for Auth Test + #include "../llhasheduniqueid.h" +  // STL headers  // std headers  // external library headers @@ -188,35 +191,6 @@ void LLUIColorTable::saveUserSettings(void)const {}  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 ""; } -  bool llHashedUniqueID(unsigned char* id)   {  	memcpy( id, "66666666666666666666666666666666", MD5HEX_STR_SIZE ); @@ -224,6 +198,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 +318,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 +455,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/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp index f1f69f33f1..2f7a4e9601 100644 --- a/indra/newview/tests/llversioninfo_test.cpp +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -29,6 +29,8 @@  #include "../llversioninfo.h" + #include <iostream> +  // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The  // macro expands to the string name of the channel, but without quotes. We  // need to turn it into a quoted string. This macro trick does that. @@ -81,7 +83,9 @@ namespace tut  	template<> template<>  	void versioninfo_object_t::test<1>() -	{ +	{    +		std::cout << "What we parsed from CMake: " << LL_VIEWER_VERSION_BUILD << std::endl; +		std::cout << "What we get from llversioninfo: " << LLVersionInfo::getBuild() << std::endl;  		ensure_equals("Major version",   					  LLVersionInfo::getMajor(),   					  LL_VIEWER_VERSION_MAJOR); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 3a8cd0c626..af97bb4728 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 @@ -222,7 +223,7 @@ class ViewerManifest(LLManifest):          return channel_type      def channel_variant_app_suffix(self): -        # get any part of the compiled channel name after the CHANNEL_VENDOR_BASE +        # get any part of the channel name after the CHANNEL_VENDOR_BASE          suffix=self.channel_variant()          # by ancient convention, we don't use Release in the app name          if self.channel_type() == 'release': @@ -341,17 +342,42 @@ class WindowsManifest(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") +        vmpdir = os.path.join(pkgdir, "VMP") +        llbasedir = os.path.join(pkgdir, "llbase")          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 scripts so that it gets included in the file_list +            self.path(src='%s/apply_update.exe' % vmpdir, dst="apply_update.exe") +            self.path(src='%s/download_update.exe' % vmpdir, dst="download_update.exe") +            self.path(src='%s/SL_Launcher.exe' % vmpdir, dst="SL_Launcher.exe") +            self.path(src='%s/update_manager.exe' % vmpdir, dst="update_manager.exe") + +            #IUM is not normally executed directly, just imported.  No exe needed. +            self.path2basename(vmpdir,"InstallerUserMessage.py") + +            #VMP  Tkinter icons +            if self.prefix("vmp_icons"): +                self.path("*.png") +                self.path("*.gif") +                self.end_prefix("vmp_icons") + +            #before, we only needed llbase at build time.  With VMP, we need it at run time. +            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(llbasedir,"*.py") +                self.path2basename(llbasedir,"_cllsd.so") +                self.end_prefix() +          # 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")          # Get shared libs from the shared libs staging directory          if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),                         dst=""): @@ -614,7 +640,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" @@ -686,7 +712,17 @@ class WindowsManifest(ViewerManifest):          if not python or python == "${PYTHON}":              python = 'python'          if os.path.exists(sign_py): +            print "about to run signing of: ", self.dst_path_of(installer_file).replace('\\', '\\\\\\\\')              self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of(installer_file).replace('\\', '\\\\\\\\'))) +            #Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. +            print "about to run signing of: ", self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\') +            self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\'))) +            print "about to run signing of: ", self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\') +            self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\'))) +            print "about to run signing of: ", self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\') +            self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\'))) +            print "about to run signing of: ", self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\') +            self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\')))          else:              print "Skipping code signing,", sign_py, "does not exist"          self.created_path(self.dst_path_of(installer_file)) @@ -715,17 +751,29 @@ 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") +        vmpdir = os.path.join(pkgdir, "VMP") +        llbasedir = os.path.join(pkgdir, "llbase")          if self.prefix(src="", dst="Contents"):  # everything goes in Contents              self.path("Info.plist", dst="Info.plist")              # copy additional libs in <bundle>/Contents/MacOS/              self.path(os.path.join(relpkgdir, "libndofdev.dylib"), dst="Resources/libndofdev.dylib") -            self.path(os.path.join(relpkgdir, "libhunspell-1.3.0.dylib"), dst="Resources/libhunspell-1.3.0.dylib") +            self.path(os.path.join(relpkgdir, "libhunspell-1.3.0.dylib"), dst="Resources/libhunspell-1.3.0.dylib")                 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(vmpdir,"SL_Launcher") +                self.path2basename(vmpdir,"*.py") +                llbase_path = os.path.join(self.get_dst_prefix(),'llbase') +                if not os.path.exists(llbase_path): +                    os.makedirs(llbase_path) +                #before, we only needed llbase at build time.  With VMP, we need it at run time. +                if self.prefix(dst="llbase"): +                    self.path2basename(llbasedir,"*.py") +                    self.path2basename(llbasedir,"_cllsd.so") +                    self.end_prefix() +                self.end_prefix()                # most everything goes in the Resources directory              if self.prefix(src="", dst="Resources"): @@ -744,6 +792,12 @@ class DarwinManifest(ViewerManifest):                      self.path("secondlife.icns")                      self.end_prefix(icon_path) +                #VMP Tkinter icons +                if self.prefix("vmp_icons"): +                    self.path("*.png") +                    self.path("*.gif") +                    self.end_prefix("vmp_icons") +                  self.path("SecondLife.nib")                  # Translations @@ -960,12 +1014,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. @@ -1150,8 +1198,16 @@ class LinuxManifest(ViewerManifest):          if self.prefix(src="", dst="bin"):              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") +            self.path2basename("../llplugin/slplugin", "SLPlugin")  +            #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("bin")          if self.prefix("res-sdl"): @@ -1190,12 +1246,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() @@ -1237,7 +1287,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.gifBinary files differ new file mode 100644 index 0000000000..c24d6b08cb --- /dev/null +++ b/indra/newview/vmp_icons/SL_Logo.gif diff --git a/indra/newview/vmp_icons/SL_Logo.png b/indra/newview/vmp_icons/SL_Logo.pngBinary files differ new file mode 100644 index 0000000000..5e376c72f9 --- /dev/null +++ b/indra/newview/vmp_icons/SL_Logo.png diff --git a/indra/newview/vmp_icons/head-sl-logo.gif b/indra/newview/vmp_icons/head-sl-logo.gifBinary files differ new file mode 100644 index 0000000000..d635348dcc --- /dev/null +++ b/indra/newview/vmp_icons/head-sl-logo.gif diff --git a/indra/newview/vmp_icons/head-sl-logo.png b/indra/newview/vmp_icons/head-sl-logo.pngBinary files differ new file mode 100644 index 0000000000..5c214e96d1 --- /dev/null +++ b/indra/newview/vmp_icons/head-sl-logo.png 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()); -	} -} | 
