summaryrefslogtreecommitdiff
path: root/indra/viewer_components
diff options
context:
space:
mode:
authorMark Palange (Mani) <palange@lindenlab.com>2010-11-10 14:28:54 -0800
committerMark Palange (Mani) <palange@lindenlab.com>2010-11-10 14:28:54 -0800
commit7eed962a6237f74ec980e06d53886259ef225c55 (patch)
tree6f90cd7736c74164f5cfaff071ecfc9f63b7a46f /indra/viewer_components
parentb2e84d739b4f5c00b497e57e892fc10d78af8b76 (diff)
parent9d33a548b636fa739de2aa11ba9ed02b301c53a5 (diff)
Merge
Diffstat (limited to 'indra/viewer_components')
-rw-r--r--indra/viewer_components/updater/CMakeLists.txt19
-rw-r--r--indra/viewer_components/updater/llupdatechecker.cpp14
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.cpp53
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.h3
-rw-r--r--indra/viewer_components/updater/llupdateinstaller.cpp38
-rw-r--r--indra/viewer_components/updater/llupdateinstaller.h42
-rw-r--r--indra/viewer_components/updater/scripts/darwin/update_install6
7 files changed, 151 insertions, 24 deletions
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 980599dd48..c5ccfbf66a 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -6,6 +6,7 @@ include(00-Common)
if(LL_TESTS)
include(LLAddBuildTest)
endif(LL_TESTS)
+include(CMakeCopyIfDifferent)
include(CURL)
include(LLCommon)
include(LLMessage)
@@ -24,12 +25,14 @@ 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}
@@ -49,7 +52,6 @@ target_link_libraries(llupdaterservice
${LLMESSAGE_LIBRARIES}
${LLPLUGIN_LIBRARIES}
${LLVFS_LIBRARIES}
- ${CURL_LIBRARIES}
)
if(LL_TESTS)
@@ -78,3 +80,18 @@ set(UPDATER_LIBRARIES
llupdaterservice
CACHE INTERNAL ""
)
+
+# Copy install script.
+if(DARWIN)
+ copy_if_different(
+ "${CMAKE_CURRENT_SOURCE_DIR}/scripts/darwin"
+ "${CMAKE_CURRENT_BINARY_DIR}"
+ update_installer_targets
+ "update_install"
+ )
+endif()
+add_custom_target(copy_update_install ALL DEPENDS ${update_installer_targets})
+add_dependencies(llupdaterservice copy_update_install)
+
+
+ \ No newline at end of file
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index d31244cc9b..c6aa9b0f11 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -70,7 +70,6 @@ private:
Client & mClient;
LLHTTPClient mHttpClient;
bool mInProgress;
- LLHTTPClient::ResponderPtr mMe;
std::string mVersion;
std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl,
@@ -109,8 +108,7 @@ const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.0";
LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
mClient(client),
- mInProgress(false),
- mMe(this)
+ mInProgress(false)
{
; // No op.
}
@@ -118,7 +116,7 @@ LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client
LLUpdateChecker::Implementation::~Implementation()
{
- mMe.reset(0);
+ ; // No op.
}
@@ -136,9 +134,11 @@ void LLUpdateChecker::Implementation::check(std::string const & protocolVersion,
// The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the
// passed object to be silently and automatically deleted. We pass a self-
- // referential intrusive pointer stored as an attribute of this class to keep
- // the client from deletig the update checker implementation instance.
- mHttpClient.get(checkUrl, mMe);
+ // referential intrusive pointer to which we add a reference to keep the
+ // client from deleting the update checker implementation instance.
+ LLHTTPClient::ResponderPtr temporaryPtr(this);
+ boost::intrusive_ptr_add_ref(temporaryPtr.get());
+ mHttpClient.get(checkUrl, temporaryPtr);
}
void LLUpdateChecker::Implementation::completed(U32 status,
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index efb55ab83a..208cc48c12 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -46,11 +46,12 @@ public:
void cancel(void);
void download(LLURI const & uri, std::string const & hash);
bool isDownloading(void);
- void onHeader(void * header, size_t size);
- void onBody(void * header, size_t size);
+ size_t onHeader(void * header, size_t size);
+ size_t onBody(void * header, size_t size);
void resume(void);
private:
+ bool mCancelled;
LLUpdateDownloader::Client & mClient;
CURL * mCurl;
LLSD mDownloadData;
@@ -137,25 +138,23 @@ namespace {
size_t write_function(void * data, size_t blockSize, size_t blocks, void * downloader)
{
size_t bytes = blockSize * blocks;
- reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onBody(data, bytes);
- return bytes;
+ 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;
- reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes);
- return bytes;
+ return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes);
}
}
LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client):
LLThread("LLUpdateDownloader"),
+ mCancelled(false),
mClient(client),
- mCurl(0),
- mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath())
+ mCurl(0)
{
CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
llverify(code == CURLE_OK); // TODO: real error handling here.
@@ -164,20 +163,27 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
LLUpdateDownloader::Implementation::~Implementation()
{
+ if(isDownloading()) {
+ cancel();
+ shutdown();
+ } else {
+ ; // No op.
+ }
if(mCurl) curl_easy_cleanup(mCurl);
}
void LLUpdateDownloader::Implementation::cancel(void)
{
- llassert(!"not implemented");
+ mCancelled = true;
}
void LLUpdateDownloader::Implementation::download(LLURI const & uri, std::string const & hash)
{
if(isDownloading()) mClient.downloadError("download in progress");
-
+
+ mDownloadRecordPath = downloadMarkerPath();
mDownloadData = LLSD();
try {
startDownloading(uri, hash);
@@ -195,6 +201,9 @@ bool LLUpdateDownloader::Implementation::isDownloading(void)
void LLUpdateDownloader::Implementation::resume(void)
{
+ if(isDownloading()) mClient.downloadError("download in progress");
+
+ mDownloadRecordPath = downloadMarkerPath();
llifstream dataStream(mDownloadRecordPath);
if(!dataStream) {
mClient.downloadError("no download marker");
@@ -230,12 +239,12 @@ void LLUpdateDownloader::Implementation::resume(void)
}
-void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
+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; // HTML response; ignore.
+ if(colonPosition == std::string::npos) return size; // HTML response; ignore.
if(header.substr(0, colonPosition) == "Content-Length") {
try {
@@ -255,20 +264,26 @@ void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
} else {
; // No op.
}
+
+ return size;
}
-void LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
+size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
{
+ if(mCancelled) return 0; // Forces a write error which will halt curl thread.
+
mDownloadStream.write(reinterpret_cast<const char *>(buffer), size);
+ return size;
}
void LLUpdateDownloader::Implementation::run(void)
{
CURLcode code = curl_easy_perform(mCurl);
- LLFile::remove(mDownloadRecordPath);
+ mDownloadStream.close();
if(code == CURLE_OK) {
+ LLFile::remove(mDownloadRecordPath);
if(validateDownload()) {
LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
mClient.downloadComplete(mDownloadData);
@@ -278,9 +293,13 @@ void LLUpdateDownloader::Implementation::run(void)
if(filePath.size() != 0) LLFile::remove(filePath);
mClient.downloadError("failed hash check");
}
+ } else if(mCancelled && (code == CURLE_WRITE_ERROR)) {
+ LL_INFOS("UpdateDownload") << "download canceled by user" << LL_ENDL;
+ // Do not call back client.
} else {
LL_WARNS("UpdateDownload") << "download failed with error '" <<
curl_easy_strerror(code) << "'" << LL_ENDL;
+ LLFile::remove(mDownloadRecordPath);
mClient.downloadError("curl error");
}
}
@@ -370,7 +389,7 @@ void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code)
bool LLUpdateDownloader::Implementation::validateDownload(void)
{
std::string filePath = mDownloadData["path"].asString();
- llifstream fileStream(filePath);
+ llifstream fileStream(filePath, std::ios_base::in | std::ios_base::binary);
if(!fileStream) return false;
std::string hash = mDownloadData["hash"].asString();
@@ -378,6 +397,10 @@ bool LLUpdateDownloader::Implementation::validateDownload(void)
LL_INFOS("UpdateDownload") << "checking hash..." << LL_ENDL;
char digest[33];
LLMD5(fileStream).hex_digest(digest);
+ if(hash != digest) {
+ LL_WARNS("UpdateDownload") << "download hash mismatch; expeted " << hash <<
+ " but download is " << digest << LL_ENDL;
+ }
return hash == digest;
} else {
return true; // No hash check provided.
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index fb628c99eb..1b3d7480fd 100644
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -47,7 +47,8 @@ public:
LLUpdateDownloader(Client & client);
- // Cancel any in progress download; a no op if none is in progress.
+ // 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.
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
new file mode 100644
index 0000000000..1bb2101df1
--- /dev/null
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -0,0 +1,38 @@
+/**
+ * @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 "llprocesslauncher.h"
+#include "llupdateinstaller.h"
+
+
+void ll_install_update(std::string const & script, std::string const & updatePath)
+{
+ LLProcessLauncher launcher;
+ launcher.setExecutable(script);
+ launcher.addArgument(updatePath);
+ launcher.launch();
+ launcher.orphan();
+}
diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h
new file mode 100644
index 0000000000..991fe2afe1
--- /dev/null
+++ b/indra/viewer_components/updater/llupdateinstaller.h
@@ -0,0 +1,42 @@
+/**
+ * @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>
+
+
+//
+// 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.
+//
+void ll_install_update(std::string const & script, std::string const & updatePath);
+
+
+#endif
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install
new file mode 100644
index 0000000000..24d344ca52
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/darwin/update_install
@@ -0,0 +1,6 @@
+#! /bin/bash
+
+hdiutil attach -nobrowse $1
+cp -R /Volumes/Second\ Life\ Installer/Second\ Life\ Viewer\ 2.app /Applications
+hdiutil detach /Volumes/Second\ Life\ Installer
+open /Applications/Second\ Life\ Viewer\ 2.app \ No newline at end of file