diff options
| author | Nat Goodspeed <nat@lindenlab.com> | 2017-10-11 14:35:49 -0400 | 
|---|---|---|
| committer | Nat Goodspeed <nat@lindenlab.com> | 2017-10-11 14:35:49 -0400 | 
| commit | 0c7bc67814dd4fa347401c24ba0e1be78e4b838f (patch) | |
| tree | 450fc1ce0aff2f2880c32b3ca85161ca0ceff8a6 /indra/viewer_components | |
| parent | b6d22de58850fc9a5b34eeb5b7930e5845bfc42d (diff) | |
| parent | 25be14381e29481413c94edf5436c0af715a1578 (diff) | |
Automated merge with ssh://bitbucket.org/lindenlab/viewer-release
Diffstat (limited to 'indra/viewer_components')
18 files changed, 10 insertions, 3199 deletions
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..b0863a7f25 --- /dev/null +++ b/indra/viewer_components/Resources/README @@ -0,0 +1,9 @@ +This directory only exists as a place for the build_data.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 1665e41e70..0000000000 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ /dev/null @@ -1,761 +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; -	 -	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; -	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); -} - -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); -	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(); -	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); -} - -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()); -	} -}  | 
