From 0b9cd83642f297687989b0813a9dca83cc78cc15 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Mon, 25 Oct 2010 14:53:58 -0700
Subject: CHOP-122 Adding stub background updater files to the build. Rev. by
 brad

---
 indra/viewer_components/CMakeLists.txt             |  2 +-
 indra/viewer_components/updater/CMakeLists.txt     | 51 +++++++++++++++++++
 .../viewer_components/updater/llupdaterservice.cpp | 58 +++++++++++++++++++++
 indra/viewer_components/updater/llupdaterservice.h | 46 +++++++++++++++++
 .../updater/tests/llupdaterservice_test.cpp        | 59 ++++++++++++++++++++++
 5 files changed, 215 insertions(+), 1 deletion(-)
 create mode 100644 indra/viewer_components/updater/CMakeLists.txt
 create mode 100644 indra/viewer_components/updater/llupdaterservice.cpp
 create mode 100644 indra/viewer_components/updater/llupdaterservice.h
 create mode 100644 indra/viewer_components/updater/tests/llupdaterservice_test.cpp

(limited to 'indra')

diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt
index 0993b64b14..74c9b4568d 100644
--- a/indra/viewer_components/CMakeLists.txt
+++ b/indra/viewer_components/CMakeLists.txt
@@ -1,4 +1,4 @@
 # -*- cmake -*-
 
 add_subdirectory(login)
-
+add_subdirectory(updater)
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
new file mode 100644
index 0000000000..4dc5424142
--- /dev/null
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -0,0 +1,51 @@
+# -*- cmake -*-
+
+project(updater_service)
+
+include(00-Common)
+if(LL_TESTS)
+  include(LLAddBuildTest)
+endif(LL_TESTS)
+include(LLCommon)
+
+include_directories(
+    ${LLCOMMON_INCLUDE_DIRS}
+    )
+
+set(updater_service_SOURCE_FILES
+    llupdaterservice.cpp
+    )
+
+set(updater_service_HEADER_FILES
+    llupdaterservice.h
+    )
+
+set_source_files_properties(${updater_service_HEADER_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND 
+    updater_service_SOURCE_FILES 
+    ${updater_service_HEADER_FILES} 
+    )
+
+add_library(llupdaterservice
+            ${updater_service_SOURCE_FILES}
+            )
+
+target_link_libraries(llupdaterservice
+    ${LLCOMMON_LIBRARIES}
+    )
+
+if(LL_TESTS)
+  SET(llupdater_service_TEST_SOURCE_FILES
+      llupdaterservice.cpp
+      )
+
+#  set_source_files_properties(
+#    llupdaterservice.cpp
+#    PROPERTIES
+#      LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}"
+#    )
+
+  LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}")
+endif(LL_TESTS)
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
new file mode 100644
index 0000000000..14906bcef8
--- /dev/null
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -0,0 +1,58 @@
+/** 
+ * @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"
+
+LLUpdaterService::LLUpdaterService()
+{
+}
+
+LLUpdaterService::~LLUpdaterService()
+{
+}
+
+void LLUpdaterService::setURL(const std::string& url)
+{
+}
+
+void LLUpdaterService::setChannel(const std::string& channel)
+{
+}
+
+void LLUpdaterService::setVersion(const std::string& version)
+{
+}
+	
+void LLUpdaterService::setUpdateCheckFrequency(unsigned int seconds)
+{
+}
+	
+void LLUpdaterService::startChecking()
+{
+}
+
+void LLUpdaterService::stopChecking()
+{
+}
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
new file mode 100644
index 0000000000..7836c2cf7f
--- /dev/null
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -0,0 +1,46 @@
+/** 
+ * @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
+
+class LLUpdaterService
+{
+	LLUpdaterService();
+	~LLUpdaterService();
+
+	// The base URL.
+	// *NOTE:Mani The grid, if any, would be embedded in the base URL.
+	void setURL(const std::string& url);
+	void setChannel(const std::string& channel);
+	void setVersion(const std::string& version);
+	
+	void setUpdateCheckFrequency(unsigned int seconds);
+	
+	void startChecking();
+	void stopChecking();
+}
+
+#endif LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
new file mode 100644
index 0000000000..37d1c8243e
--- /dev/null
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -0,0 +1,59 @@
+/**
+ * @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 "../../../test/lltut.h"
+//#define DEBUG_ON
+#include "../../../test/debug.h"
+
+/*****************************************************************************
+*   TUT
+*****************************************************************************/
+namespace tut
+{
+    struct llupdaterservice_data
+    {
+		llupdaterservice_data() :
+            pumps(LLEventPumps::instance())
+		{}
+		LLEventPumps& pumps;
+	};
+
+    typedef test_group<llupdaterservice_data> llupdaterservice_group;
+    typedef llviewerlogin_group::object llupdaterservice_object;
+    llupdaterservice_group llupdaterservicegrp("LLUpdaterService");
+
+    template<> template<>
+    void llupdateservice_object::test<1>()
+    {
+        DEBUG;
+		ensure_equals("Dummy", "true", "true");
+	}
+}
-- 
cgit v1.2.3


From 34db27c26f9a5627b733cc8a04265afed68d199c Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Tue, 26 Oct 2010 15:00:34 -0700
Subject: CHOP-122 Mowr work on the llupdater facade... Added
 LLPluginProcessParent, including mockery for unit tests. Re. by Jenn

---
 indra/viewer_components/updater/CMakeLists.txt     |   6 ++
 .../viewer_components/updater/llupdaterservice.cpp | 120 ++++++++++++++++++++-
 indra/viewer_components/updater/llupdaterservice.h |  10 +-
 .../updater/tests/llupdaterservice_test.cpp        |  28 ++++-
 4 files changed, 158 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 4dc5424142..df9404474c 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -7,9 +7,13 @@ if(LL_TESTS)
   include(LLAddBuildTest)
 endif(LL_TESTS)
 include(LLCommon)
+include(LLMessage)
+include(LLPlugin)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLMESSAGE_INCLUDE_DIRS}
+    ${LLPLUGIN_INCLUDE_DIRS}
     )
 
 set(updater_service_SOURCE_FILES
@@ -34,6 +38,8 @@ add_library(llupdaterservice
 
 target_link_libraries(llupdaterservice
     ${LLCOMMON_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLPLUGIN_LIBRARIES}
     )
 
 if(LL_TESTS)
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 14906bcef8..6c7619a2b9 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -25,6 +25,118 @@
 
 #include "linden_common.h"
 
+#include "llupdaterservice.h"
+
+#include "llsingleton.h"
+#include "llpluginprocessparent.h"
+#include <boost/scoped_ptr.hpp>
+
+class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, 
+							 public LLSingleton<LLUpdaterServiceImpl>
+{
+	std::string mUrl;
+	std::string mChannel;
+	std::string mVersion;
+	
+	unsigned int mUpdateCheckPeriod;
+	bool mIsChecking;
+	boost::scoped_ptr<LLPluginProcessParent> mPlugin;
+
+public:
+	LLUpdaterServiceImpl();
+	virtual ~LLUpdaterServiceImpl() {}
+
+	// LLPluginProcessParentOwner interfaces
+	virtual void receivePluginMessage(const LLPluginMessage &message);
+	virtual bool receivePluginMessageEarly(const LLPluginMessage &message);
+	virtual void pluginLaunchFailed();
+	virtual void pluginDied();
+
+	void setURL(const std::string& url);
+	void setChannel(const std::string& channel);
+	void setVersion(const std::string& version);
+	void setUpdateCheckPeriod(unsigned int seconds);
+	void startChecking();
+	void stopChecking();
+};
+
+LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
+	mIsChecking(false),
+	mUpdateCheckPeriod(0),
+	mPlugin(0)
+{
+	// Create the plugin parent, this is the owner.
+	mPlugin.reset(new LLPluginProcessParent(this));
+}
+
+// LLPluginProcessParentOwner interfaces
+void LLUpdaterServiceImpl::receivePluginMessage(const LLPluginMessage &message)
+{
+}
+
+bool LLUpdaterServiceImpl::receivePluginMessageEarly(const LLPluginMessage &message) 
+{
+	return false;
+};
+
+void LLUpdaterServiceImpl::pluginLaunchFailed() 
+{
+};
+
+void LLUpdaterServiceImpl::pluginDied() 
+{
+};
+
+void LLUpdaterServiceImpl::setURL(const std::string& url)
+{
+	if(mUrl != url)
+	{
+		mUrl = url;
+	}
+}
+
+void LLUpdaterServiceImpl::setChannel(const std::string& channel)
+{
+	if(mChannel != channel)
+	{
+		mChannel = channel;
+	}
+}
+
+void LLUpdaterServiceImpl::setVersion(const std::string& version)
+{
+	if(mVersion != version)
+	{
+		mVersion = version;
+	}
+}
+
+void LLUpdaterServiceImpl::setUpdateCheckPeriod(unsigned int seconds)
+{
+	if(mUpdateCheckPeriod != seconds)
+	{
+		mUpdateCheckPeriod = seconds;
+	}
+}
+
+void LLUpdaterServiceImpl::startChecking()
+{
+	if(!mIsChecking)
+	{
+		mIsChecking = true;
+	}
+}
+
+void LLUpdaterServiceImpl::stopChecking()
+{
+	if(mIsChecking)
+	{
+		mIsChecking = false;
+	}
+}
+
+//-----------------------------------------------------------------------
+// Facade interface
 LLUpdaterService::LLUpdaterService()
 {
 }
@@ -35,24 +147,30 @@ LLUpdaterService::~LLUpdaterService()
 
 void LLUpdaterService::setURL(const std::string& url)
 {
+	LLUpdaterServiceImpl::getInstance()->setURL(url);
 }
 
 void LLUpdaterService::setChannel(const std::string& channel)
 {
+	LLUpdaterServiceImpl::getInstance()->setChannel(channel);
 }
 
 void LLUpdaterService::setVersion(const std::string& version)
 {
+	LLUpdaterServiceImpl::getInstance()->setVersion(version);
 }
 	
-void LLUpdaterService::setUpdateCheckFrequency(unsigned int seconds)
+void LLUpdaterService::setUpdateCheckPeriod(unsigned int seconds)
 {
+	LLUpdaterServiceImpl::getInstance()->setUpdateCheckPeriod(seconds);
 }
 	
 void LLUpdaterService::startChecking()
 {
+	LLUpdaterServiceImpl::getInstance()->startChecking();
 }
 
 void LLUpdaterService::stopChecking()
 {
+	LLUpdaterServiceImpl::getInstance()->stopChecking();
 }
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 7836c2cf7f..33d0dc0816 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -28,6 +28,12 @@
 
 class LLUpdaterService
 {
+public:
+	class UsageError: public std::runtime_error
+	{
+		UsageError(const std::string& msg) : std::runtime_error(msg) {}
+	};
+
 	LLUpdaterService();
 	~LLUpdaterService();
 
@@ -37,10 +43,10 @@ class LLUpdaterService
 	void setChannel(const std::string& channel);
 	void setVersion(const std::string& version);
 	
-	void setUpdateCheckFrequency(unsigned int seconds);
+	void setUpdateCheckPeriod(unsigned int seconds);
 	
 	void startChecking();
 	void stopChecking();
-}
+};
 
 #endif LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 37d1c8243e..9edf15ba11 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -33,6 +33,28 @@
 //#define DEBUG_ON
 #include "../../../test/debug.h"
 
+#include "llevents.h"
+#include "llpluginprocessparent.h"
+
+/*****************************************************************************
+*   MOCK'd
+*****************************************************************************/
+LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {}
+LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
+: mOwner(owner),
+  mIncomingQueueMutex(NULL)
+{
+}
+
+LLPluginProcessParent::~LLPluginProcessParent() {}
+LLPluginMessagePipeOwner::LLPluginMessagePipeOwner(){}
+LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner(){}
+void LLPluginProcessParent::receiveMessageRaw(const std::string &message) {}
+int LLPluginMessagePipeOwner::socketError(int) { return 0; }
+void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {}
+void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {}
+LLPluginMessage::~LLPluginMessage() {}
+
 /*****************************************************************************
 *   TUT
 *****************************************************************************/
@@ -47,13 +69,13 @@ namespace tut
 	};
 
     typedef test_group<llupdaterservice_data> llupdaterservice_group;
-    typedef llviewerlogin_group::object llupdaterservice_object;
+    typedef llupdaterservice_group::object llupdaterservice_object;
     llupdaterservice_group llupdaterservicegrp("LLUpdaterService");
 
     template<> template<>
-    void llupdateservice_object::test<1>()
+    void llupdaterservice_object::test<1>()
     {
         DEBUG;
-		ensure_equals("Dummy", "true", "true");
+		ensure_equals("Dummy", 0, 0);
 	}
 }
-- 
cgit v1.2.3


From be8c9fc21758bcbc1d9f3d565b221310344231bd Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Wed, 27 Oct 2010 17:07:31 -0700
Subject: CHOP-122 Initializing Facade service in the viewer. Rev. by Brad.

---
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/app_settings/settings.xml            |  35 +++-
 indra/newview/llappviewer.cpp                      |  25 ++-
 indra/newview/llappviewer.h                        |  11 +-
 indra/newview/lltranslate.cpp                      |  12 +-
 indra/viewer_components/updater/CMakeLists.txt     |  10 ++
 .../viewer_components/updater/llupdaterservice.cpp | 107 +++++------
 indra/viewer_components/updater/llupdaterservice.h |  19 +-
 .../updater/tests/llupdaterservice_test.cpp        | 195 +++++++++++++--------
 9 files changed, 278 insertions(+), 138 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index bf885e5934..63982ba87b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -64,6 +64,7 @@ include_directories(
     ${LSCRIPT_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
     ${LLLOGIN_INCLUDE_DIRS}
+    ${UPDATER_INCLUDE_DIRS}
     )
 
 set(viewer_SOURCE_FILES
@@ -1679,6 +1680,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${OPENSSL_LIBRARIES}
     ${CRYPTO_LIBRARIES}
     ${LLLOGIN_LIBRARIES}
+    ${UPDATER_LIBRARIES}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     )
 
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 086d73bc00..371326c0f5 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10991,7 +10991,40 @@
       <key>Value</key>
       <integer>15</integer>
     </map>
-	<key>UploadBakedTexOld</key>
+    <key>UpdaterServiceActive</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable or disable the updater service.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>UpdaterServiceCheckPeriod</key>
+    <map>
+      <key>Comment</key>
+      <string>Default period between update checking.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>3600</integer>
+    </map>
+    <key>UpdaterServiceURL</key>
+    <map>
+      <key>Comment</key>
+      <string>Default location for the updater service.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>http://secondlife.com/app/update</string>
+    </map>
+    <key>UploadBakedTexOld</key>
     <map>
       <key>Comment</key>
       <string>Forces the baked texture pipeline to upload using the old method.</string>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 931b9fd2f3..e6feaae504 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -83,6 +83,7 @@
 
 #include "llweb.h"
 #include "llsecondlifeurls.h"
+#include "llupdaterservice.h"
 
 // Linden library includes
 #include "llavatarnamecache.h"
@@ -581,7 +582,8 @@ LLAppViewer::LLAppViewer() :
 	mAgentRegionLastAlive(false),
 	mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
 	mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
-	mFastTimerLogThread(NULL)
+	mFastTimerLogThread(NULL),
+	mUpdater(new LLUpdaterService())
 {
 	if(NULL != sInstance)
 	{
@@ -630,6 +632,9 @@ bool LLAppViewer::init()
 	if (!initConfiguration())
 		return false;
 
+	// Initialize updater service
+	initUpdater();
+
 	// write Google Breakpad minidump files to our log directory
 	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
 	logdir += gDirUtilp->getDirDelimiter();
@@ -2324,6 +2329,24 @@ bool LLAppViewer::initConfiguration()
 	return true; // Config was successful.
 }
 
+void LLAppViewer::initUpdater()
+{
+	// Initialize the updater service.
+	// Generate URL to the udpater service
+	// Get Channel
+	// Get Version
+	std::string url = gSavedSettings.getString("UpdaterServiceURL");
+	std::string channel = gSavedSettings.getString("VersionChannelName");
+	std::string version = LLVersionInfo::getVersion();
+	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
+
+	mUpdater->setParams(url, channel, version);
+	mUpdater->setCheckPeriod(check_period);
+	if(gSavedSettings.getBOOL("UpdaterServiceActive"))
+	{
+		mUpdater->startChecking();
+	}
+}
 
 void LLAppViewer::checkForCrash(void)
 {
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index fdc3b9ef9e..ea44ade8c6 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -39,7 +39,7 @@ class LLTextureCache;
 class LLImageDecodeThread;
 class LLTextureFetch;
 class LLWatchdogTimeout;
-class LLCommandLineParser;
+class LLUpdaterService;
 
 struct apr_dso_handle_t;
 
@@ -186,7 +186,7 @@ private:
 
 	bool initThreads(); // Initialize viewer threads, return false on failure.
 	bool initConfiguration(); // Initialize settings from the command line/config file.
-
+	void initUpdater(); // Initialize the updater service.
 	bool initCache(); // Initialize local client cache.
 
 
@@ -260,7 +260,13 @@ private:
 
 	std::set<struct apr_dso_handle_t*> mPlugins;
 
+	boost::scoped_ptr<LLUpdaterService> mUpdater;
+
+	//---------------------------------------------
+	//*NOTE: Mani - legacy updater stuff
+	// Still useable?
 public:
+
 	//some information for updater
 	typedef struct
 	{
@@ -270,6 +276,7 @@ public:
 	static LLUpdaterInfo *sUpdaterInfo ;
 
 	void launchUpdater();
+	//---------------------------------------------
 };
 
 // consts from viewer.h
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 050e34ade9..21467a2ab8 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -36,7 +36,7 @@
 
 #include "llbufferstream.h"
 #include "llui.h"
-#include "llversionviewer.h"
+#include "llversioninfo.h"
 #include "llviewercontrol.h"
 
 #include "jsoncpp/reader.h"
@@ -64,11 +64,11 @@ void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std
 	getTranslateUrl(url, from_lang, to_lang, mesg);
 
     std::string user_agent = llformat("%s %d.%d.%d (%d)",
-		LL_CHANNEL,
-		LL_VERSION_MAJOR,
-		LL_VERSION_MINOR,
-		LL_VERSION_PATCH,
-		LL_VERSION_BUILD );
+		LLVersionInfo::getChannel(),
+		LLVersionInfo::getMajor(),
+		LLVersionInfo::getMinor(),
+		LLVersionInfo::getPatch(),
+		LLVersionInfo::getBuild());
 
 	if (!m_Header.size())
 	{
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index df9404474c..a8a1d685f7 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -55,3 +55,13 @@ if(LL_TESTS)
 
   LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}")
 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/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 6c7619a2b9..28c942b5f2 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -27,18 +27,19 @@
 
 #include "llupdaterservice.h"
 
-#include "llsingleton.h"
 #include "llpluginprocessparent.h"
 #include <boost/scoped_ptr.hpp>
+#include <boost/weak_ptr.hpp>
 
-class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, 
-							 public LLSingleton<LLUpdaterServiceImpl>
+boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
+
+class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
 {
 	std::string mUrl;
 	std::string mChannel;
 	std::string mVersion;
 	
-	unsigned int mUpdateCheckPeriod;
+	unsigned int mCheckPeriod;
 	bool mIsChecking;
 	boost::scoped_ptr<LLPluginProcessParent> mPlugin;
 
@@ -52,17 +53,20 @@ public:
 	virtual void pluginLaunchFailed();
 	virtual void pluginDied();
 
-	void setURL(const std::string& url);
-	void setChannel(const std::string& channel);
-	void setVersion(const std::string& version);
-	void setUpdateCheckPeriod(unsigned int seconds);
+	void setParams(const std::string& url,
+				   const std::string& channel,
+				   const std::string& version);
+
+	void setCheckPeriod(unsigned int seconds);
+
 	void startChecking();
 	void stopChecking();
+	bool isChecking();
 };
 
 LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
-	mUpdateCheckPeriod(0),
+	mCheckPeriod(0),
 	mPlugin(0)
 {
 	// Create the plugin parent, this is the owner.
@@ -87,42 +91,35 @@ void LLUpdaterServiceImpl::pluginDied()
 {
 };
 
-void LLUpdaterServiceImpl::setURL(const std::string& url)
-{
-	if(mUrl != url)
-	{
-		mUrl = url;
-	}
-}
-
-void LLUpdaterServiceImpl::setChannel(const std::string& channel)
+void LLUpdaterServiceImpl::setParams(const std::string& url,
+									 const std::string& channel,
+									 const std::string& version)
 {
-	if(mChannel != channel)
-	{
-		mChannel = channel;
-	}
-}
-
-void LLUpdaterServiceImpl::setVersion(const std::string& version)
-{
-	if(mVersion != version)
+	if(mIsChecking)
 	{
-		mVersion = version;
+		throw LLUpdaterService::UsageError("Call LLUpdaterService::stopCheck()"
+			" before setting params.");
 	}
+		
+	mUrl = url;
+	mChannel = channel;
+	mVersion = version;
 }
 
-void LLUpdaterServiceImpl::setUpdateCheckPeriod(unsigned int seconds)
+void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
 {
-	if(mUpdateCheckPeriod != seconds)
-	{
-		mUpdateCheckPeriod = seconds;
-	}
+	mCheckPeriod = seconds;
 }
 
 void LLUpdaterServiceImpl::startChecking()
 {
 	if(!mIsChecking)
 	{
+		if(mUrl.empty() || mChannel.empty() || mVersion.empty())
+		{
+			throw LLUpdaterService::UsageError("Set params before call to "
+				"LLUpdaterService::startCheck().");
+		}
 		mIsChecking = true;
 	}
 }
@@ -135,42 +132,54 @@ void LLUpdaterServiceImpl::stopChecking()
 	}
 }
 
+bool LLUpdaterServiceImpl::isChecking()
+{
+	return mIsChecking;
+}
+
 //-----------------------------------------------------------------------
 // Facade interface
 LLUpdaterService::LLUpdaterService()
 {
+	if(gUpdater.expired())
+	{
+		mImpl = 
+			boost::shared_ptr<LLUpdaterServiceImpl>(new LLUpdaterServiceImpl());
+		gUpdater = mImpl;
+	}
+	else
+	{
+		mImpl = gUpdater.lock();
+	}
 }
 
 LLUpdaterService::~LLUpdaterService()
 {
 }
 
-void LLUpdaterService::setURL(const std::string& url)
-{
-	LLUpdaterServiceImpl::getInstance()->setURL(url);
-}
-
-void LLUpdaterService::setChannel(const std::string& channel)
+void LLUpdaterService::setParams(const std::string& url,
+								 const std::string& chan,
+								 const std::string& vers)
 {
-	LLUpdaterServiceImpl::getInstance()->setChannel(channel);
+	mImpl->setParams(url, chan, vers);
 }
 
-void LLUpdaterService::setVersion(const std::string& version)
-{
-	LLUpdaterServiceImpl::getInstance()->setVersion(version);
-}
-	
-void LLUpdaterService::setUpdateCheckPeriod(unsigned int seconds)
+void LLUpdaterService::setCheckPeriod(unsigned int seconds)
 {
-	LLUpdaterServiceImpl::getInstance()->setUpdateCheckPeriod(seconds);
+	mImpl->setCheckPeriod(seconds);
 }
 	
 void LLUpdaterService::startChecking()
 {
-	LLUpdaterServiceImpl::getInstance()->startChecking();
+	mImpl->startChecking();
 }
 
 void LLUpdaterService::stopChecking()
 {
-	LLUpdaterServiceImpl::getInstance()->stopChecking();
+	mImpl->stopChecking();
+}
+
+bool LLUpdaterService::isChecking()
+{
+	return mImpl->isChecking();
 }
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 33d0dc0816..6459ca49f8 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -26,11 +26,16 @@
 #ifndef LL_UPDATERSERVICE_H
 #define LL_UPDATERSERVICE_H
 
+#include <boost/shared_ptr.hpp>
+
+class LLUpdaterServiceImpl;
+
 class LLUpdaterService
 {
 public:
 	class UsageError: public std::runtime_error
 	{
+	public:
 		UsageError(const std::string& msg) : std::runtime_error(msg) {}
 	};
 
@@ -39,14 +44,18 @@ public:
 
 	// The base URL.
 	// *NOTE:Mani The grid, if any, would be embedded in the base URL.
-	void setURL(const std::string& url);
-	void setChannel(const std::string& channel);
-	void setVersion(const std::string& version);
-	
-	void setUpdateCheckPeriod(unsigned int seconds);
+	void setParams(const std::string& url, 
+				   const std::string& channel,
+				   const std::string& version);
+
+	void setCheckPeriod(unsigned int seconds);
 	
 	void startChecking();
 	void stopChecking();
+	bool isChecking();
+
+private:
+	boost::shared_ptr<LLUpdaterServiceImpl> mImpl;
 };
 
 #endif LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 9edf15ba11..73cf6ea6eb 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -1,50 +1,50 @@
-/**
- * @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 "../../../test/lltut.h"
-//#define DEBUG_ON
-#include "../../../test/debug.h"
-
-#include "llevents.h"
-#include "llpluginprocessparent.h"
-
-/*****************************************************************************
-*   MOCK'd
-*****************************************************************************/
-LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {}
-LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
-: mOwner(owner),
-  mIncomingQueueMutex(NULL)
-{
-}
+/**
+ * @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 "../../../test/lltut.h"
+//#define DEBUG_ON
+#include "../../../test/debug.h"
+
+#include "llevents.h"
+#include "llpluginprocessparent.h"
+
+/*****************************************************************************
+*   MOCK'd
+*****************************************************************************/
+LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {}
+LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
+: mOwner(owner),
+  mIncomingQueueMutex(gAPRPoolp)
+{
+}
 
 LLPluginProcessParent::~LLPluginProcessParent() {}
 LLPluginMessagePipeOwner::LLPluginMessagePipeOwner(){}
@@ -52,30 +52,77 @@ LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner(){}
 void LLPluginProcessParent::receiveMessageRaw(const std::string &message) {}
 int LLPluginMessagePipeOwner::socketError(int) { return 0; }
 void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {}
-void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {}
-LLPluginMessage::~LLPluginMessage() {}
-
-/*****************************************************************************
-*   TUT
-*****************************************************************************/
-namespace tut
-{
-    struct llupdaterservice_data
-    {
-		llupdaterservice_data() :
-            pumps(LLEventPumps::instance())
-		{}
-		LLEventPumps& pumps;
-	};
-
-    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;
-		ensure_equals("Dummy", 0, 0);
-	}
-}
+void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {}
+LLPluginMessage::~LLPluginMessage() {}
+
+/*****************************************************************************
+*   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
+		{
+			updater.setParams(test_url, test_channel, test_version);
+			updater.startChecking();
+			updater.setParams("other_url", test_channel, test_version);
+		}
+		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;
+		updater.setParams(test_url, test_channel, test_version);
+		updater.startChecking();
+		ensure(updater.isChecking());
+		updater.stopChecking();
+		ensure(!updater.isChecking());
+	}
+}
-- 
cgit v1.2.3


From ca9594af28ce2e1cc8bb333a0fa7384dae718a9a Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 28 Oct 2010 16:47:05 -0700
Subject: shell of the update checker; it will just print a message to the log
 depending on the result of the check one time.

---
 indra/newview/llappviewer.cpp                      |   8 +-
 indra/newview/lltranslate.cpp                      |   2 +-
 indra/viewer_components/updater/CMakeLists.txt     |   2 +
 .../viewer_components/updater/llupdatechecker.cpp  | 131 +++++++++++++++++++++
 indra/viewer_components/updater/llupdatechecker.h  |  69 +++++++++++
 .../viewer_components/updater/llupdaterservice.cpp |  31 ++++-
 .../updater/tests/llupdaterservice_test.cpp        |   6 +
 7 files changed, 241 insertions(+), 8 deletions(-)
 create mode 100644 indra/viewer_components/updater/llupdatechecker.cpp
 create mode 100644 indra/viewer_components/updater/llupdatechecker.h

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e6feaae504..06300141be 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -632,9 +632,6 @@ bool LLAppViewer::init()
 	if (!initConfiguration())
 		return false;
 
-	// Initialize updater service
-	initUpdater();
-
 	// write Google Breakpad minidump files to our log directory
 	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
 	logdir += gDirUtilp->getDirDelimiter();
@@ -980,7 +977,10 @@ bool LLAppViewer::mainLoop()
 	gServicePump = new LLPumpIO(gAPRPoolp);
 	LLHTTPClient::setPump(*gServicePump);
 	LLCurl::setCAFile(gDirUtilp->getCAFile());
-
+	
+	// Initialize updater service (now that we have an io pump)
+	initUpdater();
+	
 	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
 
 	LLVoiceChannel::initClass();
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 21467a2ab8..8ccfdb071b 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -64,7 +64,7 @@ void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std
 	getTranslateUrl(url, from_lang, to_lang, mesg);
 
     std::string user_agent = llformat("%s %d.%d.%d (%d)",
-		LLVersionInfo::getChannel(),
+		LLVersionInfo::getChannel().c_str(),
 		LLVersionInfo::getMajor(),
 		LLVersionInfo::getMinor(),
 		LLVersionInfo::getPatch(),
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index a8a1d685f7..2e77a7140a 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -18,10 +18,12 @@ include_directories(
 
 set(updater_service_SOURCE_FILES
     llupdaterservice.cpp
+    llupdatechecker.cpp
     )
 
 set(updater_service_HEADER_FILES
     llupdaterservice.h
+    llupdatechecker.h
     )
 
 set_source_files_properties(${updater_service_HEADER_FILES}
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
new file mode 100644
index 0000000000..a19b8be607
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -0,0 +1,131 @@
+/** 
+ * @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 <boost/format.hpp>
+#include "llhttpclient.h"
+#include "llupdatechecker.h"
+
+
+class LLUpdateChecker::Implementation:
+	public LLHTTPClient::Responder
+{
+public:
+	
+	Implementation(Client & client);
+	void check(std::string const & host, std::string channel, std::string version);
+	
+	// Responder:
+	virtual void completed(U32 status,
+						   const std::string & reason,
+						   const LLSD& content);
+	virtual void error(U32 status, const std::string & reason);
+	
+private:
+	std::string buildUrl(std::string const & host, std::string channel, std::string version);
+	
+	Client & mClient;
+	LLHTTPClient mHttpClient;
+	bool mInProgress;
+	std::string mVersion;
+	
+	LOG_CLASS(LLUpdateChecker::Implementation);
+};
+
+
+
+// LLUpdateChecker
+//-----------------------------------------------------------------------------
+
+
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
+	mImplementation(new LLUpdateChecker::Implementation(client))
+{
+	; // No op.
+}
+
+
+void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version)
+{
+	mImplementation->check(host, channel, version);
+}
+
+
+
+// LLUpdateChecker::Implementation
+//-----------------------------------------------------------------------------
+
+
+LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
+	mClient(client),
+	mInProgress(false)
+{
+	; // No op.
+}
+
+
+void LLUpdateChecker::Implementation::check(std::string const & host, std::string channel, std::string version)
+{
+	llassert(!mInProgress);
+		
+	mInProgress = true;
+	mVersion = version;
+	std::string checkUrl = buildUrl(host, channel, version);
+	LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
+	mHttpClient.get(checkUrl, this);
+}
+
+void LLUpdateChecker::Implementation::completed(U32 status,
+							  const std::string & reason,
+							  const LLSD & content)
+{
+	mInProgress = false;
+	
+	if(status != 200) {
+		LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
+	} else if(!content["valid"].asBoolean()) {
+		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
+	} else if(content["latest_version"].asString() != mVersion) {
+		LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl;
+	} else {
+		LL_INFOS("UpdateCheck") << "up to date" << llendl;
+	}
+}
+
+
+void LLUpdateChecker::Implementation::error(U32 status, const std::string & reason)
+{
+	mInProgress = false;
+	LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl;
+}
+
+
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host, std::string channel, std::string version)
+{	
+	static boost::format urlFormat("%s/version/%s/%s");
+	urlFormat % host % channel % version;
+	return urlFormat.str();
+}
+
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
new file mode 100644
index 0000000000..d2ec848e14
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -0,0 +1,69 @@
+/** 
+ * @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>
+
+
+//
+// Implements asynchronous checking for updates.
+//
+class LLUpdateChecker {
+public:
+	class Client;
+	class Implementation;
+	
+	LLUpdateChecker(Client & client);
+	
+	// Check status of current app on the given host for the channel and version provided.
+	void check(std::string const & hostUrl, std::string channel, std::string version);
+private:
+	boost::shared_ptr<Implementation> mImplementation;
+};
+
+
+//
+// The client interface implemented by a requestor checking for an update.
+//
+class LLUpdateChecker::Client
+{
+	// An error occurred while checking for an update.
+	virtual void error(std::string const & message) = 0;
+	
+	// A newer version is available, but the current version may still be used.
+	virtual void optionalUpdate(std::string const & newVersion) = 0;
+	
+	// A newer version is available, and the current version is no longer valid. 
+	virtual void requiredUpdate(std::string const & newVersion) = 0;
+	
+	// The checked version is up to date; no newer version exists.
+	virtual void upToDate(void) = 0;
+};
+
+
+#endif
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 28c942b5f2..e0f23722dd 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -26,6 +26,7 @@
 #include "linden_common.h"
 
 #include "llupdaterservice.h"
+#include "llupdatechecker.h"
 
 #include "llpluginprocessparent.h"
 #include <boost/scoped_ptr.hpp>
@@ -33,7 +34,9 @@
 
 boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
 
-class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
+class LLUpdaterServiceImpl : 
+	public LLPluginProcessParentOwner,
+	public LLUpdateChecker::Client
 {
 	std::string mUrl;
 	std::string mChannel;
@@ -42,7 +45,9 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
 	unsigned int mCheckPeriod;
 	bool mIsChecking;
 	boost::scoped_ptr<LLPluginProcessParent> mPlugin;
-
+	
+	LLUpdateChecker mUpdateChecker;
+	
 public:
 	LLUpdaterServiceImpl();
 	virtual ~LLUpdaterServiceImpl() {}
@@ -62,12 +67,21 @@ public:
 	void startChecking();
 	void stopChecking();
 	bool isChecking();
+	
+	// LLUpdateChecker::Client:
+	virtual void error(std::string const & message);
+	virtual void optionalUpdate(std::string const & newVersion);
+	virtual void requiredUpdate(std::string const & newVersion);
+	virtual void upToDate(void);
+	
 };
 
+
 LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
 	mCheckPeriod(0),
-	mPlugin(0)
+	mPlugin(0),
+	mUpdateChecker(*this)
 {
 	// Create the plugin parent, this is the owner.
 	mPlugin.reset(new LLPluginProcessParent(this));
@@ -121,6 +135,8 @@ void LLUpdaterServiceImpl::startChecking()
 				"LLUpdaterService::startCheck().");
 		}
 		mIsChecking = true;
+		
+		mUpdateChecker.check(mUrl, mChannel, mVersion);
 	}
 }
 
@@ -137,6 +153,15 @@ bool LLUpdaterServiceImpl::isChecking()
 	return mIsChecking;
 }
 
+void LLUpdaterServiceImpl::error(std::string const & message) {}
+
+void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion) {}
+
+void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion) {}
+
+void LLUpdaterServiceImpl::upToDate(void) {}
+
+
 //-----------------------------------------------------------------------
 // Facade interface
 LLUpdaterService::LLUpdaterService()
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 73cf6ea6eb..d93a85cf7d 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -28,6 +28,7 @@
 #include "linden_common.h"
 // associated header
 #include "../llupdaterservice.h"
+#include "../llupdatechecker.h"
 
 #include "../../../test/lltut.h"
 //#define DEBUG_ON
@@ -54,6 +55,11 @@ int LLPluginMessagePipeOwner::socketError(int) { return 0; }
 void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {}
 void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {}
 LLPluginMessage::~LLPluginMessage() {}
+LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {}
+
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
+{}
+void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version){}
 
 /*****************************************************************************
 *   TUT
-- 
cgit v1.2.3


From 609f5bd6810ca16a409f209610e6fac972348cba Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 29 Oct 2010 11:20:54 -0700
Subject: added periodic retry to look for updates

---
 indra/newview/app_settings/settings.xml            |  4 +-
 .../viewer_components/updater/llupdatechecker.cpp  | 19 +++++--
 indra/viewer_components/updater/llupdatechecker.h  |  2 +
 .../viewer_components/updater/llupdaterservice.cpp | 63 ++++++++++++++++++++--
 4 files changed, 78 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 371326c0f5..5b9bfd0f9c 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11011,7 +11011,7 @@
       <key>Type</key>
       <string>U32</string>
       <key>Value</key>
-      <integer>3600</integer>
+      <integer>10</integer>
     </map>
     <key>UpdaterServiceURL</key>
     <map>
@@ -11022,7 +11022,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>http://secondlife.com/app/update</string>
+      <string>http://localhost/agni</string>
     </map>
     <key>UploadBakedTexOld</key>
     <map>
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index a19b8be607..ca2959a4ac 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -35,6 +35,7 @@ class LLUpdateChecker::Implementation:
 public:
 	
 	Implementation(Client & client);
+	~Implementation();
 	void check(std::string const & host, std::string channel, std::string version);
 	
 	// Responder:
@@ -49,6 +50,7 @@ private:
 	Client & mClient;
 	LLHTTPClient mHttpClient;
 	bool mInProgress;
+	LLHTTPClient::ResponderPtr mMe;
 	std::string mVersion;
 	
 	LOG_CLASS(LLUpdateChecker::Implementation);
@@ -80,21 +82,28 @@ void LLUpdateChecker::check(std::string const & host, std::string channel, std::
 
 LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
 	mClient(client),
-	mInProgress(false)
+	mInProgress(false),
+	mMe(this)
 {
 	; // No op.
 }
 
 
+LLUpdateChecker::Implementation::~Implementation()
+{
+	mMe.reset(0);
+}
+
+
 void LLUpdateChecker::Implementation::check(std::string const & host, std::string channel, std::string version)
 {
-	llassert(!mInProgress);
+	// llassert(!mInProgress);
 		
 	mInProgress = true;
 	mVersion = version;
 	std::string checkUrl = buildUrl(host, channel, version);
 	LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
-	mHttpClient.get(checkUrl, this);
+	mHttpClient.get(checkUrl, mMe);
 }
 
 void LLUpdateChecker::Implementation::completed(U32 status,
@@ -105,12 +114,16 @@ void LLUpdateChecker::Implementation::completed(U32 status,
 	
 	if(status != 200) {
 		LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
+		mClient.error(reason);
 	} else if(!content["valid"].asBoolean()) {
 		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
+		mClient.requiredUpdate(content["latest_version"].asString());
 	} else if(content["latest_version"].asString() != mVersion) {
 		LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl;
+		mClient.optionalUpdate(content["latest_version"].asString());
 	} else {
 		LL_INFOS("UpdateCheck") << "up to date" << llendl;
+		mClient.upToDate();
 	}
 }
 
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index d2ec848e14..b630c4d8a6 100644
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -42,6 +42,7 @@ public:
 	
 	// Check status of current app on the given host for the channel and version provided.
 	void check(std::string const & hostUrl, std::string channel, std::string version);
+	
 private:
 	boost::shared_ptr<Implementation> mImplementation;
 };
@@ -52,6 +53,7 @@ private:
 //
 class LLUpdateChecker::Client
 {
+public:
 	// An error occurred while checking for an update.
 	virtual void error(std::string const & message) = 0;
 	
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index e0f23722dd..2633dbc015 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -25,6 +25,8 @@
 
 #include "linden_common.h"
 
+#include "llevents.h"
+#include "lltimer.h"
 #include "llupdaterservice.h"
 #include "llupdatechecker.h"
 
@@ -38,6 +40,8 @@ class LLUpdaterServiceImpl :
 	public LLPluginProcessParentOwner,
 	public LLUpdateChecker::Client
 {
+	static const std::string ListenerName;
+	
 	std::string mUrl;
 	std::string mChannel;
 	std::string mVersion;
@@ -47,10 +51,15 @@ class LLUpdaterServiceImpl :
 	boost::scoped_ptr<LLPluginProcessParent> mPlugin;
 	
 	LLUpdateChecker mUpdateChecker;
+	LLTimer mTimer;
+
+	void retry(void);
+	
+	LOG_CLASS(LLUpdaterServiceImpl);
 	
 public:
 	LLUpdaterServiceImpl();
-	virtual ~LLUpdaterServiceImpl() {}
+	virtual ~LLUpdaterServiceImpl();
 
 	// LLPluginProcessParentOwner interfaces
 	virtual void receivePluginMessage(const LLPluginMessage &message);
@@ -74,8 +83,10 @@ public:
 	virtual void requiredUpdate(std::string const & newVersion);
 	virtual void upToDate(void);
 	
+	bool onMainLoop(LLSD const & event);	
 };
 
+const std::string LLUpdaterServiceImpl::ListenerName = "LLUpdaterServiceImpl";
 
 LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
@@ -87,6 +98,12 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mPlugin.reset(new LLPluginProcessParent(this));
 }
 
+LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
+{
+	LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL;
+	LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName);
+}
+
 // LLPluginProcessParentOwner interfaces
 void LLUpdaterServiceImpl::receivePluginMessage(const LLPluginMessage &message)
 {
@@ -153,13 +170,49 @@ bool LLUpdaterServiceImpl::isChecking()
 	return mIsChecking;
 }
 
-void LLUpdaterServiceImpl::error(std::string const & message) {}
+void LLUpdaterServiceImpl::error(std::string const & message)
+{
+	retry();
+}
 
-void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion) {}
+void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion)
+{
+	retry();
+}
 
-void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion) {}
+void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion)
+{
+	retry();
+}
 
-void LLUpdaterServiceImpl::upToDate(void) {}
+void LLUpdaterServiceImpl::upToDate(void)
+{
+	retry();
+}
+
+void LLUpdaterServiceImpl::retry(void)
+{
+	LL_INFOS("UpdaterService") << "will check for update again in " << 
+	mCheckPeriod << " seconds" << LL_ENDL; 
+	mTimer.start();
+	mTimer.setTimerExpirySec(mCheckPeriod);
+	LLEventPumps::instance().obtain("mainloop").listen(
+		ListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
+}
+
+bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
+{
+	if(mTimer.hasExpired())
+	{
+		mTimer.stop();
+		LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName);
+		mUpdateChecker.check(mUrl, mChannel, mVersion);
+	} else {
+		// Keep on waiting...
+	}
+	
+	return false;
+}
 
 
 //-----------------------------------------------------------------------
-- 
cgit v1.2.3


From 064a8d079917ecd91bd6b47f5f7f353989594593 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 29 Oct 2010 11:22:07 -0700
Subject: restore 1hr polling frequency

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5b9bfd0f9c..274c7fbeb8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11011,7 +11011,7 @@
       <key>Type</key>
       <string>U32</string>
       <key>Value</key>
-      <integer>10</integer>
+      <integer>3600</integer>
     </map>
     <key>UpdaterServiceURL</key>
     <map>
-- 
cgit v1.2.3


From a2a9161e1b2d369689d76668dcad2c0ed7752960 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 29 Oct 2010 11:39:07 -0700
Subject: fix quoting of url in version check.

---
 indra/viewer_components/updater/llupdatechecker.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index ca2959a4ac..941210d35b 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -26,7 +26,9 @@
 #include "linden_common.h"
 #include <boost/format.hpp>
 #include "llhttpclient.h"
+#include "llsd.h"
 #include "llupdatechecker.h"
+#include "lluri.h"
 
 
 class LLUpdateChecker::Implementation:
@@ -137,8 +139,10 @@ void LLUpdateChecker::Implementation::error(U32 status, const std::string & reas
 
 std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host, std::string channel, std::string version)
 {	
-	static boost::format urlFormat("%s/version/%s/%s");
-	urlFormat % host % channel % version;
-	return urlFormat.str();
+	LLSD path;
+	path.append("version");
+	path.append(channel);
+	path.append(version);
+	return LLURI::buildHTTP(host, path).asString();
 }
 
-- 
cgit v1.2.3


From 8bdd99436580772b825a1e99ae5cf37d20163a8c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 29 Oct 2010 15:26:33 -0400
Subject: Fix #endif SYMBOL (breaks Linux build)

---
 indra/viewer_components/updater/llupdaterservice.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 6459ca49f8..313ae8ada3 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -58,4 +58,4 @@ private:
 	boost::shared_ptr<LLUpdaterServiceImpl> mImpl;
 };
 
-#endif LL_UPDATERSERVICE_H
+#endif // LL_UPDATERSERVICE_H
-- 
cgit v1.2.3


From 36b8b88153180f637c24709dc94739b5f4c4367e Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 1 Nov 2010 09:33:30 -0700
Subject: changes in respone to review comments.

---
 indra/viewer_components/updater/llupdatechecker.cpp  |  7 ++++++-
 indra/viewer_components/updater/llupdaterservice.cpp | 10 +++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 941210d35b..8733bb7ac0 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -52,7 +52,7 @@ private:
 	Client & mClient;
 	LLHTTPClient mHttpClient;
 	bool mInProgress;
-	LLHTTPClient::ResponderPtr mMe;
+	LLHTTPClient::ResponderPtr mMe; 
 	std::string mVersion;
 	
 	LOG_CLASS(LLUpdateChecker::Implementation);
@@ -105,6 +105,11 @@ void LLUpdateChecker::Implementation::check(std::string const & host, std::strin
 	mVersion = version;
 	std::string checkUrl = buildUrl(host, channel, version);
 	LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
+	
+	// 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);
 }
 
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 2633dbc015..62c909e57b 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -40,7 +40,7 @@ class LLUpdaterServiceImpl :
 	public LLPluginProcessParentOwner,
 	public LLUpdateChecker::Client
 {
-	static const std::string ListenerName;
+	static const std::string sListenerName;
 	
 	std::string mUrl;
 	std::string mChannel;
@@ -86,7 +86,7 @@ public:
 	bool onMainLoop(LLSD const & event);	
 };
 
-const std::string LLUpdaterServiceImpl::ListenerName = "LLUpdaterServiceImpl";
+const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
 
 LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
@@ -101,7 +101,7 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
 {
 	LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL;
-	LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName);
+	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 }
 
 // LLPluginProcessParentOwner interfaces
@@ -197,7 +197,7 @@ void LLUpdaterServiceImpl::retry(void)
 	mTimer.start();
 	mTimer.setTimerExpirySec(mCheckPeriod);
 	LLEventPumps::instance().obtain("mainloop").listen(
-		ListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
+		sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
 }
 
 bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
@@ -205,7 +205,7 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 	if(mTimer.hasExpired())
 	{
 		mTimer.stop();
-		LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName);
+		LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 		mUpdateChecker.check(mUrl, mChannel, mVersion);
 	} else {
 		// Keep on waiting...
-- 
cgit v1.2.3


From 3e43b0f4ca58aa859de455efe9503a6f6602fe6d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 1 Nov 2010 14:21:56 -0400
Subject: On Mac, require at least CMake 2.6.4 for an important bug fix. 2.6.4
 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION): before that
 version it returns "pathname/SLPlugin", whereas the correct answer is
 "pathname/SLPlugin.app/Contents/MacOS/SLPlugin". With 2.6.2, the Mac build
 breaks in a mysterious way. Changing this version requirement should clarify
 the solution.

---
 indra/CMakeLists.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 8d4969a49e..d01e1869b6 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -22,7 +22,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 include(Variables)
 
 if (DARWIN)
-  cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
+  # 2.6.4 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION):
+  # before that version it returns "pathname/SLPlugin", whereas the correct
+  # answer is "pathname/SLPlugin.app/Contents/MacOS/SLPlugin".
+  cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
 endif (DARWIN)
 
 if (NOT CMAKE_BUILD_TYPE)
-- 
cgit v1.2.3


From 2125bc0bbb3a5493b0b96bf68889b1f44b2db011 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 1 Nov 2010 15:49:04 -0400
Subject: On Windows, disable this-used-in-initializer warning.

---
 indra/viewer_components/updater/llupdatechecker.cpp  | 3 +++
 indra/viewer_components/updater/llupdaterservice.cpp | 4 ++++
 2 files changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 941210d35b..331d0269d4 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -30,6 +30,9 @@
 #include "llupdatechecker.h"
 #include "lluri.h"
 
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
 
 class LLUpdateChecker::Implementation:
 	public LLHTTPClient::Responder
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 2633dbc015..1d0ead3cd4 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -34,6 +34,10 @@
 #include <boost/scoped_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
 boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
 
 class LLUpdaterServiceImpl : 
-- 
cgit v1.2.3


From 6ab2e44e945ddc085a7b4b5f1524de924419a897 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Mon, 1 Nov 2010 15:18:18 -0700
Subject: VWR-23666 Removed setting VersionChannelName.
 LLVersionInfo::resetChannel() and unit tests. Reviewed by brad.

---
 indra/newview/CMakeLists.txt                 |   1 +
 indra/newview/app_settings/cmd_line.xml      |   3 +-
 indra/newview/app_settings/settings.xml      |  11 ---
 indra/newview/llappviewer.cpp                |  25 +++---
 indra/newview/llcurrencyuimanager.cpp        |   4 +-
 indra/newview/llfloaterabout.cpp             |   4 +-
 indra/newview/lllogininstance.cpp            |   5 +-
 indra/newview/llpanellogin.cpp               |   4 +-
 indra/newview/llversioninfo.cpp              |  37 ++++++++-
 indra/newview/llversioninfo.h                |   7 ++
 indra/newview/llviewercontrol.cpp            |   1 -
 indra/newview/llviewercontrol.h              |   2 -
 indra/newview/llviewermedia.cpp              |   2 +-
 indra/newview/llviewerstats.cpp              |   3 +-
 indra/newview/tests/lllogininstance_test.cpp |   9 ++-
 indra/newview/tests/llversioninfo_test.cpp   | 114 +++++++++++++++++++++++++++
 16 files changed, 189 insertions(+), 43 deletions(-)
 create mode 100644 indra/newview/tests/llversioninfo_test.cpp

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 63982ba87b..a488fb1069 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1858,6 +1858,7 @@ if (LL_TESTS)
     llmediadataclient.cpp
     lllogininstance.cpp
     llviewerhelputil.cpp
+    llversioninfo.cpp
   )
 
   ##################################################
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 00d69f805e..a17da8e344 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -361,8 +361,7 @@
     <map>
       <key>count</key>
       <integer>1</integer>
-      <key>map-to</key>
-      <string>VersionChannelName</string>
+      <!-- Special case. Not mapped to a setting. -->
     </map>
 
     <key>loginpage</key>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 371326c0f5..96d4fb1295 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11344,17 +11344,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>VersionChannelName</key>
-    <map>
-      <key>Comment</key>
-      <string>Versioning Channel Name.</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string>Second Life Release</string>
-    </map>
     <key>VertexShaderEnable</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e6feaae504..b122209af8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -662,11 +662,6 @@ bool LLAppViewer::init()
     initThreads();
     writeSystemInfo();
 
-	// Build a string representing the current version number.
-    gCurrentVersion = llformat("%s %s", 
-							   gSavedSettings.getString("VersionChannelName").c_str(),
-							   LLVersionInfo::getVersion().c_str());
-
 	//////////////////////////////////////////////////////////////////////////////
 	//////////////////////////////////////////////////////////////////////////////
 	//////////////////////////////////////////////////////////////////////////////
@@ -905,7 +900,8 @@ bool LLAppViewer::init()
 	gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
 
 	// Save the current version to the prefs file
-	gSavedSettings.setString("LastRunVersion", gCurrentVersion);
+	gSavedSettings.setString("LastRunVersion", 
+							 LLVersionInfo::getVersionAndChannel());
 
 	gSimLastTime = gRenderStartTime.getElapsedTimeF32();
 	gSimFrames = (F32)gFrameCount;
@@ -1941,8 +1937,6 @@ bool LLAppViewer::initConfiguration()
 	gSavedSettings.setString("ClientSettingsFile", 
         gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
 
-	gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel());
-
 #ifndef	LL_RELEASE_FOR_DOWNLOAD
 	// provide developer build only overrides for these control variables that are not
 	// persisted to settings.xml
@@ -2074,6 +2068,11 @@ bool LLAppViewer::initConfiguration()
         }
     }
 
+    if(clp.hasOption("channel"))
+    {
+		LLVersionInfo::resetChannel(clp.getOption("channel")[0]);
+	}
+	
 
 	// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
 	if(clp.hasOption("crashonstartup"))
@@ -2336,7 +2335,7 @@ void LLAppViewer::initUpdater()
 	// Get Channel
 	// Get Version
 	std::string url = gSavedSettings.getString("UpdaterServiceURL");
-	std::string channel = gSavedSettings.getString("VersionChannelName");
+	std::string channel = LLVersionInfo::getChannel();
 	std::string version = LLVersionInfo::getVersion();
 	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
 
@@ -2538,7 +2537,7 @@ void LLAppViewer::writeSystemInfo()
 {
 	gDebugInfo["SLLog"] = LLError::logFileName();
 
-	gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+	gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
 	gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
@@ -2636,7 +2635,7 @@ void LLAppViewer::handleViewerCrash()
 	
 	//We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version
 	//to check against no matter what
-	gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+	gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
 
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
@@ -4363,7 +4362,7 @@ void LLAppViewer::handleLoginComplete()
 	initMainloopTimeout("Mainloop Init");
 
 	// Store some data to DebugInfo in case of a freeze.
-	gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+	gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
 
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
@@ -4469,7 +4468,7 @@ void LLAppViewer::launchUpdater()
 	// *TODO change userserver to be grid on both viewer and sim, since
 	// userserver no longer exists.
 	query_map["userserver"] = LLGridManager::getInstance()->getGridLabel();
-	query_map["channel"] = gSavedSettings.getString("VersionChannelName");
+	query_map["channel"] = LLVersionInfo::getChannel();
 	// *TODO constantize this guy
 	// *NOTE: This URL is also used in win_setup/lldownloader.cpp
 	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 2b92b228b3..b4a1457f47 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -166,7 +166,7 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
 		gAgent.getSecureSessionID().asString());
 	keywordArgs.appendString("language", LLUI::getLanguage());
 	keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
-	keywordArgs.appendString("viewerChannel", gSavedSettings.getString("VersionChannelName"));
+	keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
 	keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
 	keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
 	keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
@@ -241,7 +241,7 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
 	{
 		keywordArgs.appendString("password", password);
 	}
-	keywordArgs.appendString("viewerChannel", gSavedSettings.getString("VersionChannelName"));
+	keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
 	keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
 	keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
 	keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 135137069c..8ae3ccbae3 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -213,7 +213,7 @@ LLSD LLFloaterAbout::getInfo()
 	info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion();
 	info["BUILD_DATE"] = __DATE__;
 	info["BUILD_TIME"] = __TIME__;
-	info["CHANNEL"] = gSavedSettings.getString("VersionChannelName");
+	info["CHANNEL"] = LLVersionInfo::getChannel();
 
 	info["VIEWER_RELEASE_NOTES_URL"] = get_viewer_release_notes_url();
 
@@ -291,7 +291,7 @@ static std::string get_viewer_release_notes_url()
 	std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
 	if (! LLStringUtil::endsWith(url, "/"))
 		url += "/";
-	url += gSavedSettings.getString("VersionChannelName") + "/";
+	url += LLVersionInfo::getChannel() + "/";
 	url += LLVersionInfo::getShortVersion();
 	return LLWeb::escapeURL(url);
 }
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 029e700c4c..fe84aca147 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -42,6 +42,7 @@
 // newview
 #include "llviewernetwork.h"
 #include "llviewercontrol.h"
+#include "llversioninfo.h"
 #include "llslurl.h"
 #include "llstartup.h"
 #include "llfloaterreg.h"
@@ -181,8 +182,8 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
 	request_params["read_critical"] = false; // handleTOSResponse
 	request_params["last_exec_event"] = mLastExecEvent;
 	request_params["mac"] = hashed_unique_id_string;
-	request_params["version"] = gCurrentVersion; // Includes channel name
-	request_params["channel"] = gSavedSettings.getString("VersionChannelName");
+	request_params["version"] = LLVersionInfo::getVersionAndChannel(); // Includes channel name
+	request_params["channel"] = LLVersionInfo::getChannel();
 	request_params["id0"] = mSerialNumber;
 
 	mRequestData.clear();
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 467aefc60f..cf567fb208 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -230,7 +230,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	getChild<LLPanel>("login")->setDefaultBtn("connect_btn");
 
-	std::string channel = gSavedSettings.getString("VersionChannelName");
+	std::string channel = LLVersionInfo::getChannel();
 	std::string version = llformat("%s (%d)",
 								   LLVersionInfo::getShortVersion().c_str(),
 								   LLVersionInfo::getBuild());
@@ -817,7 +817,7 @@ void LLPanelLogin::loadLoginPage()
 								   LLVersionInfo::getShortVersion().c_str(),
 								   LLVersionInfo::getBuild());
 
-	char* curl_channel = curl_escape(gSavedSettings.getString("VersionChannelName").c_str(), 0);
+	char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0);
 	char* curl_version = curl_escape(version.c_str(), 0);
 
 	oStr << "&channel=" << curl_channel;
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 733d05834a..53994c68f2 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -95,9 +95,42 @@ const std::string &LLVersionInfo::getShortVersion()
 	return version;
 }
 
+namespace
+{
+	/// Storage of the channel name the viewer is using.
+	//  The channel name is set by hardcoded constant, 
+	//  or by calling LLVersionInfo::resetChannel()
+	std::string sWorkingChannelName(LL_CHANNEL);
+
+	// Storage for the "version and channel" string.
+	// This will get reset too.
+	std::string sVersionChannel("");
+}
+
+//static
+const std::string &LLVersionInfo::getVersionAndChannel()
+{
+	if (sVersionChannel.empty())
+	{
+		// cache the version string
+		std::ostringstream stream;
+		stream << LLVersionInfo::getVersion() 
+			   << " "
+			   << LLVersionInfo::getChannel();
+		sVersionChannel = stream.str();
+	}
+
+	return sVersionChannel;
+}
+
 //static
 const std::string &LLVersionInfo::getChannel()
 {
-	static std::string name(LL_CHANNEL);
-	return name;
+	return sWorkingChannelName;
+}
+
+void LLVersionInfo::resetChannel(const std::string& channel)
+{
+	sWorkingChannelName = channel;
+	sVersionChannel.clear(); // Reset version and channel string til next use.
 }
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index e468b6ae4e..36defbcd68 100644
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -58,8 +58,15 @@ public:
 	/// return the viewer version as a string like "2.0.0"
 	static const std::string &getShortVersion();
 
+	/// return the viewer version and channel as a string
+	/// like "2.0.0.200030 Second Life Release"
+	static const std::string &getVersionAndChannel();
+
 	/// return the channel name, e.g. "Second Life"
 	static const std::string &getChannel();
+	
+	/// reset the channel name used by the viewer.
+	static void resetChannel(const std::string& channel);
 };
 
 #endif
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 522b5a7dfa..ebe9f7e275 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -82,7 +82,6 @@ LLControlGroup gCrashSettings("CrashSettings");	// saved at end of session
 LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings
 
 std::string gLastRunVersion;
-std::string gCurrentVersion;
 
 extern BOOL gResizeScreenTexture;
 extern BOOL gDebugGL;
diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h
index 22b48f8906..d7191f5c8d 100644
--- a/indra/newview/llviewercontrol.h
+++ b/indra/newview/llviewercontrol.h
@@ -57,7 +57,5 @@ extern LLControlGroup gCrashSettings;
 
 // Set after settings loaded
 extern std::string gLastRunVersion;
-extern std::string gCurrentVersion;
-
 
 #endif // LL_LLVIEWERCONTROL_H
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 48ab122edf..13fbce910b 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -492,7 +492,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
 
 	// Just in case we need to check browser differences in A/B test
 	// builds.
-	std::string channel = gSavedSettings.getString("VersionChannelName");
+	std::string channel = LLVersionInfo::getChannel();
 
 	// append our magic version number string to the browser user agent id
 	// See the HTTP 1.0 and 1.1 specifications for allowed formats:
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 42266ad233..3b7e44668d 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -48,6 +48,7 @@
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llviewercontrol.h"
+#include "llversioninfo.h"
 #include "llfloatertools.h"
 #include "lldebugview.h"
 #include "llfasttimerview.h"
@@ -749,7 +750,7 @@ void send_stats()
 
 	// send fps only for time app spends in foreground
 	agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
-	agent["version"] = gCurrentVersion;
+	agent["version"] = LLVersionInfo::getVersionAndChannel();
 	std::string language = LLUI::getLanguage();
 	agent["language"] = language;
 	
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index db50b89620..b902c7ab09 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -48,6 +48,9 @@ const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid");
 
 const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno");
 
+const std::string VIEWERLOGIN_CHANNEL("invalid_channel");
+const std::string VIEWERLOGIN_VERSION_CHANNEL("invalid_version");
+
 // Link seams.
 
 //-----------------------------------------------------------------------------
@@ -160,7 +163,6 @@ std::string LLGridManager::getAppSLURLBase(const std::string& grid_name)
 //-----------------------------------------------------------------------------
 #include "../llviewercontrol.h"
 LLControlGroup gSavedSettings("Global");
-std::string gCurrentVersion = "invalid_version";
 
 LLControlGroup::LLControlGroup(const std::string& name) :
 	LLInstanceTracker<LLControlGroup, std::string>(name){}
@@ -177,6 +179,10 @@ BOOL LLControlGroup::declareString(const std::string& name, const std::string &i
 #include "lluicolortable.h"
 void LLUIColorTable::saveUserSettings(void)const {}
 
+//-----------------------------------------------------------------------------
+#include "../llversioninfo.h"
+const std::string &LLVersionInfo::getVersionAndChannel() { return VIEWERLOGIN_VERSION_CHANNEL; }
+const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }
 
 //-----------------------------------------------------------------------------
 #include "llnotifications.h"
@@ -290,7 +296,6 @@ namespace tut
 			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE);
 			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE);
 			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE);
-			gSavedSettings.declareString("VersionChannelName", "test_version_string", "", FALSE);
 			gSavedSettings.declareString("NextLoginLocation", "", "", FALSE);
 			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE);
 
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
new file mode 100644
index 0000000000..b4f1b0273f
--- /dev/null
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -0,0 +1,114 @@
+/** 
+ * @file llversioninfo_test.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 "../test/lltut.h"
+
+#include "../llversioninfo.h"
+#include "llversionviewer.h"
+
+namespace tut
+{
+    struct versioninfo
+    {
+		versioninfo()
+			: mResetChannel("Reset Channel")
+		{
+			std::ostringstream stream;
+			stream << LL_VERSION_MAJOR << "."
+				   << LL_VERSION_MINOR << "."
+				   << LL_VERSION_PATCH << "."
+				   << LL_VERSION_BUILD;
+			mVersion = stream.str();
+			stream.str("");
+
+			stream << LL_VERSION_MAJOR << "."
+				   << LL_VERSION_MINOR << "."
+				   << LL_VERSION_PATCH;
+			mShortVersion = stream.str();
+			stream.str("");
+
+			stream << mVersion
+				   << " "
+				   << LL_CHANNEL;
+			mVersionAndChannel = stream.str();
+			stream.str("");
+
+			stream << mVersion
+				   << " "
+				   << mResetChannel;
+			mResetVersionAndChannel = stream.str();
+		}
+		std::string mResetChannel;
+		std::string mVersion;
+		std::string mShortVersion;
+		std::string mVersionAndChannel;
+		std::string mResetVersionAndChannel;
+    };
+    
+	typedef test_group<versioninfo> versioninfo_t;
+	typedef versioninfo_t::object versioninfo_object_t;
+	tut::versioninfo_t tut_versioninfo("LLVersionInfo");
+
+	template<> template<>
+	void versioninfo_object_t::test<1>()
+	{
+		ensure_equals("Major version", 
+					  LLVersionInfo::getMajor(), 
+					  LL_VERSION_MAJOR);
+		ensure_equals("Minor version", 
+					  LLVersionInfo::getMinor(), 
+					  LL_VERSION_MINOR);
+		ensure_equals("Patch version", 
+					  LLVersionInfo::getPatch(), 
+					  LL_VERSION_PATCH);
+		ensure_equals("Build version", 
+					  LLVersionInfo::getBuild(), 
+					  LL_VERSION_BUILD);
+		ensure_equals("Channel version", 
+					  LLVersionInfo::getChannel(), 
+					  LL_CHANNEL);
+
+		ensure_equals("Version String", 
+					  LLVersionInfo::getVersion(), 
+					  mVersion);
+		ensure_equals("Short Version String", 
+					  LLVersionInfo::getShortVersion(), 
+					  mShortVersion);
+		ensure_equals("Version and channel String", 
+					  LLVersionInfo::getVersionAndChannel(), 
+					  mVersionAndChannel);
+
+		LLVersionInfo::resetChannel(mResetChannel);
+		ensure_equals("Reset channel version", 
+					  LLVersionInfo::getChannel(), 
+					  mResetChannel);
+
+		ensure_equals("Reset Version and channel String", 
+					  LLVersionInfo::getVersionAndChannel(), 
+					  mResetVersionAndChannel);
+	}
+}
\ No newline at end of file
-- 
cgit v1.2.3


From 9cc290ef8fccdc585027d84ac9cfb864ed933061 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Mon, 1 Nov 2010 16:49:18 -0700
Subject: Added newline at EOF to satisfy linux gcc

---
 indra/newview/tests/llversioninfo_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
index b4f1b0273f..8855a24ead 100644
--- a/indra/newview/tests/llversioninfo_test.cpp
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -111,4 +111,4 @@ namespace tut
 					  LLVersionInfo::getVersionAndChannel(), 
 					  mResetVersionAndChannel);
 	}
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3


From be151807222ffa5972256aa9a392e8a319eae5ee Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 2 Nov 2010 15:59:10 -0700
Subject: start of the downloader service.

---
 indra/viewer_components/updater/CMakeLists.txt     |   8 +
 .../updater/llupdatedownloader.cpp                 | 168 +++++++++++++++++++++
 .../viewer_components/updater/llupdatedownloader.h |  73 +++++++++
 3 files changed, 249 insertions(+)
 create mode 100644 indra/viewer_components/updater/llupdatedownloader.cpp
 create mode 100644 indra/viewer_components/updater/llupdatedownloader.h

(limited to 'indra')

diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 2e77a7140a..64a0f98c2a 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -6,24 +6,30 @@ include(00-Common)
 if(LL_TESTS)
   include(LLAddBuildTest)
 endif(LL_TESTS)
+include(CURL)
 include(LLCommon)
 include(LLMessage)
 include(LLPlugin)
+include(LLVFS)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLPLUGIN_INCLUDE_DIRS}
+	${LLVFS_INCLUDE_DIRS}
+	${CURL_INCLUDE_DIRS}
     )
 
 set(updater_service_SOURCE_FILES
     llupdaterservice.cpp
     llupdatechecker.cpp
+    llupdatedownloader.cpp
     )
 
 set(updater_service_HEADER_FILES
     llupdaterservice.h
     llupdatechecker.h
+    llupdatedownloader.h
     )
 
 set_source_files_properties(${updater_service_HEADER_FILES}
@@ -42,6 +48,8 @@ target_link_libraries(llupdaterservice
     ${LLCOMMON_LIBRARIES}
     ${LLMESSAGE_LIBRARIES}
     ${LLPLUGIN_LIBRARIES}
+	${LLVFS_LIBRARIES}
+	${CURL_LIBRARIES}
     )
 
 if(LL_TESTS)
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
new file mode 100644
index 0000000000..4adf9c42b1
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -0,0 +1,168 @@
+/** 
+ * @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 "lldir.h"
+#include "llfile.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llthread.h"
+#include "llupdatedownloader.h"
+
+
+class LLUpdateDownloader::Implementation:
+	public LLThread
+{
+public:
+	Implementation(LLUpdateDownloader::Client & client);
+	void cancel(void);
+	void download(LLURI const & uri);
+	bool isDownloading(void);
+
+private:
+	static const char * sSecondLifeUpdateRecord;
+	
+	LLUpdateDownloader::Client & mClient;
+	std::string mDownloadRecordPath;
+	
+	void resumeDownloading(LLSD const & downloadData);
+	void run(void);
+	bool shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData);
+	void startDownloading(LLURI const & uri);
+};
+
+
+
+// LLUpdateDownloader
+//-----------------------------------------------------------------------------
+
+
+LLUpdateDownloader::LLUpdateDownloader(Client & client):
+	mImplementation(new LLUpdateDownloader::Implementation(client))
+{
+	; // No op.
+}
+
+
+void LLUpdateDownloader::cancel(void)
+{
+	mImplementation->cancel();
+}
+
+
+void LLUpdateDownloader::download(LLURI const & uri)
+{
+	mImplementation->download(uri);
+}
+
+
+bool LLUpdateDownloader::isDownloading(void)
+{
+	return mImplementation->isDownloading();
+}
+
+
+
+// LLUpdateDownloader::Implementation
+//-----------------------------------------------------------------------------
+
+
+const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord =
+	"SecondLifeUpdateDownload.xml";
+
+
+LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client):
+	LLThread("LLUpdateDownloader"),
+	mClient(client),
+	mDownloadRecordPath(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, sSecondLifeUpdateRecord))
+{
+	; // No op.
+}
+
+
+void LLUpdateDownloader::Implementation::cancel(void)
+{
+}
+
+
+void LLUpdateDownloader::Implementation::download(LLURI const & uri)
+{
+	LLSD downloadData;
+	if(shouldResumeOngoingDownload(uri, downloadData)){
+		
+	} else {
+					
+	}
+}
+
+
+bool LLUpdateDownloader::Implementation::isDownloading(void)
+{
+	return false;
+}
+
+
+void resumeDownloading(LLSD const & downloadData)
+{
+}
+
+
+bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData)
+{
+	if(!LLFile::isfile(mDownloadRecordPath)) return false;
+	
+	llifstream dataStream(mDownloadRecordPath);
+	LLSDSerialize parser;
+	parser.fromXMLDocument(downloadData, dataStream);
+	
+	if(downloadData["url"].asString() != uri.asString()) return false;
+	
+	std::string downloadedFilePath = downloadData["path"].asString();
+	if(LLFile::isfile(downloadedFilePath)) {
+		llstat fileStatus;
+		LLFile::stat(downloadedFilePath, &fileStatus);
+		downloadData["bytes_downloaded"] = LLSD(LLSD::Integer(fileStatus.st_size)); 
+		return true;
+	} else {
+		return false;
+	}
+
+	return true;
+}
+
+
+void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri)
+{
+	LLSD downloadData;
+	downloadData["url"] = uri.asString();
+	LLSD path = uri.pathArray();
+	std::string fileName = path[path.size() - 1].asString();
+	std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName);
+	llofstream dataStream(mDownloadRecordPath);
+	LLSDSerialize parser;
+	parser.toPrettyXML(downloadData, dataStream);
+	
+	llofstream downloadStream(filePath);
+}
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
new file mode 100644
index 0000000000..9dc5d789ce
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -0,0 +1,73 @@
+/** 
+ * @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;
+	
+	LLUpdateDownloader(Client & client);
+	
+	// Cancel any in progress download.
+	void cancel(void);
+	
+	// Start a new download.
+	void download(LLURI const & uri);
+	
+	// Returns true if a download is in progress.
+	bool isDownloading(void);
+	
+private:
+	boost::shared_ptr<Implementation> mImplementation;
+};
+
+
+//
+// An interface to be implemented by clients initiating a update download.
+//
+class LLUpdateDownloader::Client {
+	
+	// The download has completed successfully.
+	void downloadComplete(void);
+	
+	// The download failed.
+	void downloadError(std::string const & message);
+};
+
+
+#endif
\ No newline at end of file
-- 
cgit v1.2.3


From a26386c53a09d47eff092ad89b5684503ee31b9d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 3 Nov 2010 08:43:31 -0400
Subject: For non-Release Linux build, explain why we don't create tarball.

---
 indra/newview/viewer_manifest.py | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 6861f02bfb..4b98a11091 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -897,6 +897,9 @@ class LinuxManifest(ViewerManifest):
                         'dir': self.get_build_prefix(),
                         'inst_name': installer_name,
                         'inst_path':self.build_path_of(installer_name)})
+            else:
+                print "Skipping %s.tar.bz2 for non-Release build (%s)" % \
+                      (installer_name, self.args['buildtype'])
         finally:
             self.run_command("mv %(inst)s %(dst)s" % {
                 'dst': self.get_dst_prefix(),
-- 
cgit v1.2.3


From 2f6062e59793c8a5326c1dfac41334bac428faa9 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 3 Nov 2010 11:08:04 -0400
Subject: Remove erroneous 'inline' on LLPanelStandStopFlying::getInstance()
 This is ignored by every compiler except Linux g++ 4.4.3 in Release mode. In
 that case, it literally does cause getInstance() to be inlined, therefore
 llmoveview.o contains no such symbol, therefore the Linux viewer link fails
 in Release mode. But for a method implementation in a .cpp file of a method
 declared in a .h file, 'inline' is just wrong. Removing it fixes Release
 build.

---
 indra/newview/llmoveview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 6658e1d7e8..d38bb5aa4a 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -552,7 +552,7 @@ LLPanelStandStopFlying::LLPanelStandStopFlying() :
 }
 
 // static
-inline LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance()
+LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance()
 {
 	static LLPanelStandStopFlying* panel = getStandStopFlyingPanel();
 	return panel;
-- 
cgit v1.2.3


From 65997a1f5bb05dd263063606c00e0633af282784 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Wed, 3 Nov 2010 14:39:24 -0700
Subject: Added some logging to viewer_manifest.py to attempt to narrow down
 the Mac packaging failures a bit.

---
 indra/newview/viewer_manifest.py | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 4b98a11091..4596938775 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -743,6 +743,11 @@ class DarwinManifest(ViewerManifest):
             devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
             volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
 
+            if devfile != '/dev/disk1':
+                # adding more debugging info based upon nat's hunches to the
+                # logs to help track down 'SetFile -a V' failures -brad
+                print "WARNING: 'SetFile -a V' command below is probably gonna fail"
+
             # Copy everything in to the mounted .dmg
 
             if self.default_channel() and not self.default_grid():
-- 
cgit v1.2.3


From d594744d49732fd235694bde41f09cf578fccaf1 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Thu, 4 Nov 2010 10:52:21 -0700
Subject: Turned inlining on in windows builds (RelWithDebInfo and Release).
 This reduces the number of symbols in the viewer binary by about 30%. Also,
 fixed test errors revealed by inlining being enabled.

---
 indra/cmake/00-Common.cmake                   |  4 ++--
 indra/newview/tests/llviewerhelputil_test.cpp | 17 +++++++----------
 2 files changed, 9 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index a114d6e778..db2cdb5ff8 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -38,10 +38,10 @@ if (WINDOWS)
   set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP"
       CACHE STRING "C++ compiler debug options" FORCE)
   set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 
-      "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP"
+      "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob2"
       CACHE STRING "C++ compiler release-with-debug options" FORCE)
   set(CMAKE_CXX_FLAGS_RELEASE
-      "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP"
+      "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2"
       CACHE STRING "C++ compiler release options" FORCE)
 
   set(CMAKE_CXX_STANDARD_LIBRARIES "")
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
index a0f1d1c3c3..b425b50c8b 100644
--- a/indra/newview/tests/llviewerhelputil_test.cpp
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -72,16 +72,13 @@ static void substitute_string(std::string &input, const std::string &search, con
 	}
 }
 
-class LLAgent
-{
-public:
-	LLAgent() {}
-	~LLAgent() {}
-#ifdef __GNUC__
-	__attribute__ ((noinline))
-#endif
-	bool isGodlike() const { return FALSE; }
-};
+#include "../llagent.h"
+LLAgent::LLAgent() : mAgentAccess(gSavedSettings) { }
+LLAgent::~LLAgent() { }
+bool LLAgent::isGodlike() const { return FALSE; }
+LLAgentAccess::LLAgentAccess(LLControlGroup& settings) : mSavedSettings(settings) { }
+LLUIColor::LLUIColor() {}
+
 LLAgent gAgent;
 
 std::string LLWeb::expandURLSubstitutions(const std::string &url,
-- 
cgit v1.2.3


From e0c734a7105060740e5597d4439d882bb3f2bff4 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Thu, 4 Nov 2010 10:53:11 -0700
Subject: Turned generate_breakpad_symbols target into a noop for non-Release
 builds.

---
 indra/newview/CMakeLists.txt               | 10 +++++++++-
 indra/newview/generate_breakpad_symbols.py | 10 +++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a488fb1069..f18107f673 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1831,10 +1831,18 @@ if (PACKAGE)
     set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
   endif (LINUX)
 
+  if(CMAKE_CONFIGURATION_TYPES)
+      # set LLBUILD_CONFIG to be a shell variable evaluated at build time
+      # reflecting the configuration we are currently building.
+      set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
+  else(CMAKE_CONFIGURATION_TYPES)
+      set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
+  endif(CMAKE_CONFIGURATION_TYPES)
   add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
     COMMAND "${PYTHON_EXECUTABLE}"
     ARGS
       "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
+      "${LLBUILD_CONFIG}"
       "${VIEWER_DIST_DIR}"
       "${VIEWER_EXE_GLOBS}"
       "${VIEWER_LIB_GLOB}"
@@ -1843,7 +1851,7 @@ if (PACKAGE)
     DEPENDS generate_breakpad_symbols.py
     VERBATIM
   )
-  add_custom_target(generate_breakpad_symbols ALL DEPENDS "${VIEWER_SYMBOL_FILE}")
+  add_custom_target(generate_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
   add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
   add_dependencies(package generate_breakpad_symbols)
 endif (PACKAGE)
diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py
index 8f2dfd2348..0e61bee1ef 100644
--- a/indra/newview/generate_breakpad_symbols.py
+++ b/indra/newview/generate_breakpad_symbols.py
@@ -45,8 +45,12 @@ class MissingModuleError(Exception):
         Exception.__init__(self, "Failed to find required modules: %r" % modules)
         self.modules = modules
 
-def main(viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
-    print "generate_breakpad_symbols run with args: %s" % str((viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
+def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
+    print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
+
+    if configuration != "Release":
+        print "skipping breakpad symbol generation for non-release build."
+        return 0
 
     # split up list of viewer_exes
     # "'Second Life' SLPlugin" becomes ['Second Life', 'SLPlugin']
@@ -122,7 +126,7 @@ def main(viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_fil
     return 0
 
 if __name__ == "__main__":
-    if len(sys.argv) != 6:
+    if len(sys.argv) != 7:
         usage()
         sys.exit(1)
     sys.exit(main(*sys.argv[1:]))
-- 
cgit v1.2.3


From 7622ab9249506539894d0e33d4c2a8fd9fb3e3ac Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 4 Nov 2010 11:33:02 -0700
Subject: just barely working udate downloading service; missing little
 nicities like error checking and sill stuff like that.

---
 .../viewer_components/updater/llupdatechecker.cpp  |   9 +-
 indra/viewer_components/updater/llupdatechecker.h  |   7 +-
 .../updater/llupdatedownloader.cpp                 | 128 +++++++++++++++++++--
 .../viewer_components/updater/llupdatedownloader.h |  12 +-
 .../viewer_components/updater/llupdaterservice.cpp |  24 ++--
 .../updater/tests/llupdaterservice_test.cpp        |   4 +
 6 files changed, 159 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 9cfa919b39..596b122a25 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -120,17 +120,19 @@ void LLUpdateChecker::Implementation::completed(U32 status,
 							  const std::string & reason,
 							  const LLSD & content)
 {
-	mInProgress = false;
+	mInProgress = false;	
 	
 	if(status != 200) {
 		LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
 		mClient.error(reason);
 	} else if(!content["valid"].asBoolean()) {
 		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
-		mClient.requiredUpdate(content["latest_version"].asString());
+		LLURI uri(content["download_url"].asString());
+		mClient.requiredUpdate(content["latest_version"].asString(), uri);
 	} else if(content["latest_version"].asString() != mVersion) {
 		LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl;
-		mClient.optionalUpdate(content["latest_version"].asString());
+		LLURI uri(content["download_url"].asString());
+		mClient.optionalUpdate(content["latest_version"].asString(), uri);
 	} else {
 		LL_INFOS("UpdateCheck") << "up to date" << llendl;
 		mClient.upToDate();
@@ -153,4 +155,3 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host,
 	path.append(version);
 	return LLURI::buildHTTP(host, path).asString();
 }
-
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index b630c4d8a6..1f8c6d8a91 100644
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -48,6 +48,9 @@ private:
 };
 
 
+class LLURI; // From lluri.h
+
+
 //
 // The client interface implemented by a requestor checking for an update.
 //
@@ -58,10 +61,10 @@ public:
 	virtual void error(std::string const & message) = 0;
 	
 	// A newer version is available, but the current version may still be used.
-	virtual void optionalUpdate(std::string const & newVersion) = 0;
+	virtual void optionalUpdate(std::string const & newVersion, LLURI const & uri) = 0;
 	
 	// A newer version is available, and the current version is no longer valid. 
-	virtual void requiredUpdate(std::string const & newVersion) = 0;
+	virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri) = 0;
 	
 	// The checked version is up to date; no newer version exists.
 	virtual void upToDate(void) = 0;
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 4adf9c42b1..21e4ce94cc 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -24,6 +24,8 @@
  */
 
 #include "linden_common.h"
+#include <boost/lexical_cast.hpp>
+#include <curl/curl.h>
 #include "lldir.h"
 #include "llfile.h"
 #include "llsd.h"
@@ -37,20 +39,27 @@ class LLUpdateDownloader::Implementation:
 {
 public:
 	Implementation(LLUpdateDownloader::Client & client);
+	~Implementation();
 	void cancel(void);
 	void download(LLURI const & uri);
 	bool isDownloading(void);
-
+	void onHeader(void * header, size_t size);
+	void onBody(void * header, size_t size);
 private:
 	static const char * sSecondLifeUpdateRecord;
 	
 	LLUpdateDownloader::Client & mClient;
+	CURL * mCurl;
+	llofstream mDownloadStream;
 	std::string mDownloadRecordPath;
 	
+	void initializeCurlGet(std::string const & url);
 	void resumeDownloading(LLSD const & downloadData);
 	void run(void);
 	bool shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData);
 	void startDownloading(LLURI const & uri);
+
+	LOG_CLASS(LLUpdateDownloader::Implementation);
 };
 
 
@@ -89,6 +98,23 @@ bool LLUpdateDownloader::isDownloading(void)
 //-----------------------------------------------------------------------------
 
 
+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;
+	}
+
+	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;
+	}
+}
+
+
 const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord =
 	"SecondLifeUpdateDownload.xml";
 
@@ -96,35 +122,116 @@ const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord =
 LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client):
 	LLThread("LLUpdateDownloader"),
 	mClient(client),
+	mCurl(0),
 	mDownloadRecordPath(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, sSecondLifeUpdateRecord))
 {
-	; // No op.
+	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
+	llassert(code = CURLE_OK); // TODO: real error handling here. 
 }
 
 
-void LLUpdateDownloader::Implementation::cancel(void)
+LLUpdateDownloader::Implementation::~Implementation()
 {
+	if(mCurl) curl_easy_cleanup(mCurl);
 }
 
 
+void LLUpdateDownloader::Implementation::cancel(void)
+{
+	llassert(!"not implemented");
+}
+	
+
 void LLUpdateDownloader::Implementation::download(LLURI const & uri)
 {
 	LLSD downloadData;
 	if(shouldResumeOngoingDownload(uri, downloadData)){
-		
+		startDownloading(uri); // TODO: Implement resume.
 	} else {
-					
+		startDownloading(uri);
 	}
 }
 
 
 bool LLUpdateDownloader::Implementation::isDownloading(void)
 {
-	return false;
+	return !isStopped();
+}
+
+void 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(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("UpdateDownload") << "download size is " << size << LL_ENDL;
+			
+			LLSD downloadData;
+			llifstream idataStream(mDownloadRecordPath);
+			LLSDSerialize parser;
+			parser.fromXMLDocument(downloadData, idataStream);
+			idataStream.close();
+			downloadData["size"] = LLSD(LLSD::Integer(size));
+			llofstream odataStream(mDownloadRecordPath);
+			parser.toPrettyXML(downloadData, odataStream);
+		} catch (std::exception const & e) {
+			LL_WARNS("UpdateDownload") << "unable to read content length (" 
+				<< e.what() << ")" << LL_ENDL;
+		}
+	} else {
+		; // No op.
+	}
+}
+
+
+void LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
+{
+	mDownloadStream.write(reinterpret_cast<const char *>(buffer), size);
+}
+
+
+void LLUpdateDownloader::Implementation::run(void)
+{
+	CURLcode code = curl_easy_perform(mCurl);
+	if(code == CURLE_OK) {
+		LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
+		mClient.downloadComplete();
+	} else {
+		LL_WARNS("UpdateDownload") << "download failed with error " << code << LL_ENDL;
+		mClient.downloadError("curl error");
+	}
+}
+
+
+void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url)
+{
+	if(mCurl == 0) {
+		mCurl = curl_easy_init();
+	} else {
+		curl_easy_reset(mCurl);
+	}
+	
+	llassert(mCurl != 0); // TODO: real error handling here.
+	
+	CURLcode code;
+	code = curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true);
+	code = curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function);
+	code = curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this);
+	code = curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function);
+	code = curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this);
+	code = curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true);
+	code = curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str());
 }
 
 
-void resumeDownloading(LLSD const & downloadData)
+void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & downloadData)
 {
 }
 
@@ -160,9 +267,14 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri)
 	LLSD path = uri.pathArray();
 	std::string fileName = path[path.size() - 1].asString();
 	std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName);
+	LL_INFOS("UpdateDownload") << "downloading " << filePath << LL_ENDL;
+	LL_INFOS("UpdateDownload") << "from " << uri.asString() << LL_ENDL;
+	downloadData["path"] = filePath;
 	llofstream dataStream(mDownloadRecordPath);
 	LLSDSerialize parser;
 	parser.toPrettyXML(downloadData, dataStream);
 	
-	llofstream downloadStream(filePath);
+	mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary);
+	initializeCurlGet(uri.asString());
+	start();
 }
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index 9dc5d789ce..6118c4338e 100644
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -27,6 +27,7 @@
 #define LL_UPDATE_DOWNLOADER_H
 
 
+#include <stdexcept>
 #include <string>
 #include <boost/shared_ptr.hpp>
 #include "lluri.h"
@@ -38,15 +39,19 @@
 class LLUpdateDownloader
 {
 public:
+	class BusyError;
 	class Client;
 	class Implementation;
 	
 	LLUpdateDownloader(Client & client);
 	
-	// Cancel any in progress download.
+	// Cancel any in progress download; a no op if none is in progress.
 	void cancel(void);
 	
 	// Start a new download.
+	//
+	// This method will throw a BusyException instance if a download is already
+	// in progress.
 	void download(LLURI const & uri);
 	
 	// Returns true if a download is in progress.
@@ -61,12 +66,13 @@ private:
 // An interface to be implemented by clients initiating a update download.
 //
 class LLUpdateDownloader::Client {
+public:
 	
 	// The download has completed successfully.
-	void downloadComplete(void);
+	virtual void downloadComplete(void) = 0;
 	
 	// The download failed.
-	void downloadError(std::string const & message);
+	virtual void downloadError(std::string const & message) = 0;
 };
 
 
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index e339c69724..a1b6de38e5 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -25,6 +25,7 @@
 
 #include "linden_common.h"
 
+#include "llupdatedownloader.h"
 #include "llevents.h"
 #include "lltimer.h"
 #include "llupdaterservice.h"
@@ -42,7 +43,8 @@ boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
 
 class LLUpdaterServiceImpl : 
 	public LLPluginProcessParentOwner,
-	public LLUpdateChecker::Client
+	public LLUpdateChecker::Client,
+	public LLUpdateDownloader::Client
 {
 	static const std::string sListenerName;
 	
@@ -55,6 +57,7 @@ class LLUpdaterServiceImpl :
 	boost::scoped_ptr<LLPluginProcessParent> mPlugin;
 	
 	LLUpdateChecker mUpdateChecker;
+	LLUpdateDownloader mUpdateDownloader;
 	LLTimer mTimer;
 
 	void retry(void);
@@ -83,10 +86,14 @@ public:
 	
 	// LLUpdateChecker::Client:
 	virtual void error(std::string const & message);
-	virtual void optionalUpdate(std::string const & newVersion);
-	virtual void requiredUpdate(std::string const & newVersion);
+	virtual void optionalUpdate(std::string const & newVersion, LLURI const & uri);
+	virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri);
 	virtual void upToDate(void);
 	
+	// LLUpdateDownloader::Client
+	void downloadComplete(void) { retry(); }
+	void downloadError(std::string const & message) { retry(); }	
+
 	bool onMainLoop(LLSD const & event);	
 };
 
@@ -96,7 +103,8 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
 	mCheckPeriod(0),
 	mPlugin(0),
-	mUpdateChecker(*this)
+	mUpdateChecker(*this),
+	mUpdateDownloader(*this)
 {
 	// Create the plugin parent, this is the owner.
 	mPlugin.reset(new LLPluginProcessParent(this));
@@ -179,14 +187,14 @@ void LLUpdaterServiceImpl::error(std::string const & message)
 	retry();
 }
 
-void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion)
+void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, LLURI const & uri)
 {
-	retry();
+	mUpdateDownloader.download(uri);
 }
 
-void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion)
+void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, LLURI const & uri)
 {
-	retry();
+	mUpdateDownloader.download(uri);
 }
 
 void LLUpdaterServiceImpl::upToDate(void)
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index d93a85cf7d..0ffc1f2c70 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -29,6 +29,7 @@
 // associated header
 #include "../llupdaterservice.h"
 #include "../llupdatechecker.h"
+#include "../llupdatedownloader.h"
 
 #include "../../../test/lltut.h"
 //#define DEBUG_ON
@@ -60,6 +61,9 @@ LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {}
 LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
 {}
 void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version){}
+LLUpdateDownloader::LLUpdateDownloader(LLUpdateDownloader::Client & client)
+{}
+void LLUpdateDownloader::download(LLURI const & ){}
 
 /*****************************************************************************
 *   TUT
-- 
cgit v1.2.3


From dfeb7abe5f690bbd3a908c84c53bbea20a5adb7c Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 4 Nov 2010 14:08:14 -0700
Subject: checker working with v1.0 update protocol.

---
 indra/newview/app_settings/settings.xml            | 24 +++++++++-
 indra/newview/llappviewer.cpp                      |  4 +-
 .../viewer_components/updater/llupdatechecker.cpp  | 52 ++++++++++++++--------
 indra/viewer_components/updater/llupdatechecker.h  |  3 +-
 .../updater/llupdatedownloader.cpp                 |  1 +
 .../viewer_components/updater/llupdaterservice.cpp | 28 ++++++++----
 indra/viewer_components/updater/llupdaterservice.h |  6 +--
 .../updater/tests/llupdaterservice_test.cpp        | 11 ++---
 8 files changed, 91 insertions(+), 38 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8f5cb7c709..cc0e0a78db 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11022,7 +11022,29 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>http://localhost/agni</string>
+      <string>http://update.secondlife.com</string>
+    </map>
+    <key>UpdaterServicePath</key>
+    <map>
+      <key>Comment</key>
+      <string>Path on the update server host.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>update</string>
+    </map>
+    <key>UpdaterServiceProtocolVersion</key>
+    <map>
+      <key>Comment</key>
+      <string>The update protocol version to use.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>v1.0</string>
     </map>
     <key>UploadBakedTexOld</key>
     <map>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3a48bc25f1..6bb25969a6 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2337,9 +2337,11 @@ void LLAppViewer::initUpdater()
 	std::string url = gSavedSettings.getString("UpdaterServiceURL");
 	std::string channel = LLVersionInfo::getChannel();
 	std::string version = LLVersionInfo::getVersion();
+	std::string protocol_version = gSavedSettings.getString("UpdaterServiceProtocolVersion");
+	std::string service_path = gSavedSettings.getString("UpdaterServicePath");
 	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
 
-	mUpdater->setParams(url, channel, version);
+	mUpdater->setParams(protocol_version, url, service_path, channel, version);
 	mUpdater->setCheckPeriod(check_period);
 	if(gSavedSettings.getBOOL("UpdaterServiceActive"))
 	{
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 596b122a25..2c60636122 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -41,7 +41,8 @@ public:
 	
 	Implementation(Client & client);
 	~Implementation();
-	void check(std::string const & host, std::string channel, std::string version);
+	void check(std::string const & protocolVersion, std::string const & hostUrl, 
+			   std::string const & servicePath, std::string channel, std::string version);
 	
 	// Responder:
 	virtual void completed(U32 status,
@@ -50,7 +51,8 @@ public:
 	virtual void error(U32 status, const std::string & reason);
 	
 private:
-	std::string buildUrl(std::string const & host, std::string channel, std::string version);
+	std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, 
+						 std::string const & servicePath, std::string channel, std::string version);
 	
 	Client & mClient;
 	LLHTTPClient mHttpClient;
@@ -74,9 +76,10 @@ LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
 }
 
 
-void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version)
+void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, 
+							std::string const & servicePath, std::string channel, std::string version)
 {
-	mImplementation->check(host, channel, version);
+	mImplementation->check(protocolVersion, hostUrl, servicePath, channel, version);
 }
 
 
@@ -100,13 +103,14 @@ LLUpdateChecker::Implementation::~Implementation()
 }
 
 
-void LLUpdateChecker::Implementation::check(std::string const & host, std::string channel, std::string version)
+void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, std::string const & hostUrl, 
+											std::string const & servicePath, std::string channel, std::string version)
 {
 	// llassert(!mInProgress);
 		
 	mInProgress = true;
 	mVersion = version;
-	std::string checkUrl = buildUrl(host, channel, version);
+	std::string checkUrl = buildUrl(protocolVersion, hostUrl, servicePath, channel, version);
 	LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
 	
 	// The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the
@@ -125,17 +129,17 @@ void LLUpdateChecker::Implementation::completed(U32 status,
 	if(status != 200) {
 		LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
 		mClient.error(reason);
-	} else if(!content["valid"].asBoolean()) {
-		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
-		LLURI uri(content["download_url"].asString());
-		mClient.requiredUpdate(content["latest_version"].asString(), uri);
-	} else if(content["latest_version"].asString() != mVersion) {
-		LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl;
-		LLURI uri(content["download_url"].asString());
-		mClient.optionalUpdate(content["latest_version"].asString(), uri);
-	} else {
+	} else if(!content.asBoolean()) {
 		LL_INFOS("UpdateCheck") << "up to date" << llendl;
 		mClient.upToDate();
+	} else if(content["required"].asBoolean()) {
+		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
+		LLURI uri(content["url"].asString());
+		mClient.requiredUpdate(content["version"].asString(), uri);
+	} else {
+		LL_INFOS("UpdateCheck") << "newer version " << content["version"].asString() << " available" << llendl;
+		LLURI uri(content["url"].asString());
+		mClient.optionalUpdate(content["version"].asString(), uri);
 	}
 }
 
@@ -144,14 +148,26 @@ void LLUpdateChecker::Implementation::error(U32 status, const std::string & reas
 {
 	mInProgress = false;
 	LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl;
+	mClient.error(reason);
 }
 
 
-std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host, std::string channel, std::string version)
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & protocolVersion, std::string const & hostUrl, 
+													  std::string const & servicePath, std::string channel, std::string version)
 {	
+#ifdef LL_WINDOWS
+	static const char * platform = "win";
+#elif LL_DARWIN
+	static const char * platform = "mac";
+#else
+	static const char * platform = "lnx";
+#endif
+	
 	LLSD path;
-	path.append("version");
+	path.append(servicePath);
+	path.append(protocolVersion);
 	path.append(channel);
 	path.append(version);
-	return LLURI::buildHTTP(host, path).asString();
+	path.append(platform);
+	return LLURI::buildHTTP(hostUrl, path).asString();
 }
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index 1f8c6d8a91..58aaee4e3d 100644
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -41,7 +41,8 @@ public:
 	LLUpdateChecker(Client & client);
 	
 	// Check status of current app on the given host for the channel and version provided.
-	void check(std::string const & hostUrl, std::string channel, std::string version);
+	void check(std::string const & protocolVersion, std::string const & hostUrl, 
+			   std::string const & servicePath, std::string channel, std::string version);
 	
 private:
 	boost::shared_ptr<Implementation> mImplementation;
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 21e4ce94cc..087d79f804 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -222,6 +222,7 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u
 	
 	CURLcode code;
 	code = curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true);
+	code = curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true);
 	code = curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function);
 	code = curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this);
 	code = curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function);
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index a1b6de38e5..e865552fb3 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -48,7 +48,9 @@ class LLUpdaterServiceImpl :
 {
 	static const std::string sListenerName;
 	
+	std::string mProtocolVersion;
 	std::string mUrl;
+	std::string mPath;
 	std::string mChannel;
 	std::string mVersion;
 	
@@ -74,10 +76,12 @@ public:
 	virtual void pluginLaunchFailed();
 	virtual void pluginDied();
 
-	void setParams(const std::string& url,
+	void setParams(const std::string& protocol_version,
+				   const std::string& url, 
+				   const std::string& path,
 				   const std::string& channel,
 				   const std::string& version);
-
+	
 	void setCheckPeriod(unsigned int seconds);
 
 	void startChecking();
@@ -134,7 +138,9 @@ void LLUpdaterServiceImpl::pluginDied()
 {
 };
 
-void LLUpdaterServiceImpl::setParams(const std::string& url,
+void LLUpdaterServiceImpl::setParams(const std::string& protocol_version,
+									 const std::string& url, 
+									 const std::string& path,
 									 const std::string& channel,
 									 const std::string& version)
 {
@@ -144,7 +150,9 @@ void LLUpdaterServiceImpl::setParams(const std::string& url,
 			" before setting params.");
 	}
 		
+	mProtocolVersion = protocol_version;
 	mUrl = url;
+	mPath = path;
 	mChannel = channel;
 	mVersion = version;
 }
@@ -165,7 +173,7 @@ void LLUpdaterServiceImpl::startChecking()
 		}
 		mIsChecking = true;
 		
-		mUpdateChecker.check(mUrl, mChannel, mVersion);
+		mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
 	}
 }
 
@@ -218,7 +226,7 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 	{
 		mTimer.stop();
 		LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
-		mUpdateChecker.check(mUrl, mChannel, mVersion);
+		mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
 	} else {
 		// Keep on waiting...
 	}
@@ -247,11 +255,13 @@ LLUpdaterService::~LLUpdaterService()
 {
 }
 
-void LLUpdaterService::setParams(const std::string& url,
-								 const std::string& chan,
-								 const std::string& vers)
+void LLUpdaterService::setParams(const std::string& protocol_version,
+								 const std::string& url, 
+								 const std::string& path,
+								 const std::string& channel,
+								 const std::string& version)
 {
-	mImpl->setParams(url, chan, vers);
+	mImpl->setParams(protocol_version, url, path, channel, version);
 }
 
 void LLUpdaterService::setCheckPeriod(unsigned int seconds)
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 313ae8ada3..83b09c4bdd 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -42,9 +42,9 @@ public:
 	LLUpdaterService();
 	~LLUpdaterService();
 
-	// The base URL.
-	// *NOTE:Mani The grid, if any, would be embedded in the base URL.
-	void setParams(const std::string& url, 
+	void setParams(const std::string& version,
+				   const std::string& url, 
+				   const std::string& path,
 				   const std::string& channel,
 				   const std::string& version);
 
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 0ffc1f2c70..958526e35b 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -60,9 +60,10 @@ LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {}
 
 LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
 {}
-void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version){}
-LLUpdateDownloader::LLUpdateDownloader(LLUpdateDownloader::Client & client)
+void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, 
+								  std::string const & servicePath, std::string channel, std::string version)
 {}
+LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
 void LLUpdateDownloader::download(LLURI const & ){}
 
 /*****************************************************************************
@@ -113,9 +114,9 @@ namespace tut
 		bool got_usage_error = false;
 		try
 		{
-			updater.setParams(test_url, test_channel, test_version);
+			updater.setParams("1.0",test_url, "update" ,test_channel, test_version);
 			updater.startChecking();
-			updater.setParams("other_url", test_channel, test_version);
+			updater.setParams("1.0", "other_url", "update", test_channel, test_version);
 		}
 		catch(LLUpdaterService::UsageError)
 		{
@@ -129,7 +130,7 @@ namespace tut
     {
         DEBUG;
 		LLUpdaterService updater;
-		updater.setParams(test_url, test_channel, test_version);
+		updater.setParams("1.0", test_url, "update", test_channel, test_version);
 		updater.startChecking();
 		ensure(updater.isChecking());
 		updater.stopChecking();
-- 
cgit v1.2.3


From e45ba2957630f6319f8c633a409d78be56c264bd Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Thu, 4 Nov 2010 15:09:10 -0700
Subject: Fix for linux eol error.

---
 indra/viewer_components/updater/llupdatedownloader.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index 6118c4338e..395d19d6bf 100644
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -76,4 +76,4 @@ public:
 };
 
 
-#endif
\ No newline at end of file
+#endif
-- 
cgit v1.2.3


From 191e164a503b72c7feae0a46ad0422740b365556 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 4 Nov 2010 15:49:19 -0700
Subject: some better error handling.

---
 .../viewer_components/updater/llupdatechecker.cpp  |  35 ++++--
 indra/viewer_components/updater/llupdatechecker.h  |  11 +-
 .../updater/llupdatedownloader.cpp                 | 122 +++++++++++++--------
 .../viewer_components/updater/llupdatedownloader.h |  11 +-
 .../viewer_components/updater/llupdaterservice.cpp |  20 +++-
 .../updater/tests/llupdaterservice_test.cpp        |   2 +-
 6 files changed, 136 insertions(+), 65 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 2c60636122..d31244cc9b 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -24,21 +24,35 @@
  */
 
 #include "linden_common.h"
+#include <stdexcept>
 #include <boost/format.hpp>
 #include "llhttpclient.h"
 #include "llsd.h"
 #include "llupdatechecker.h"
 #include "lluri.h"
 
+
 #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.
+	}
+};
+
+
 class LLUpdateChecker::Implementation:
 	public LLHTTPClient::Responder
 {
 public:
-	
 	Implementation(Client & client);
 	~Implementation();
 	void check(std::string const & protocolVersion, std::string const & hostUrl, 
@@ -50,9 +64,8 @@ public:
 						   const LLSD& content);
 	virtual void error(U32 status, const std::string & reason);
 	
-private:
-	std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, 
-						 std::string const & servicePath, std::string channel, std::string version);
+private:	
+	static const char * sProtocolVersion;
 	
 	Client & mClient;
 	LLHTTPClient mHttpClient;
@@ -60,6 +73,9 @@ private:
 	LLHTTPClient::ResponderPtr mMe; 
 	std::string mVersion;
 	
+	std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, 
+						 std::string const & servicePath, std::string channel, std::string version);
+
 	LOG_CLASS(LLUpdateChecker::Implementation);
 };
 
@@ -88,6 +104,9 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con
 //-----------------------------------------------------------------------------
 
 
+const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.0";
+
+
 LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
 	mClient(client),
 	mInProgress(false),
@@ -106,7 +125,9 @@ LLUpdateChecker::Implementation::~Implementation()
 void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, std::string const & hostUrl, 
 											std::string const & servicePath, std::string channel, std::string version)
 {
-	// llassert(!mInProgress);
+	llassert(!mInProgress);
+	
+	if(protocolVersion != sProtocolVersion) throw CheckError("unsupported protocol");
 		
 	mInProgress = true;
 	mVersion = version;
@@ -135,11 +156,11 @@ void LLUpdateChecker::Implementation::completed(U32 status,
 	} else if(content["required"].asBoolean()) {
 		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
 		LLURI uri(content["url"].asString());
-		mClient.requiredUpdate(content["version"].asString(), uri);
+		mClient.requiredUpdate(content["version"].asString(), uri, content["hash"].asString());
 	} else {
 		LL_INFOS("UpdateCheck") << "newer version " << content["version"].asString() << " available" << llendl;
 		LLURI uri(content["url"].asString());
-		mClient.optionalUpdate(content["version"].asString(), uri);
+		mClient.optionalUpdate(content["version"].asString(), uri, content["hash"].asString());
 	}
 }
 
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index 58aaee4e3d..cea1f13647 100644
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -38,6 +38,9 @@ public:
 	class Client;
 	class Implementation;
 	
+	// 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.
@@ -62,10 +65,14 @@ public:
 	virtual void error(std::string const & message) = 0;
 	
 	// A newer version is available, but the current version may still be used.
-	virtual void optionalUpdate(std::string const & newVersion, LLURI const & uri) = 0;
+	virtual void optionalUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash) = 0;
 	
 	// A newer version is available, and the current version is no longer valid. 
-	virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri) = 0;
+	virtual void requiredUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash) = 0;
 	
 	// The checked version is up to date; no newer version exists.
 	virtual void upToDate(void) = 0;
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 087d79f804..23772e021e 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "linden_common.h"
+#include <stdexcept>
 #include <boost/lexical_cast.hpp>
 #include <curl/curl.h>
 #include "lldir.h"
@@ -41,33 +42,56 @@ public:
 	Implementation(LLUpdateDownloader::Client & client);
 	~Implementation();
 	void cancel(void);
-	void download(LLURI const & uri);
+	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);
 private:
-	static const char * sSecondLifeUpdateRecord;
-	
 	LLUpdateDownloader::Client & mClient;
 	CURL * mCurl;
+	LLSD mDownloadData;
 	llofstream mDownloadStream;
 	std::string mDownloadRecordPath;
 	
 	void initializeCurlGet(std::string const & url);
 	void resumeDownloading(LLSD const & downloadData);
 	void run(void);
-	bool shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData);
-	void startDownloading(LLURI const & uri);
+	void startDownloading(LLURI const & uri, std::string const & hash);
+	void throwOnCurlError(CURLcode code);
 
 	LOG_CLASS(LLUpdateDownloader::Implementation);
 };
 
 
+namespace {
+	class DownloadError:
+		public std::runtime_error
+	{
+	public:
+		DownloadError(const char * message):
+			std::runtime_error(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))
 {
@@ -81,9 +105,9 @@ void LLUpdateDownloader::cancel(void)
 }
 
 
-void LLUpdateDownloader::download(LLURI const & uri)
+void LLUpdateDownloader::download(LLURI const & uri, std::string const & hash)
 {
-	mImplementation->download(uri);
+	mImplementation->download(uri, hash);
 }
 
 
@@ -115,15 +139,11 @@ namespace {
 }
 
 
-const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord =
-	"SecondLifeUpdateDownload.xml";
-
-
 LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client):
 	LLThread("LLUpdateDownloader"),
 	mClient(client),
 	mCurl(0),
-	mDownloadRecordPath(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, sSecondLifeUpdateRecord))
+	mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath())
 {
 	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
 	llassert(code = CURLE_OK); // TODO: real error handling here. 
@@ -142,13 +162,15 @@ void LLUpdateDownloader::Implementation::cancel(void)
 }
 	
 
-void LLUpdateDownloader::Implementation::download(LLURI const & uri)
+void LLUpdateDownloader::Implementation::download(LLURI const & uri, std::string const & hash)
 {
-	LLSD downloadData;
-	if(shouldResumeOngoingDownload(uri, downloadData)){
-		startDownloading(uri); // TODO: Implement resume.
-	} else {
-		startDownloading(uri);
+	if(isDownloading()) mClient.downloadError("download in progress");
+	
+	mDownloadData = LLSD();
+	try {
+		startDownloading(uri, hash);
+	} catch(DownloadError const & e) {
+		mClient.downloadError(e.what());
 	}
 }
 
@@ -173,14 +195,10 @@ void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
 			size_t size = boost::lexical_cast<size_t>(contentLength);
 			LL_INFOS("UpdateDownload") << "download size is " << size << LL_ENDL;
 			
-			LLSD downloadData;
-			llifstream idataStream(mDownloadRecordPath);
-			LLSDSerialize parser;
-			parser.fromXMLDocument(downloadData, idataStream);
-			idataStream.close();
-			downloadData["size"] = LLSD(LLSD::Integer(size));
+			mDownloadData["size"] = LLSD(LLSD::Integer(size));
 			llofstream odataStream(mDownloadRecordPath);
-			parser.toPrettyXML(downloadData, odataStream);
+			LLSDSerialize parser;
+			parser.toPrettyXML(mDownloadData, odataStream);
 		} catch (std::exception const & e) {
 			LL_WARNS("UpdateDownload") << "unable to read content length (" 
 				<< e.what() << ")" << LL_ENDL;
@@ -218,17 +236,16 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u
 		curl_easy_reset(mCurl);
 	}
 	
-	llassert(mCurl != 0); // TODO: real error handling here.
+	if(mCurl == 0) throw DownloadError("failed to initialize curl");
 	
-	CURLcode code;
-	code = curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true);
-	code = curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true);
-	code = curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function);
-	code = curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this);
-	code = curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function);
-	code = curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this);
-	code = curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true);
-	code = curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str());
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str()));
 }
 
 
@@ -236,7 +253,7 @@ void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & download
 {
 }
 
-
+/*
 bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData)
 {
 	if(!LLFile::isfile(mDownloadRecordPath)) return false;
@@ -259,23 +276,42 @@ bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const
 
 	return true;
 }
+ */
 
 
-void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri)
+void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std::string const & hash)
 {
-	LLSD downloadData;
-	downloadData["url"] = uri.asString();
+	mDownloadData["url"] = uri.asString();
+	mDownloadData["hash"] = hash;
 	LLSD path = uri.pathArray();
+	if(path.size() == 0) throw DownloadError("no file path");
 	std::string fileName = path[path.size() - 1].asString();
 	std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName);
-	LL_INFOS("UpdateDownload") << "downloading " << filePath << LL_ENDL;
-	LL_INFOS("UpdateDownload") << "from " << uri.asString() << LL_ENDL;
-	downloadData["path"] = filePath;
+	mDownloadData["path"] = filePath;
+
+	LL_INFOS("UpdateDownload") << "downloading " << filePath << "\n"
+		<< "from " << uri.asString() << LL_ENDL;
+		
 	llofstream dataStream(mDownloadRecordPath);
 	LLSDSerialize parser;
-	parser.toPrettyXML(downloadData, dataStream);
+	parser.toPrettyXML(mDownloadData, dataStream);
 	
 	mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary);
 	initializeCurlGet(uri.asString());
 	start();
 }
+
+
+void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code)
+{
+	if(code != CURLE_OK) {
+		const char * errorString = curl_easy_strerror(code);
+		if(errorString != 0) {
+			throw DownloadError(curl_easy_strerror(code));
+		} else {
+			throw DownloadError("unknown curl error");
+		}
+	} else {
+		; // No op.
+	}
+}
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index 6118c4338e..8754ea329c 100644
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -27,7 +27,6 @@
 #define LL_UPDATE_DOWNLOADER_H
 
 
-#include <stdexcept>
 #include <string>
 #include <boost/shared_ptr.hpp>
 #include "lluri.h"
@@ -39,20 +38,20 @@
 class LLUpdateDownloader
 {
 public:
-	class BusyError;
 	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.
 	void cancel(void);
 	
 	// Start a new download.
-	//
-	// This method will throw a BusyException instance if a download is already
-	// in progress.
-	void download(LLURI const & uri);
+	void download(LLURI const & uri, std::string const & hash);
 	
 	// Returns true if a download is in progress.
 	bool isDownloading(void);
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index e865552fb3..1e0c393539 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -90,8 +90,12 @@ public:
 	
 	// LLUpdateChecker::Client:
 	virtual void error(std::string const & message);
-	virtual void optionalUpdate(std::string const & newVersion, LLURI const & uri);
-	virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri);
+	virtual void optionalUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash);
+	virtual void requiredUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash);
 	virtual void upToDate(void);
 	
 	// LLUpdateDownloader::Client
@@ -195,14 +199,18 @@ void LLUpdaterServiceImpl::error(std::string const & message)
 	retry();
 }
 
-void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, LLURI const & uri)
+void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion,
+										  LLURI const & uri,
+										  std::string const & hash)
 {
-	mUpdateDownloader.download(uri);
+	mUpdateDownloader.download(uri, hash);
 }
 
-void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, LLURI const & uri)
+void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion,
+										  LLURI const & uri,
+										  std::string const & hash)
 {
-	mUpdateDownloader.download(uri);
+	mUpdateDownloader.download(uri, hash);
 }
 
 void LLUpdaterServiceImpl::upToDate(void)
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 958526e35b..20d0f8fa09 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -64,7 +64,7 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con
 								  std::string const & servicePath, std::string channel, std::string version)
 {}
 LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
-void LLUpdateDownloader::download(LLURI const & ){}
+void LLUpdateDownloader::download(LLURI const & , std::string const &){}
 
 /*****************************************************************************
 *   TUT
-- 
cgit v1.2.3


From 4d1e45f20f924f070d0f0139878c2c96e698fb07 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 4 Nov 2010 17:14:12 -0700
Subject: added hash validation of downloaded file.

---
 .../updater/llupdatedownloader.cpp                 | 41 +++++++++++++++++++---
 1 file changed, 36 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 23772e021e..59e929d99f 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -29,6 +29,7 @@
 #include <curl/curl.h>
 #include "lldir.h"
 #include "llfile.h"
+#include "llmd5.h"
 #include "llsd.h"
 #include "llsdserialize.h"
 #include "llthread.h"
@@ -58,6 +59,7 @@ private:
 	void run(void);
 	void startDownloading(LLURI const & uri, std::string const & hash);
 	void throwOnCurlError(CURLcode code);
+	bool validateDownload(void);
 
 	LOG_CLASS(LLUpdateDownloader::Implementation);
 };
@@ -130,6 +132,7 @@ namespace {
 		return bytes;
 	}
 
+
 	size_t header_function(void * data, size_t blockSize, size_t blocks, void * downloader)
 	{
 		size_t bytes = blockSize * blocks;
@@ -219,10 +222,18 @@ void LLUpdateDownloader::Implementation::run(void)
 {
 	CURLcode code = curl_easy_perform(mCurl);
 	if(code == CURLE_OK) {
-		LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
-		mClient.downloadComplete();
+		if(validateDownload()) {
+			LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
+			mClient.downloadComplete();
+		} else {
+			LL_INFOS("UpdateDownload") << "download failed hash check" << LL_ENDL;
+			std::string filePath = mDownloadData["path"].asString();
+			if(filePath.size() != 0) LLFile::remove(filePath);
+			mClient.downloadError("failed hash check");
+		}
 	} else {
-		LL_WARNS("UpdateDownload") << "download failed with error " << code << LL_ENDL;
+		LL_WARNS("UpdateDownload") << "download failed with error '" << 
+			curl_easy_strerror(code) << "'" << LL_ENDL;
 		mClient.downloadError("curl error");
 	}
 }
@@ -253,6 +264,7 @@ void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & download
 {
 }
 
+
 /*
 bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData)
 {
@@ -289,8 +301,9 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std
 	std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName);
 	mDownloadData["path"] = filePath;
 
-	LL_INFOS("UpdateDownload") << "downloading " << filePath << "\n"
-		<< "from " << uri.asString() << LL_ENDL;
+	LL_INFOS("UpdateDownload") << "downloading " << filePath
+		<< " from " << uri.asString() << LL_ENDL;
+	LL_INFOS("UpdateDownload") << "hash of file is " << hash << LL_ENDL;
 		
 	llofstream dataStream(mDownloadRecordPath);
 	LLSDSerialize parser;
@@ -315,3 +328,21 @@ void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code)
 		; // No op.
 	}
 }
+
+
+bool LLUpdateDownloader::Implementation::validateDownload(void)
+{
+	std::string filePath = mDownloadData["path"].asString();
+	llifstream fileStream(filePath);
+	if(!fileStream) return false;
+
+	std::string hash = mDownloadData["hash"].asString();
+	if(hash.size() != 0) {
+		LL_INFOS("UpdateDownload") << "checking hash..." << LL_ENDL;
+		char digest[33];
+		LLMD5(fileStream).hex_digest(digest);
+		return hash == digest;
+	} else {
+		return true; // No hash check provided.
+	}
+}
-- 
cgit v1.2.3


From 95d39166faecec2c851285775422c3f668641de2 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Thu, 4 Nov 2010 19:11:40 -0700
Subject: Fix for windows build breakage in teamcity.

---
 indra/viewer_components/updater/llupdaterservice.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 83b09c4bdd..04adf461b6 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -42,7 +42,7 @@ public:
 	LLUpdaterService();
 	~LLUpdaterService();
 
-	void setParams(const std::string& version,
+	void setParams(const std::string& protocol_version,
 				   const std::string& url, 
 				   const std::string& path,
 				   const std::string& channel,
-- 
cgit v1.2.3


From 9d7cdc17e311ba5f1f62112e316c531b68f67046 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 5 Nov 2010 11:12:54 -0700
Subject: resume feature (untested).

---
 .../updater/llupdatedownloader.cpp                 | 104 ++++++++++++++-------
 .../viewer_components/updater/llupdatedownloader.h |   5 +-
 .../viewer_components/updater/llupdaterservice.cpp |   2 +-
 3 files changed, 77 insertions(+), 34 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 59e929d99f..102f2f9eec 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -25,6 +25,7 @@
 
 #include "linden_common.h"
 #include <stdexcept>
+#include <boost/format.hpp>
 #include <boost/lexical_cast.hpp>
 #include <curl/curl.h>
 #include "lldir.h"
@@ -47,6 +48,8 @@ public:
 	bool isDownloading(void);
 	void onHeader(void * header, size_t size);
 	void onBody(void * header, size_t size);
+	void resume(void);
+	
 private:
 	LLUpdateDownloader::Client & mClient;
 	CURL * mCurl;
@@ -54,8 +57,8 @@ private:
 	llofstream mDownloadStream;
 	std::string mDownloadRecordPath;
 	
-	void initializeCurlGet(std::string const & url);
-	void resumeDownloading(LLSD const & downloadData);
+	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);
@@ -119,6 +122,12 @@ bool LLUpdateDownloader::isDownloading(void)
 }
 
 
+void LLUpdateDownloader::resume(void)
+{
+	mImplementation->resume();
+}
+
+
 
 // LLUpdateDownloader::Implementation
 //-----------------------------------------------------------------------------
@@ -183,6 +192,45 @@ bool LLUpdateDownloader::Implementation::isDownloading(void)
 	return !isStopped();
 }
 
+
+void LLUpdateDownloader::Implementation::resume(void)
+{
+	llifstream dataStream(mDownloadRecordPath);
+	if(!dataStream) {
+		mClient.downloadError("no download marker");
+		return;
+	}
+	
+	LLSDSerialize parser;
+	parser.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(!validateDownload()) {
+				LLFile::remove(filePath);
+				download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString());
+			} else {
+				mClient.downloadComplete(mDownloadData);
+			}
+		} else {
+			download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString());
+		}
+	} catch(DownloadError & e) {
+		mClient.downloadError(e.what());
+	}
+}
+
+
 void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
 {
 	char const * headerPtr = reinterpret_cast<const char *> (buffer);
@@ -221,10 +269,11 @@ void LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
 void LLUpdateDownloader::Implementation::run(void)
 {
 	CURLcode code = curl_easy_perform(mCurl);
+	LLFile::remove(mDownloadRecordPath);
 	if(code == CURLE_OK) {
 		if(validateDownload()) {
 			LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
-			mClient.downloadComplete();
+			mClient.downloadComplete(mDownloadData);
 		} else {
 			LL_INFOS("UpdateDownload") << "download failed hash check" << LL_ENDL;
 			std::string filePath = mDownloadData["path"].asString();
@@ -239,7 +288,7 @@ void LLUpdateDownloader::Implementation::run(void)
 }
 
 
-void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url)
+void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
 {
 	if(mCurl == 0) {
 		mCurl = curl_easy_init();
@@ -253,42 +302,33 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u
 	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true));
 	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function));
 	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this));
-	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));
-	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));
+	if(processHeader) {
+	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));
+	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));
+	}
 	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true));
 	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str()));
 }
 
 
-void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & downloadData)
-{
-}
-
-
-/*
-bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData)
+void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)
 {
-	if(!LLFile::isfile(mDownloadRecordPath)) return false;
+	initializeCurlGet(mDownloadData["url"].asString(), false);
 	
-	llifstream dataStream(mDownloadRecordPath);
-	LLSDSerialize parser;
-	parser.fromXMLDocument(downloadData, dataStream);
+	// 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;
+	curl_slist * headerList = 0;
+	headerList = curl_slist_append(headerList, rangeHeaderFormat.str().c_str());
+	if(headerList == 0) throw DownloadError("cannot add Range header");
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, headerList));
+	curl_slist_free_all(headerList);
 	
-	if(downloadData["url"].asString() != uri.asString()) return false;
-	
-	std::string downloadedFilePath = downloadData["path"].asString();
-	if(LLFile::isfile(downloadedFilePath)) {
-		llstat fileStatus;
-		LLFile::stat(downloadedFilePath, &fileStatus);
-		downloadData["bytes_downloaded"] = LLSD(LLSD::Integer(fileStatus.st_size)); 
-		return true;
-	} else {
-		return false;
-	}
-
-	return true;
+	mDownloadStream.open(mDownloadData["path"].asString(),
+						 std::ios_base::out | std::ios_base::binary | std::ios_base::app);
+	start();
 }
- */
 
 
 void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std::string const & hash)
@@ -310,7 +350,7 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std
 	parser.toPrettyXML(mDownloadData, dataStream);
 	
 	mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary);
-	initializeCurlGet(uri.asString());
+	initializeCurlGet(uri.asString(), true);
 	start();
 }
 
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index 8754ea329c..7bfb430879 100644
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -56,6 +56,9 @@ public:
 	// Returns true if a download is in progress.
 	bool isDownloading(void);
 	
+	// Resume a partial download.
+	void resume(void);
+	
 private:
 	boost::shared_ptr<Implementation> mImplementation;
 };
@@ -68,7 +71,7 @@ class LLUpdateDownloader::Client {
 public:
 	
 	// The download has completed successfully.
-	virtual void downloadComplete(void) = 0;
+	virtual void downloadComplete(LLSD const & data) = 0;
 	
 	// The download failed.
 	virtual void downloadError(std::string const & message) = 0;
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 1e0c393539..dc48606cbc 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -99,7 +99,7 @@ public:
 	virtual void upToDate(void);
 	
 	// LLUpdateDownloader::Client
-	void downloadComplete(void) { retry(); }
+	void downloadComplete(LLSD const & data) { retry(); }
 	void downloadError(std::string const & message) { retry(); }	
 
 	bool onMainLoop(LLSD const & event);	
-- 
cgit v1.2.3


From 6f7183cd4422a008554afd854dc631fe575ad8dc Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Fri, 5 Nov 2010 13:56:36 -0700
Subject: Fixed windows build error.

---
 indra/viewer_components/updater/llupdatedownloader.cpp | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 102f2f9eec..75f896cc76 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -201,8 +201,7 @@ void LLUpdateDownloader::Implementation::resume(void)
 		return;
 	}
 	
-	LLSDSerialize parser;
-	parser.fromXMLDocument(mDownloadData, dataStream);
+	LLSDSerialize::fromXMLDocument(mDownloadData, dataStream);
 	
 	if(!mDownloadData.asBoolean()) {
 		mClient.downloadError("no download information in marker");
@@ -248,8 +247,7 @@ void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
 			
 			mDownloadData["size"] = LLSD(LLSD::Integer(size));
 			llofstream odataStream(mDownloadRecordPath);
-			LLSDSerialize parser;
-			parser.toPrettyXML(mDownloadData, odataStream);
+			LLSDSerialize::toPrettyXML(mDownloadData, odataStream);
 		} catch (std::exception const & e) {
 			LL_WARNS("UpdateDownload") << "unable to read content length (" 
 				<< e.what() << ")" << LL_ENDL;
@@ -346,8 +344,7 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std
 	LL_INFOS("UpdateDownload") << "hash of file is " << hash << LL_ENDL;
 		
 	llofstream dataStream(mDownloadRecordPath);
-	LLSDSerialize parser;
-	parser.toPrettyXML(mDownloadData, dataStream);
+	LLSDSerialize::toPrettyXML(mDownloadData, dataStream);
 	
 	mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary);
 	initializeCurlGet(uri.asString(), true);
-- 
cgit v1.2.3


From a13acfc9073b0e29d84e1633fc11ff08e285be8f Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Fri, 5 Nov 2010 15:08:27 -0700
Subject: Fixed build error due to unreferenced local variable.

---
 indra/viewer_components/updater/llupdatedownloader.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 75f896cc76..efb55ab83a 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -158,7 +158,7 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
 	mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath())
 {
 	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
-	llassert(code = CURLE_OK); // TODO: real error handling here. 
+	llverify(code == CURLE_OK); // TODO: real error handling here. 
 }
 
 
-- 
cgit v1.2.3


From 02c362b8ccad08f290ca99a738ca6ad1546c7df6 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 5 Nov 2010 15:56:33 -0700
Subject: implement download cancel (untested).

---
 .../updater/llupdatedownloader.cpp                 | 37 +++++++++++++++-------
 .../viewer_components/updater/llupdatedownloader.h |  3 +-
 2 files changed, 27 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 102f2f9eec..eaef230a8f 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,28 +138,27 @@ 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())
 {
 	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
-	llassert(code = CURLE_OK); // TODO: real error handling here. 
+	llassert(code == CURLE_OK); // TODO: real error handling here. 
 }
 
 
@@ -170,7 +170,7 @@ LLUpdateDownloader::Implementation::~Implementation()
 
 void LLUpdateDownloader::Implementation::cancel(void)
 {
-	llassert(!"not implemented");
+	mCancelled = true;
 }
 	
 
@@ -231,12 +231,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 {
@@ -257,20 +257,25 @@ 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);
 	if(code == CURLE_OK) {
+		LLFile::remove(mDownloadRecordPath);
 		if(validateDownload()) {
 			LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
 			mClient.downloadComplete(mDownloadData);
@@ -280,9 +285,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");
 	}
 }
@@ -381,6 +390,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 dc8ecc378a..491a638f9a 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.
-- 
cgit v1.2.3


From 1a711b3fd5912776424012fcfcb472baf6c195af Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Fri, 5 Nov 2010 18:33:25 -0700
Subject: "Fix" for linux link errors due to library ordering problems on the
 linker command line.

---
 indra/viewer_components/updater/CMakeLists.txt | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 64a0f98c2a..563b64655d 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -49,7 +49,6 @@ target_link_libraries(llupdaterservice
     ${LLMESSAGE_LIBRARIES}
     ${LLPLUGIN_LIBRARIES}
 	${LLVFS_LIBRARIES}
-	${CURL_LIBRARIES}
     )
 
 if(LL_TESTS)
-- 
cgit v1.2.3


From e1016b5bc7cda03fed98b10f1ee5615245495e00 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Mon, 8 Nov 2010 09:49:38 -0800
Subject: Removed refrences to SLPlugin from LLUpdaterService and test.

---
 .../viewer_components/updater/llupdaterservice.cpp | 30 ----------------------
 .../updater/tests/llupdaterservice_test.cpp        | 18 -------------
 2 files changed, 48 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index dc48606cbc..4292da1528 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -31,7 +31,6 @@
 #include "llupdaterservice.h"
 #include "llupdatechecker.h"
 
-#include "llpluginprocessparent.h"
 #include <boost/scoped_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 
@@ -42,7 +41,6 @@
 boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
 
 class LLUpdaterServiceImpl : 
-	public LLPluginProcessParentOwner,
 	public LLUpdateChecker::Client,
 	public LLUpdateDownloader::Client
 {
@@ -56,7 +54,6 @@ class LLUpdaterServiceImpl :
 	
 	unsigned int mCheckPeriod;
 	bool mIsChecking;
-	boost::scoped_ptr<LLPluginProcessParent> mPlugin;
 	
 	LLUpdateChecker mUpdateChecker;
 	LLUpdateDownloader mUpdateDownloader;
@@ -70,12 +67,6 @@ public:
 	LLUpdaterServiceImpl();
 	virtual ~LLUpdaterServiceImpl();
 
-	// LLPluginProcessParentOwner interfaces
-	virtual void receivePluginMessage(const LLPluginMessage &message);
-	virtual bool receivePluginMessageEarly(const LLPluginMessage &message);
-	virtual void pluginLaunchFailed();
-	virtual void pluginDied();
-
 	void setParams(const std::string& protocol_version,
 				   const std::string& url, 
 				   const std::string& path,
@@ -110,12 +101,9 @@ const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
 LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
 	mCheckPeriod(0),
-	mPlugin(0),
 	mUpdateChecker(*this),
 	mUpdateDownloader(*this)
 {
-	// Create the plugin parent, this is the owner.
-	mPlugin.reset(new LLPluginProcessParent(this));
 }
 
 LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
@@ -124,24 +112,6 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
 	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 }
 
-// LLPluginProcessParentOwner interfaces
-void LLUpdaterServiceImpl::receivePluginMessage(const LLPluginMessage &message)
-{
-}
-
-bool LLUpdaterServiceImpl::receivePluginMessageEarly(const LLPluginMessage &message) 
-{
-	return false;
-};
-
-void LLUpdaterServiceImpl::pluginLaunchFailed() 
-{
-};
-
-void LLUpdaterServiceImpl::pluginDied() 
-{
-};
-
 void LLUpdaterServiceImpl::setParams(const std::string& protocol_version,
 									 const std::string& url, 
 									 const std::string& path,
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 20d0f8fa09..7f45ae51fb 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -36,28 +36,10 @@
 #include "../../../test/debug.h"
 
 #include "llevents.h"
-#include "llpluginprocessparent.h"
 
 /*****************************************************************************
 *   MOCK'd
 *****************************************************************************/
-LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {}
-LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
-: mOwner(owner),
-  mIncomingQueueMutex(gAPRPoolp)
-{
-}
-
-LLPluginProcessParent::~LLPluginProcessParent() {}
-LLPluginMessagePipeOwner::LLPluginMessagePipeOwner(){}
-LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner(){}
-void LLPluginProcessParent::receiveMessageRaw(const std::string &message) {}
-int LLPluginMessagePipeOwner::socketError(int) { return 0; }
-void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {}
-void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {}
-LLPluginMessage::~LLPluginMessage() {}
-LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {}
-
 LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
 {}
 void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, 
-- 
cgit v1.2.3


From 0836d1b1ae861ee7a226ba342166148a31cc5bdd Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Mon, 8 Nov 2010 15:51:39 -0800
Subject: Fix for linux link errors in teamcity.

---
 indra/newview/CMakeLists.txt | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f18107f673..ff099710f1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1643,7 +1643,14 @@ if (WINDOWS)
     endif (PACKAGE)
 endif (WINDOWS)
 
+# *NOTE - this list is very sensitive to ordering, test carefully on all
+# platforms if you change the releative order of the entries here.
+# In particular, cmake 2.6.4 (when buidling with linux/makefile generators)
+# appears to sometimes de-duplicate redundantly listed dependencies improperly.
+# To work around this, higher level modules should be listed before the modules
+# that they depend upon. -brad
 target_link_libraries(${VIEWER_BINARY_NAME}
+    ${UPDATER_LIBRARIES}
     ${LLAUDIO_LIBRARIES}
     ${LLCHARACTER_LIBRARIES}
     ${LLIMAGE_LIBRARIES}
@@ -1680,7 +1687,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${OPENSSL_LIBRARIES}
     ${CRYPTO_LIBRARIES}
     ${LLLOGIN_LIBRARIES}
-    ${UPDATER_LIBRARIES}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     )
 
-- 
cgit v1.2.3


From d681ea89d27e0e37d77c7f57c9bc66fda3f08f4e Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 8 Nov 2010 16:10:54 -0800
Subject: Get rid of intrusive_ptr member to prevent crash on shutdown.

---
 indra/viewer_components/updater/llupdatechecker.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

(limited to 'indra')

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,
-- 
cgit v1.2.3


From 8cce8827e01dab6bfcd3e94e56b6041f8f487c76 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Mon, 8 Nov 2010 17:12:43 -0800
Subject: Fix for breakpad symbol files failing to be generated on linux.

---
 indra/newview/CMakeLists.txt               | 8 ++++----
 indra/newview/generate_breakpad_symbols.py | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ff099710f1..a9d1fd9064 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1837,13 +1837,13 @@ if (PACKAGE)
     set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
   endif (LINUX)
 
-  if(CMAKE_CONFIGURATION_TYPES)
+  if(CMAKE_CFG_INTDIR STREQUAL ".")
+      set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
+  else(CMAKE_CFG_INTDIR STREQUAL ".")
       # set LLBUILD_CONFIG to be a shell variable evaluated at build time
       # reflecting the configuration we are currently building.
       set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
-  else(CMAKE_CONFIGURATION_TYPES)
-      set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
-  endif(CMAKE_CONFIGURATION_TYPES)
+  endif(CMAKE_CFG_INTDIR STREQUAL ".")
   add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
     COMMAND "${PYTHON_EXECUTABLE}"
     ARGS
diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py
index 0e61bee1ef..4fd04d780e 100644
--- a/indra/newview/generate_breakpad_symbols.py
+++ b/indra/newview/generate_breakpad_symbols.py
@@ -31,6 +31,7 @@ import fnmatch
 import itertools
 import operator
 import os
+import re
 import sys
 import shlex
 import subprocess
@@ -48,7 +49,7 @@ class MissingModuleError(Exception):
 def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
     print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
 
-    if configuration != "Release":
+    if not re.match("release", configuration, re.IGNORECASE):
         print "skipping breakpad symbol generation for non-release build."
         return 0
 
-- 
cgit v1.2.3


From 2cfcdfe2ffd97384324c940447a4197cbf85a38e Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 9 Nov 2010 09:14:50 -0800
Subject: Fix some stream bugs that were affecting windows download and
 validation.

---
 indra/viewer_components/updater/llupdatedownloader.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index ca1d2d25de..2794f80c47 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -272,6 +272,7 @@ size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
 void LLUpdateDownloader::Implementation::run(void)
 {
 	CURLcode code = curl_easy_perform(mCurl);
+	mDownloadStream.close();
 	if(code == CURLE_OK) {
 		LLFile::remove(mDownloadRecordPath);
 		if(validateDownload()) {
@@ -379,7 +380,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();
-- 
cgit v1.2.3


From 73b6d4d058107137425cd202e79fb0a2d9c22896 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 9 Nov 2010 11:15:01 -0800
Subject: Fix crash if thread is manually shut down before it is destroyed.

---
 indra/llcommon/llthread.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index d7b7c3699c..2408be74b9 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -153,10 +153,12 @@ void LLThread::shutdown()
 	}
 
 	delete mRunCondition;
+	mRunCondition = 0;
 	
-	if (mIsLocalPool)
+	if (mIsLocalPool && mAPRPoolp)
 	{
 		apr_pool_destroy(mAPRPoolp);
+		mAPRPoolp = 0;
 	}
 }
 
-- 
cgit v1.2.3


From 5da253fdde8737361333161517c1173358bd17ff Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 9 Nov 2010 11:16:28 -0800
Subject: Shut down thread if viewer closed while downloading; fix problem of
 download marker path failing to expand correctly because it was happening too
 early in start up.

---
 indra/viewer_components/updater/llupdatedownloader.cpp | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 2794f80c47..208cc48c12 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -154,8 +154,7 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::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,6 +163,12 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
 
 LLUpdateDownloader::Implementation::~Implementation()
 {
+	if(isDownloading()) {
+		cancel();
+		shutdown();
+	} else {
+		; // No op.
+	}
 	if(mCurl) curl_easy_cleanup(mCurl);
 }
 
@@ -177,7 +182,8 @@ void LLUpdateDownloader::Implementation::cancel(void)
 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");
-- 
cgit v1.2.3


From fdf616c59d87219e2d5ad6e12687cf2793cfba1e Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 9 Nov 2010 11:23:32 -0800
Subject: beginnings of the update installer (with simple install script for
 darwin).

---
 indra/newview/viewer_manifest.py                   |  4 +++
 indra/viewer_components/updater/CMakeLists.txt     | 23 ++++++++----
 .../updater/llupdateinstaller.cpp                  | 38 ++++++++++++++++++++
 .../viewer_components/updater/llupdateinstaller.h  | 42 ++++++++++++++++++++++
 .../updater/scripts/darwin/update_install          |  6 ++++
 5 files changed, 107 insertions(+), 6 deletions(-)
 create mode 100644 indra/viewer_components/updater/llupdateinstaller.cpp
 create mode 100644 indra/viewer_components/updater/llupdateinstaller.h
 create mode 100755 indra/viewer_components/updater/scripts/darwin/update_install

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 4596938775..f95697adb6 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -575,6 +575,10 @@ class DarwinManifest(ViewerManifest):
             # most everything goes in the Resources directory
             if self.prefix(src="", dst="Resources"):
                 super(DarwinManifest, self).construct()
+		
+                if self.prefix(src="../viewer_components/updater", dst=""):
+                    self.path("update_install")
+                    self.end_prefix()
 
                 if self.prefix("cursors_mac"):
                     self.path("*.tif")
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 563b64655d..c3607dff39 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}
@@ -56,12 +59,6 @@ if(LL_TESTS)
       llupdaterservice.cpp
       )
 
-#  set_source_files_properties(
-#    llupdaterservice.cpp
-#    PROPERTIES
-#      LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}"
-#    )
-
   LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}")
 endif(LL_TESTS)
 
@@ -74,3 +71,17 @@ 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})
+
+
+ 
\ No newline at end of file
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
new file mode 100644
index 0000000000..4d7c78d36c
--- /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();
+}
\ No newline at end of file
diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h
new file mode 100644
index 0000000000..a6068e9025
--- /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
\ No newline at end of file
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install
new file mode 100755
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
-- 
cgit v1.2.3


From 656b936915d5fd29f213f8eb7cd3873baed19109 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 9 Nov 2010 14:40:32 -0500
Subject: Add name, value info to convert_from_llsd<> specialization LL_ERRS.
 Prior to this, you could get a viewer crash whose ERROR: message said only:
 convert_from_llsd<std::string>: Invalid string value This gave no hint as to
 *which value* was wrong, or where to go fix it. Ironically, each
 convert_from_llsd<> specialization already has the control_name and LLSD
 value in hand; added these to each such LL_ERRS message.

---
 indra/llxml/llcontrol.cpp | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index f9a39826f5..27c694dde9 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -1107,7 +1107,7 @@ bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::strin
 		return sd.asBoolean();
 	else
 	{
-		CONTROL_ERRS << "Invalid BOOL value" << llendl;
+		CONTROL_ERRS << "Invalid BOOL value for " << control_name << ": " << sd << llendl;
 		return FALSE;
 	}
 }
@@ -1119,7 +1119,7 @@ S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string&
 		return sd.asInteger();
 	else
 	{
-		CONTROL_ERRS << "Invalid S32 value" << llendl;
+		CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << sd << llendl;
 		return 0;
 	}
 }
@@ -1131,7 +1131,7 @@ U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type, const std::string&
 		return sd.asInteger();
 	else
 	{
-		CONTROL_ERRS << "Invalid U32 value" << llendl;
+		CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << sd << llendl;
 		return 0;
 	}
 }
@@ -1143,7 +1143,7 @@ F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type, const std::string&
 		return (F32) sd.asReal();
 	else
 	{
-		CONTROL_ERRS << "Invalid F32 value" << llendl;
+		CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << sd << llendl;
 		return 0.0f;
 	}
 }
@@ -1155,7 +1155,7 @@ std::string convert_from_llsd<std::string>(const LLSD& sd, eControlType type, co
 		return sd.asString();
 	else
 	{
-		CONTROL_ERRS << "Invalid string value" << llendl;
+		CONTROL_ERRS << "Invalid string value for " << control_name << ": " << sd << llendl;
 		return LLStringUtil::null;
 	}
 }
@@ -1173,7 +1173,7 @@ LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const
 		return (LLVector3)sd;
 	else
 	{
-		CONTROL_ERRS << "Invalid LLVector3 value" << llendl;
+		CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << sd << llendl;
 		return LLVector3::zero;
 	}
 }
@@ -1185,7 +1185,7 @@ LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, cons
 		return (LLVector3d)sd;
 	else
 	{
-		CONTROL_ERRS << "Invalid LLVector3d value" << llendl;
+		CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << sd << llendl;
 		return LLVector3d::zero;
 	}
 }
@@ -1197,7 +1197,7 @@ LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::s
 		return LLRect(sd);
 	else
 	{
-		CONTROL_ERRS << "Invalid rect value" << llendl;
+		CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << sd << llendl;
 		return LLRect::null;
 	}
 }
@@ -1211,19 +1211,19 @@ LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const st
 		LLColor4 color(sd);
 		if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " red value out of range: " << color << llendl;
 		}
 		else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " green value out of range: " << color << llendl;
 		}
 		else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " blue value out of range: " << color << llendl;
 		}
 		else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl;
 		}
 
 		return LLColor4(sd);
@@ -1242,7 +1242,7 @@ LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd, eControlType type, const st
 		return sd;
 	else
 	{
-		CONTROL_ERRS << "Invalid LLColor3 value" << llendl;
+		CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << sd << llendl;
 		return LLColor3::white;
 	}
 }
-- 
cgit v1.2.3


From 9ae2891a3afefcbf0c72cadaef203426cb0e5954 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 9 Nov 2010 15:04:44 -0800
Subject: start of a thread safe queue

---
 indra/llcommon/CMakeLists.txt        |   2 +
 indra/llcommon/llthreadsafequeue.cpp | 109 +++++++++++++++++++
 indra/llcommon/llthreadsafequeue.h   | 205 +++++++++++++++++++++++++++++++++++
 indra/newview/CMakeLists.txt         |   2 +
 indra/newview/llappviewer.cpp        |   5 +
 indra/newview/llmainlooprepeater.cpp |  82 ++++++++++++++
 indra/newview/llmainlooprepeater.h   |  65 +++++++++++
 7 files changed, 470 insertions(+)
 create mode 100644 indra/llcommon/llthreadsafequeue.cpp
 create mode 100644 indra/llcommon/llthreadsafequeue.h
 create mode 100644 indra/newview/llmainlooprepeater.cpp
 create mode 100644 indra/newview/llmainlooprepeater.h

(limited to 'indra')

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 7bad780dd8..7d53667f35 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -92,6 +92,7 @@ set(llcommon_SOURCE_FILES
     llstringtable.cpp
     llsys.cpp
     llthread.cpp
+    llthreadsafequeue.cpp
     lltimer.cpp
     lluri.cpp
     lluuid.cpp
@@ -223,6 +224,7 @@ set(llcommon_HEADER_FILES
     llstringtable.h
     llsys.h
     llthread.h
+    llthreadsafequeue.h
     lltimer.h
     lltreeiterators.h
     lluri.h
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
new file mode 100644
index 0000000000..a7141605ef
--- /dev/null
+++ b/indra/llcommon/llthreadsafequeue.cpp
@@ -0,0 +1,109 @@
+/** 
+ * @file llthread.cpp
+ *
+ * $LicenseInfo:firstyear=2004&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_pools.h>
+#include <apr_queue.h>
+#include "llthreadsafequeue.h"
+
+
+
+// LLThreadSafeQueueImplementation
+//-----------------------------------------------------------------------------
+
+
+LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
+	mOwnsPool(pool == 0),
+	mPool(pool),
+	mQueue(0)
+{
+	if(mOwnsPool) {
+		apr_status_t status = apr_pool_create(&mPool, 0);
+		if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool");
+	} else {
+		; // No op.
+	}
+	
+	apr_status_t status = apr_queue_create(&mQueue, capacity, mPool);
+	if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
+}
+
+
+LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
+{
+	if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
+	if(mQueue != 0) {
+		if(apr_queue_size(mQueue) != 0) llwarns << 
+			"terminating queue which still contains elements;" << 
+			"memory will be leaked" << LL_ENDL;
+		apr_queue_term(mQueue);
+	}
+}
+
+
+void LLThreadSafeQueueImplementation::pushFront(void * element)
+{
+	apr_status_t status = apr_queue_push(mQueue, element);
+	
+	if(status == APR_EINTR) {
+		throw LLThreadSafeQueueInterrupt();
+	} else if(status != APR_SUCCESS) {
+		throw LLThreadSafeQueueError("push failed");
+	} else {
+		; // Success.
+	}
+}
+
+
+bool LLThreadSafeQueueImplementation::tryPushFront(void * element){
+	return apr_queue_trypush(mQueue, element) == APR_SUCCESS;
+}
+
+
+void * LLThreadSafeQueueImplementation::popBack(void)
+{
+	void * element;
+	apr_status_t status = apr_queue_pop(mQueue, &element);
+
+	if(status == APR_EINTR) {
+		throw LLThreadSafeQueueInterrupt();
+	} else if(status != APR_SUCCESS) {
+		throw LLThreadSafeQueueError("pop failed");
+	} else {
+		return element;
+	}
+}
+
+
+bool LLThreadSafeQueueImplementation::tryPopBack(void *& element)
+{
+	return apr_queue_trypop(mQueue, &element) == APR_SUCCESS;
+}
+
+
+size_t LLThreadSafeQueueImplementation::size()
+{
+	return apr_queue_size(mQueue);
+}
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
new file mode 100644
index 0000000000..46c8b91932
--- /dev/null
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -0,0 +1,205 @@
+/** 
+ * @file llthreadsafequeue.h
+ * @brief Base classes for thread, mutex and condition handling.
+ *
+ * $LicenseInfo:firstyear=2004&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_LLTHREADSAFEQUEUE_H
+#define LL_LLTHREADSAFEQUEUE_H
+
+
+#include <string>
+#include <stdexcept>
+
+
+struct apr_pool_t; // From apr_pools.h
+class LLThreadSafeQueueImplementation; // See below.
+
+
+//
+// A general queue exception.
+//
+class LLThreadSafeQueueError:
+public std::runtime_error
+{
+public:
+	LLThreadSafeQueueError(std::string const & message):
+	std::runtime_error(message)
+	{
+		; // No op.
+	}
+};
+
+
+//
+// An exception raised when blocking operations are interrupted.
+//
+class LLThreadSafeQueueInterrupt:
+	public LLThreadSafeQueueError
+{
+public:
+	LLThreadSafeQueueInterrupt(void):
+		LLThreadSafeQueueError("queue operation interrupted")
+	{
+		; // No op.
+	}
+};
+
+
+struct apr_queue_t; // From apr_queue.h
+
+
+//
+// Implementation details. 
+//
+class LLThreadSafeQueueImplementation
+{
+public:
+	LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
+	~LLThreadSafeQueueImplementation();
+	void pushFront(void * element);
+	bool tryPushFront(void * element);
+	void * popBack(void);
+	bool tryPopBack(void *& element);
+	size_t size();
+	
+private:
+	bool mOwnsPool;
+	apr_pool_t * mPool;
+	apr_queue_t * mQueue;
+};
+
+
+//
+// Implements a thread safe FIFO.
+//
+template<typename ElementT>
+class LLThreadSafeQueue
+{
+public:
+	typedef ElementT value_type;
+	
+	// If the pool is set to NULL one will be allocated and managed by this
+	// queue.
+	LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024);
+	
+	// Add an element to the front of queue (will block if the queue has
+	// reached capacity).
+	//
+	// This call will raise an interrupt error if the queue is deleted while
+	// the caller is blocked.
+	void pushFront(ElementT const & element);
+	
+	// Try to add an element to the front ofqueue without blocking. Returns
+	// true only if the element was actually added.
+	bool tryPushFront(ElementT const & element);
+	
+	// Pop the element at the end of the queue (will block if the queue is
+	// empty).
+	//
+	// This call will raise an interrupt error if the queue is deleted while
+	// the caller is blocked.
+	ElementT popBack(void);
+	
+	// Pop an element from the end of the queue if there is one available.
+	// Returns true only if an element was popped.
+	bool tryPopBack(ElementT & element);
+	
+	// Returns the size of the queue.
+	size_t size();
+
+private:
+	LLThreadSafeQueueImplementation mImplementation;
+};
+
+
+
+// LLThreadSafeQueue
+//-----------------------------------------------------------------------------
+
+
+template<typename ElementT>
+LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
+	mImplementation(pool, capacity)
+{
+	; // No op.
+}
+
+
+template<typename ElementT>
+void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element)
+{
+	ElementT * elementCopy = new ElementT(element);
+	try {
+		mImplementation.pushFront(elementCopy);
+	} catch (LLThreadSafeQueueInterrupt) {
+		delete elementCopy;
+		throw;
+	}
+}
+
+
+template<typename ElementT>
+bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element)
+{
+	ElementT * elementCopy = new ElementT(element);
+	bool result = mImplementation.tryPushFront(elementCopy);
+	if(!result) delete elementCopy;
+	return result;
+}
+
+
+template<typename ElementT>
+ElementT LLThreadSafeQueue<ElementT>::popBack(void)
+{
+	ElementT * element = reinterpret_cast<ElementT *> (mImplementation.popBack());
+	ElementT result(*element);
+	delete element;
+	return result;
+}
+
+
+template<typename ElementT>
+bool LLThreadSafeQueue<ElementT>::tryPopBack(ElementT & element)
+{
+	void * storedElement;
+	bool result = mImplementation.tryPopBack(storedElement);
+	if(result) {
+		ElementT * elementPtr = reinterpret_cast<ElementT *>(storedElement); 
+		element = *elementPtr;
+		delete elementPtr;
+	} else {
+		; // No op.
+	}
+	return result;
+}
+
+
+template<typename ElementT>
+size_t LLThreadSafeQueue<ElementT>::size(void)
+{
+	return mImplementation.size();
+}
+
+
+#endif
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a9d1fd9064..36cfa615f0 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -283,6 +283,7 @@ set(viewer_SOURCE_FILES
     llloginhandler.cpp
     lllogininstance.cpp
     llmachineid.cpp
+    llmainlooprepeater.cpp
     llmanip.cpp
     llmaniprotate.cpp
     llmanipscale.cpp
@@ -815,6 +816,7 @@ set(viewer_HEADER_FILES
     llloginhandler.h
     lllogininstance.h
     llmachineid.h
+    llmainlooprepeater.h
     llmanip.h
     llmaniprotate.h
     llmanipscale.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c0ec15f436..438f8668ae 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -197,6 +197,8 @@
 #include "llsecapi.h"
 #include "llmachineid.h"
 
+#include "llmainlooprepeater.h"
+
 // *FIX: These extern globals should be cleaned up.
 // The globals either represent state/config/resource-storage of either 
 // this app, or another 'component' of the viewer. App globals should be 
@@ -801,6 +803,9 @@ bool LLAppViewer::init()
 		return 1;
 	}
 	
+	// Initialize the repeater service.
+	LLMainLoopRepeater::getInstance()->start();
+	
 	//
 	// Initialize the window
 	//
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
new file mode 100644
index 0000000000..c2eba97641
--- /dev/null
+++ b/indra/newview/llmainlooprepeater.cpp
@@ -0,0 +1,82 @@
+/** 
+ * @file llmachineid.cpp
+ * @brief retrieves unique machine ids
+ *
+ * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
+#include "llapr.h"
+#include "llevents.h"
+#include "llmainlooprepeater.h"
+
+
+
+// LLMainLoopRepeater
+//-----------------------------------------------------------------------------
+
+
+LLMainLoopRepeater::LLMainLoopRepeater(void):
+	mQueue(gAPRPoolp, 1024)
+{
+	; // No op.
+}
+
+
+void LLMainLoopRepeater::start(void)
+{
+	mMainLoopConnection = LLEventPumps::instance().
+		obtain("mainloop").listen("stupid name here", boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
+	mRepeaterConnection = LLEventPumps::instance().
+		obtain("mainlooprepeater").listen("other stupid name here", boost::bind(&LLMainLoopRepeater::onMessage, this, _1));
+}
+
+
+void LLMainLoopRepeater::stop(void)
+{
+	mMainLoopConnection.release();
+	mRepeaterConnection.release();
+}
+
+
+bool LLMainLoopRepeater::onMainLoop(LLSD const &)
+{
+	LLSD message;
+	while(mQueue.tryPopBack(message)) {
+		std::string pump = message["pump"].asString();
+		if(pump.length() == 0 ) continue; // No pump.
+		LLEventPumps::instance().obtain(pump).post(message["payload"]);
+	}
+	return false;
+}
+
+
+bool LLMainLoopRepeater::onMessage(LLSD const & event)
+{
+	try {
+		mQueue.pushFront(event);
+	} catch(LLThreadSafeQueueError & e) {
+		llwarns << "could not repeat message (" << e.what() << ")" << 
+			event.asString() << LL_ENDL;
+	}
+	return false;
+}
diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h
new file mode 100644
index 0000000000..96b83b4916
--- /dev/null
+++ b/indra/newview/llmainlooprepeater.h
@@ -0,0 +1,65 @@
+/** 
+ * @file llmainlooprepeater.h
+ * @brief a service for repeating messages on the main loop.
+ *
+ * $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_LLMAINLOOPREPEATER_H
+#define LL_LLMAINLOOPREPEATER_H
+
+
+#include "llsd.h"
+#include "llthreadsafequeue.h"
+
+
+//
+// A service which creates the pump 'mainlooprepeater' to which any thread can
+// post a message that will be re-posted on the main loop.
+//
+// The posted message should contain two map elements: pump and payload.  The
+// pump value is a string naming the pump to which the message should be
+// re-posted.  The payload value is what will be posted to the designated pump.
+//
+class LLMainLoopRepeater:
+	public LLSingleton<LLMainLoopRepeater>
+{
+public:
+	LLMainLoopRepeater(void);
+	
+	// Start the repeater service.
+	void start(void);
+	
+	// Stop the repeater service.
+	void stop(void);
+	
+private:
+	LLTempBoundListener mMainLoopConnection;
+	LLTempBoundListener mRepeaterConnection;
+	LLThreadSafeQueue<LLSD> mQueue;
+	
+	bool onMainLoop(LLSD const &);
+	bool onMessage(LLSD const & event);
+};
+
+
+#endif
-- 
cgit v1.2.3


From 3493da8c41a157f2cd52632c2ac69b67e4091644 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Tue, 9 Nov 2010 17:42:05 -0800
Subject: Fix for linux eol failures.

---
 indra/viewer_components/updater/llupdateinstaller.cpp | 2 +-
 indra/viewer_components/updater/llupdateinstaller.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index 4d7c78d36c..1bb2101df1 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -35,4 +35,4 @@ void ll_install_update(std::string const & script, std::string const & updatePat
 	launcher.addArgument(updatePath);
 	launcher.launch();
 	launcher.orphan();
-}
\ No newline at end of file
+}
diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h
index a6068e9025..991fe2afe1 100644
--- a/indra/viewer_components/updater/llupdateinstaller.h
+++ b/indra/viewer_components/updater/llupdateinstaller.h
@@ -39,4 +39,4 @@
 void ll_install_update(std::string const & script, std::string const & updatePath);
 
 
-#endif
\ No newline at end of file
+#endif
-- 
cgit v1.2.3


From e87b447a0ca7c6e4aeb5f87e6767db918682499c Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Tue, 9 Nov 2010 17:42:13 -0800
Subject: Fix for dll linkage errors.

---
 indra/llcommon/llthreadsafequeue.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 46c8b91932..58cac38769 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -39,7 +39,7 @@ class LLThreadSafeQueueImplementation; // See below.
 //
 // A general queue exception.
 //
-class LLThreadSafeQueueError:
+class LL_COMMON_API LLThreadSafeQueueError:
 public std::runtime_error
 {
 public:
@@ -54,7 +54,7 @@ public:
 //
 // An exception raised when blocking operations are interrupted.
 //
-class LLThreadSafeQueueInterrupt:
+class LL_COMMON_API LLThreadSafeQueueInterrupt:
 	public LLThreadSafeQueueError
 {
 public:
@@ -72,7 +72,7 @@ struct apr_queue_t; // From apr_queue.h
 //
 // Implementation details. 
 //
-class LLThreadSafeQueueImplementation
+class LL_COMMON_API LLThreadSafeQueueImplementation
 {
 public:
 	LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
-- 
cgit v1.2.3


From deaaad5e3350a57153d7eaf8635e492ab1062c27 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Wed, 10 Nov 2010 10:03:37 -0800
Subject: Add dependency to fix viewer manifest exception in build modes other
 than all.

---
 indra/viewer_components/updater/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index c3607dff39..7657dd4517 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -82,6 +82,7 @@ if(DARWIN)
 		)
 endif()
 add_custom_target(copy_update_install ALL DEPENDS ${update_installer_targets})
+add_dependencies(llupdaterservice copy_update_install)
 
 
  
\ No newline at end of file
-- 
cgit v1.2.3


From f42bb00627f756b277496ec203d567cac31b3438 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Wed, 10 Nov 2010 14:25:03 -0800
Subject: CHOP-151 Imported patch from server-trunk to support preprocessor at
 unit tests. Rev. by Brad

---
 indra/cmake/LLAddBuildTest.cmake | 538 ++++++++++++++++++++-------------------
 1 file changed, 273 insertions(+), 265 deletions(-)

(limited to 'indra')

diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 79c3bb7da2..29e2492551 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -1,265 +1,273 @@
-# -*- cmake -*-
-include(LLTestCommand)
-include(GoogleMock)
-
-MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
-  # Given a project name and a list of sourcefiles (with optional properties on each),
-  # add targets to build and run the tests specified.
-  # ASSUMPTIONS:
-  # * this macro is being executed in the project file that is passed in
-  # * current working SOURCE dir is that project dir
-  # * there is a subfolder tests/ with test code corresponding to the filenames passed in
-  # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT)
-  #
-  # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code
-  #
-  # WARNING: do NOT modify this code without working with poppy -
-  # there is another branch that will conflict heavily with any changes here.
-INCLUDE(GoogleMock)
-
-
-  IF(LL_TEST_VERBOSE)
-    MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
-  ENDIF(LL_TEST_VERBOSE)
-
-  # Start with the header and project-wide setup before making targets
-  #project(UNITTEST_PROJECT_${project})
-  # Setup includes, paths, etc
-  SET(alltest_SOURCE_FILES
-    ${CMAKE_SOURCE_DIR}/test/test.cpp
-    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
-    )
-  SET(alltest_DEP_TARGETS
-    # needed by the test harness itself
-    ${APRUTIL_LIBRARIES}
-    ${APR_LIBRARIES}
-    llcommon
-    )
-  IF(NOT "${project}" STREQUAL "llmath")
-    # add llmath as a dep unless the tested module *is* llmath!
-    LIST(APPEND alltest_DEP_TARGETS
-      llmath
-      )
-  ENDIF(NOT "${project}" STREQUAL "llmath")
-  SET(alltest_INCLUDE_DIRS
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LIBS_OPEN_DIR}/test
-    ${GOOGLEMOCK_INCLUDE_DIRS}
-    )
-  SET(alltest_LIBRARIES
-    ${GOOGLEMOCK_LIBRARIES}
-    ${PTHREAD_LIBRARY}
-    ${WINDOWS_LIBRARIES}
-    )
-  # Headers, for convenience in targets.
-  SET(alltest_HEADER_FILES
-    ${CMAKE_SOURCE_DIR}/test/test.h
-    )
-
-  # Use the default flags
-  if (LINUX)
-    SET(CMAKE_EXE_LINKER_FLAGS "")
-  endif (LINUX)
-
-  # start the source test executable definitions
-  SET(${project}_TEST_OUTPUT "")
-  FOREACH (source ${sources})
-    STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
-    STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
-    ENDIF(LL_TEST_VERBOSE)
-
-    #
-    # Per-codefile additional / external source, header, and include dir property extraction
-    #
-    # Source
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
-    IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
-      SET(${name}_test_additional_SOURCE_FILES "")
-    ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
-    SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} )
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
-    ENDIF(LL_TEST_VERBOSE)
-    # Headers
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
-    IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
-      SET(${name}_test_additional_HEADER_FILES "")
-    ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
-    SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
-    set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
-    LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
-    ENDIF(LL_TEST_VERBOSE)
-    # Include dirs
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
-    IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
-      SET(${name}_test_additional_INCLUDE_DIRS "")
-    ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
-    INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS )
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
-    ENDIF(LL_TEST_VERBOSE)
-
-
-    # Setup target
-    ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
-    SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
-
-    #
-    # Per-codefile additional / external project dep and lib dep property extraction
-    #
-    # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
-    # Projects
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
-    IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
-      SET(${name}_test_additional_PROJECTS "")
-    ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
-    # Libraries
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
-    IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
-      SET(${name}_test_additional_LIBRARIES "")
-    ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
-    ENDIF(LL_TEST_VERBOSE)
-    # Add to project
-    TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
-    
-    #
-    # Setup test targets
-    #
-    GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
-    SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
-    SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
-
-    # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19
-    IF(LL_TEST_VERBOSE)
-      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd  = ${TEST_CMD}")
-    ENDIF(LL_TEST_VERBOSE)
-
-    SET_TEST_PATH(LD_LIBRARY_PATH)
-    LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD})
-    IF(LL_TEST_VERBOSE)
-      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script  = ${TEST_SCRIPT_CMD}")
-    ENDIF(LL_TEST_VERBOSE)
-    # Add test 
-    ADD_CUSTOM_COMMAND(
-        OUTPUT ${TEST_OUTPUT}
-        COMMAND ${TEST_SCRIPT_CMD}
-        DEPENDS PROJECT_${project}_TEST_${name}
-        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-        )
-    # Why not add custom target and add POST_BUILD command?
-    # Slightly less uncertain behavior
-    # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
-    # > I did not use a post build step as I could not make it notify of a 
-    # > failure after the first time you build and fail a test. - daveh 2009-04-20
-    LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
-  ENDFOREACH (source)
-
-  # Add the test runner target per-project
-  # (replaces old _test_ok targets all over the place)
-  ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
-  ADD_DEPENDENCIES(${project} ${project}_tests)
-ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
-
-FUNCTION(LL_ADD_INTEGRATION_TEST 
-    testname
-    additional_source_files
-    library_dependencies
-# variable args
-    )
-  if(TEST_DEBUG)
-    message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
-  endif(TEST_DEBUG)
-  
-  SET(source_files
-    tests/${testname}_test.cpp
-    ${CMAKE_SOURCE_DIR}/test/test.cpp
-    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
-    ${additional_source_files}
-    )
-
-  SET(libraries
-    ${library_dependencies}
-    ${GOOGLEMOCK_LIBRARIES}
-    ${PTHREAD_LIBRARY}
-    )
-
-  # Add test executable build target
-  if(TEST_DEBUG)
-    message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
-  endif(TEST_DEBUG)
-  ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
-  SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
-
-  # Add link deps to the executable
-  if(TEST_DEBUG)
-    message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
-  endif(TEST_DEBUG)
-  TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
-
-  # Create the test running command
-  SET(test_command ${ARGN})
-  GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
-  LIST(FIND test_command "{}" test_exe_pos)
-  IF(test_exe_pos LESS 0)
-    # The {} marker means "the full pathname of the test executable."
-    # test_exe_pos -1 means we didn't find it -- so append the test executable
-    # name to $ARGN, the variable part of the arg list. This is convenient
-    # shorthand for both straightforward execution of the test program (empty
-    # $ARGN) and for running a "wrapper" program of some kind accepting the
-    # pathname of the test program as the last of its args. You need specify
-    # {} only if the test program's pathname isn't the last argument in the
-    # desired command line.
-    LIST(APPEND test_command "${TEST_EXE}")
-  ELSE (test_exe_pos LESS 0)
-    # Found {} marker at test_exe_pos. Remove the {}...
-    LIST(REMOVE_AT test_command test_exe_pos)
-    # ...and replace it with the actual name of the test executable.
-    LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
-  ENDIF (test_exe_pos LESS 0)
-
-  SET_TEST_PATH(LD_LIBRARY_PATH)
-  LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command})
-
-  if(TEST_DEBUG)
-    message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
-  endif(TEST_DEBUG)
-
-  ADD_CUSTOM_COMMAND(
-    TARGET INTEGRATION_TEST_${testname}
-    POST_BUILD
-    COMMAND ${TEST_SCRIPT_CMD}
-    )
-
-  # Use CTEST? Not sure how to yet...
-  # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
-
-ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
-
-MACRO(SET_TEST_PATH LISTVAR)
-  IF(WINDOWS)
-    # We typically build/package only Release variants of third-party
-    # libraries, so append the Release staging dir in case the library being
-    # sought doesn't have a debug variant.
-    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release)
-  ELSEIF(DARWIN)
-    # We typically build/package only Release variants of third-party
-    # libraries, so append the Release staging dir in case the library being
-    # sought doesn't have a debug variant.
-    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
-  ELSE(WINDOWS)
-    # Linux uses a single staging directory anyway.
-    IF (STANDALONE)
-      set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
-    ELSE (STANDALONE)
-      set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
-    ENDIF (STANDALONE)
-  ENDIF(WINDOWS)
-ENDMACRO(SET_TEST_PATH)
+# -*- cmake -*-
+include(LLTestCommand)
+include(GoogleMock)
+
+MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
+  # Given a project name and a list of sourcefiles (with optional properties on each),
+  # add targets to build and run the tests specified.
+  # ASSUMPTIONS:
+  # * this macro is being executed in the project file that is passed in
+  # * current working SOURCE dir is that project dir
+  # * there is a subfolder tests/ with test code corresponding to the filenames passed in
+  # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT)
+  #
+  # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code
+  #
+  # WARNING: do NOT modify this code without working with poppy -
+  # there is another branch that will conflict heavily with any changes here.
+INCLUDE(GoogleMock)
+
+
+  IF(LL_TEST_VERBOSE)
+    MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
+  ENDIF(LL_TEST_VERBOSE)
+
+  # Start with the header and project-wide setup before making targets
+  #project(UNITTEST_PROJECT_${project})
+  # Setup includes, paths, etc
+  SET(alltest_SOURCE_FILES
+    ${CMAKE_SOURCE_DIR}/test/test.cpp
+    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
+    )
+  SET(alltest_DEP_TARGETS
+    # needed by the test harness itself
+    ${APRUTIL_LIBRARIES}
+    ${APR_LIBRARIES}
+    llcommon
+    )
+  IF(NOT "${project}" STREQUAL "llmath")
+    # add llmath as a dep unless the tested module *is* llmath!
+    LIST(APPEND alltest_DEP_TARGETS
+      llmath
+      )
+  ENDIF(NOT "${project}" STREQUAL "llmath")
+  SET(alltest_INCLUDE_DIRS
+    ${LLMATH_INCLUDE_DIRS}
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LIBS_OPEN_DIR}/test
+    ${GOOGLEMOCK_INCLUDE_DIRS}
+    )
+  SET(alltest_LIBRARIES
+    ${GOOGLEMOCK_LIBRARIES}
+    ${PTHREAD_LIBRARY}
+    ${WINDOWS_LIBRARIES}
+    )
+  # Headers, for convenience in targets.
+  SET(alltest_HEADER_FILES
+    ${CMAKE_SOURCE_DIR}/test/test.h
+    )
+
+  # Use the default flags
+  if (LINUX)
+    SET(CMAKE_EXE_LINKER_FLAGS "")
+  endif (LINUX)
+
+  # start the source test executable definitions
+  SET(${project}_TEST_OUTPUT "")
+  FOREACH (source ${sources})
+    STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
+    STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
+    IF(LL_TEST_VERBOSE)
+      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
+    ENDIF(LL_TEST_VERBOSE)
+
+    #
+    # Per-codefile additional / external source, header, and include dir property extraction
+    #
+    # Source
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
+    IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
+      SET(${name}_test_additional_SOURCE_FILES "")
+    ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
+    SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} )
+    IF(LL_TEST_VERBOSE)
+      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
+    ENDIF(LL_TEST_VERBOSE)
+    # Headers
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
+    IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
+      SET(${name}_test_additional_HEADER_FILES "")
+    ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
+    SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
+    set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
+    LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
+    IF(LL_TEST_VERBOSE)
+      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
+    ENDIF(LL_TEST_VERBOSE)
+    # Include dirs
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
+    IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
+      SET(${name}_test_additional_INCLUDE_DIRS "")
+    ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
+    INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS )
+    IF(LL_TEST_VERBOSE)
+      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
+    ENDIF(LL_TEST_VERBOSE)
+
+
+    # Setup target
+    ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
+    SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
+
+    #
+    # Per-codefile additional / external project dep and lib dep property extraction
+    #
+    # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
+    # Projects
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
+    IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
+      SET(${name}_test_additional_PROJECTS "")
+    ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
+    # Libraries
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
+    IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
+      SET(${name}_test_additional_LIBRARIES "")
+    ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
+    IF(LL_TEST_VERBOSE)
+      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
+      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
+    ENDIF(LL_TEST_VERBOSE)
+    # Add to project
+    TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
+    # Compile-time Definitions
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
+     IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
+       SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} )
+       IF(LL_TEST_VERBOSE)
+         MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
+       ENDIF(LL_TEST_VERBOSE)
+     ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
+     
+    #
+    # Setup test targets
+    #
+    GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
+    SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
+    SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
+
+    # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19
+    IF(LL_TEST_VERBOSE)
+      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd  = ${TEST_CMD}")
+    ENDIF(LL_TEST_VERBOSE)
+
+    SET_TEST_PATH(LD_LIBRARY_PATH)
+    LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD})
+    IF(LL_TEST_VERBOSE)
+      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script  = ${TEST_SCRIPT_CMD}")
+    ENDIF(LL_TEST_VERBOSE)
+    # Add test 
+    ADD_CUSTOM_COMMAND(
+        OUTPUT ${TEST_OUTPUT}
+        COMMAND ${TEST_SCRIPT_CMD}
+        DEPENDS PROJECT_${project}_TEST_${name}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        )
+    # Why not add custom target and add POST_BUILD command?
+    # Slightly less uncertain behavior
+    # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
+    # > I did not use a post build step as I could not make it notify of a 
+    # > failure after the first time you build and fail a test. - daveh 2009-04-20
+    LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
+  ENDFOREACH (source)
+
+  # Add the test runner target per-project
+  # (replaces old _test_ok targets all over the place)
+  ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
+  ADD_DEPENDENCIES(${project} ${project}_tests)
+ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
+
+FUNCTION(LL_ADD_INTEGRATION_TEST 
+    testname
+    additional_source_files
+    library_dependencies
+# variable args
+    )
+  if(TEST_DEBUG)
+    message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
+  endif(TEST_DEBUG)
+  
+  SET(source_files
+    tests/${testname}_test.cpp
+    ${CMAKE_SOURCE_DIR}/test/test.cpp
+    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
+    ${additional_source_files}
+    )
+
+  SET(libraries
+    ${library_dependencies}
+    ${GOOGLEMOCK_LIBRARIES}
+    ${PTHREAD_LIBRARY}
+    )
+
+  # Add test executable build target
+  if(TEST_DEBUG)
+    message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
+  endif(TEST_DEBUG)
+  ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
+  SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
+
+  # Add link deps to the executable
+  if(TEST_DEBUG)
+    message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
+  endif(TEST_DEBUG)
+  TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
+
+  # Create the test running command
+  SET(test_command ${ARGN})
+  GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
+  LIST(FIND test_command "{}" test_exe_pos)
+  IF(test_exe_pos LESS 0)
+    # The {} marker means "the full pathname of the test executable."
+    # test_exe_pos -1 means we didn't find it -- so append the test executable
+    # name to $ARGN, the variable part of the arg list. This is convenient
+    # shorthand for both straightforward execution of the test program (empty
+    # $ARGN) and for running a "wrapper" program of some kind accepting the
+    # pathname of the test program as the last of its args. You need specify
+    # {} only if the test program's pathname isn't the last argument in the
+    # desired command line.
+    LIST(APPEND test_command "${TEST_EXE}")
+  ELSE (test_exe_pos LESS 0)
+    # Found {} marker at test_exe_pos. Remove the {}...
+    LIST(REMOVE_AT test_command test_exe_pos)
+    # ...and replace it with the actual name of the test executable.
+    LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
+  ENDIF (test_exe_pos LESS 0)
+
+  SET_TEST_PATH(LD_LIBRARY_PATH)
+  LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command})
+
+  if(TEST_DEBUG)
+    message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
+  endif(TEST_DEBUG)
+
+  ADD_CUSTOM_COMMAND(
+    TARGET INTEGRATION_TEST_${testname}
+    POST_BUILD
+    COMMAND ${TEST_SCRIPT_CMD}
+    )
+
+  # Use CTEST? Not sure how to yet...
+  # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
+
+ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
+
+MACRO(SET_TEST_PATH LISTVAR)
+  IF(WINDOWS)
+    # We typically build/package only Release variants of third-party
+    # libraries, so append the Release staging dir in case the library being
+    # sought doesn't have a debug variant.
+    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release)
+  ELSEIF(DARWIN)
+    # We typically build/package only Release variants of third-party
+    # libraries, so append the Release staging dir in case the library being
+    # sought doesn't have a debug variant.
+    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
+  ELSE(WINDOWS)
+    # Linux uses a single staging directory anyway.
+    IF (STANDALONE)
+      set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
+    ELSE (STANDALONE)
+      set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
+    ENDIF (STANDALONE)
+  ENDIF(WINDOWS)
+ENDMACRO(SET_TEST_PATH)
-- 
cgit v1.2.3


From b2e84d739b4f5c00b497e57e892fc10d78af8b76 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Wed, 10 Nov 2010 14:26:14 -0800
Subject: CHOP-151 Adding startup updater flow to drive update installation and
 resume.

---
 indra/newview/llappviewer.cpp                      |   2 +-
 indra/viewer_components/updater/CMakeLists.txt     |   7 +-
 .../viewer_components/updater/llupdatedownloader.h |   5 +
 .../viewer_components/updater/llupdaterservice.cpp | 111 +++++++++++++++++++--
 indra/viewer_components/updater/llupdaterservice.h |  20 +++-
 .../updater/tests/llupdaterservice_test.cpp        |  71 ++++++++++++-
 6 files changed, 195 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6bb25969a6..335998767c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2341,7 +2341,7 @@ void LLAppViewer::initUpdater()
 	std::string service_path = gSavedSettings.getString("UpdaterServicePath");
 	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
 
-	mUpdater->setParams(protocol_version, url, service_path, channel, version);
+	mUpdater->initialize(protocol_version, url, service_path, channel, version);
 	mUpdater->setCheckPeriod(check_period);
 	if(gSavedSettings.getBOOL("UpdaterServiceActive"))
 	{
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 64a0f98c2a..980599dd48 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -57,10 +57,13 @@ if(LL_TESTS)
       llupdaterservice.cpp
       )
 
-#  set_source_files_properties(
+# *NOTE:Mani - I was trying to use the preprocessor seam to mock out
+#              llifstream (and other) llcommon classes. I didn't work
+#              because of the windows declspec(dllimport)attribute.
+#set_source_files_properties(
 #    llupdaterservice.cpp
 #    PROPERTIES
-#      LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}"
+#      LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream"
 #    )
 
   LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}")
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index dc8ecc378a..fb628c99eb 100644
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -71,6 +71,11 @@ 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
+	// size - the size of the installer in bytes
 	virtual void downloadComplete(LLSD const & data) = 0;
 	
 	// The download failed.
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 4292da1528..4eb317e668 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -33,12 +33,26 @@
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/weak_ptr.hpp>
+#include "lldir.h"
+#include "llsdserialize.h"
+#include "llfile.h"
 
 #if LL_WINDOWS
 #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
 #endif
 
-boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
+
+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);
+	}
+}
 
 class LLUpdaterServiceImpl : 
 	public LLUpdateChecker::Client,
@@ -59,7 +73,7 @@ class LLUpdaterServiceImpl :
 	LLUpdateDownloader mUpdateDownloader;
 	LLTimer mTimer;
 
-	void retry(void);
+	LLUpdaterService::app_exit_callback_t mAppExitCallback;
 	
 	LOG_CLASS(LLUpdaterServiceImpl);
 	
@@ -67,7 +81,7 @@ public:
 	LLUpdaterServiceImpl();
 	virtual ~LLUpdaterServiceImpl();
 
-	void setParams(const std::string& protocol_version,
+	void initialize(const std::string& protocol_version,
 				   const std::string& url, 
 				   const std::string& path,
 				   const std::string& channel,
@@ -79,6 +93,11 @@ public:
 	void stopChecking();
 	bool isChecking();
 	
+	void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;}
+
+	bool checkForInstall(); // Test if a local install is ready.
+	bool checkForResume(); // Test for resumeable d/l.
+
 	// LLUpdateChecker::Client:
 	virtual void error(std::string const & message);
 	virtual void optionalUpdate(std::string const & newVersion,
@@ -90,10 +109,14 @@ public:
 	virtual void upToDate(void);
 	
 	// LLUpdateDownloader::Client
-	void downloadComplete(LLSD const & data) { retry(); }
-	void downloadError(std::string const & message) { retry(); }	
+	void downloadComplete(LLSD const & data);
+	void downloadError(std::string const & message);
 
 	bool onMainLoop(LLSD const & event);	
+
+private:
+	void retry(void);
+
 };
 
 const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
@@ -112,8 +135,8 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
 	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 }
 
-void LLUpdaterServiceImpl::setParams(const std::string& protocol_version,
-									 const std::string& url, 
+void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
+									  const std::string& url, 
 									 const std::string& path,
 									 const std::string& channel,
 									 const std::string& version)
@@ -129,6 +152,12 @@ void LLUpdaterServiceImpl::setParams(const std::string& protocol_version,
 	mPath = path;
 	mChannel = channel;
 	mVersion = version;
+
+	// Check to see if an install is ready.
+	if(!checkForInstall())
+	{
+		checkForResume();
+	}	
 }
 
 void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
@@ -146,7 +175,7 @@ void LLUpdaterServiceImpl::startChecking()
 				"LLUpdaterService::startCheck().");
 		}
 		mIsChecking = true;
-		
+	
 		mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
 	}
 }
@@ -164,6 +193,45 @@ bool LLUpdaterServiceImpl::isChecking()
 	return mIsChecking;
 }
 
+bool LLUpdaterServiceImpl::checkForInstall()
+{
+	bool result = false; // return true if install is found.
+
+	llifstream update_marker(update_marker_path(), 
+							 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);
+
+		// Get the path to the installer file.
+		LLSD path = update_info.get("path");
+		if(path.isDefined() && !path.asString().empty())
+		{
+			// install!
+		}
+
+		update_marker.close();
+		LLFile::remove(update_marker_path());
+		result = true;
+	}
+	return result;
+}
+
+bool LLUpdaterServiceImpl::checkForResume()
+{
+	bool result = false;
+	llstat stat_info;
+	if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info))
+	{
+		mUpdateDownloader.resume();
+		result = true;
+	}
+	return false;
+}
+
 void LLUpdaterServiceImpl::error(std::string const & message)
 {
 	retry();
@@ -188,6 +256,24 @@ void LLUpdaterServiceImpl::upToDate(void)
 	retry();
 }
 
+void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) 
+{ 
+	// Save out the download data to the SecondLifeUpdateReady
+	// marker file.
+	llofstream update_marker(update_marker_path());
+	LLSDSerialize::toPrettyXML(data, update_marker);
+
+	// Stop checking.
+	stopChecking();
+
+	// Wait for restart...?
+}
+
+void LLUpdaterServiceImpl::downloadError(std::string const & message) 
+{ 
+	retry(); 
+}
+
 void LLUpdaterServiceImpl::retry(void)
 {
 	LL_INFOS("UpdaterService") << "will check for update again in " << 
@@ -233,13 +319,13 @@ LLUpdaterService::~LLUpdaterService()
 {
 }
 
-void LLUpdaterService::setParams(const std::string& protocol_version,
+void LLUpdaterService::initialize(const std::string& protocol_version,
 								 const std::string& url, 
 								 const std::string& path,
 								 const std::string& channel,
 								 const std::string& version)
 {
-	mImpl->setParams(protocol_version, url, path, channel, version);
+	mImpl->initialize(protocol_version, url, path, channel, version);
 }
 
 void LLUpdaterService::setCheckPeriod(unsigned int seconds)
@@ -261,3 +347,8 @@ bool LLUpdaterService::isChecking()
 {
 	return mImpl->isChecking();
 }
+
+void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callback_t aecb)
+{
+	return mImpl->setAppExitCallback(aecb);
+}
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 04adf461b6..42ec3a2cab 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -27,6 +27,7 @@
 #define LL_UPDATERSERVICE_H
 
 #include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
 
 class LLUpdaterServiceImpl;
 
@@ -42,11 +43,11 @@ public:
 	LLUpdaterService();
 	~LLUpdaterService();
 
-	void setParams(const std::string& protocol_version,
-				   const std::string& url, 
-				   const std::string& path,
-				   const std::string& channel,
-				   const std::string& version);
+	void initialize(const std::string& protocol_version,
+				    const std::string& url, 
+				    const std::string& path,
+				    const std::string& channel,
+				    const std::string& version);
 
 	void setCheckPeriod(unsigned int seconds);
 	
@@ -54,8 +55,17 @@ public:
 	void stopChecking();
 	bool isChecking();
 
+	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);
+	}
+
 private:
 	boost::shared_ptr<LLUpdaterServiceImpl> mImpl;
+	void setImplAppExitCallback(app_exit_callback_t aecb);
 };
 
 #endif // LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 7f45ae51fb..57732ad0a5 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -36,6 +36,7 @@
 #include "../../../test/debug.h"
 
 #include "llevents.h"
+#include "lldir.h"
 
 /*****************************************************************************
 *   MOCK'd
@@ -48,6 +49,70 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con
 LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
 void LLUpdateDownloader::download(LLURI const & , std::string const &){}
 
+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;
+	}
+
+	BOOL getNextFileInDir(const std::string &dirname, 
+						  const std::string &mask, 
+						  std::string &fname, BOOL wrap) 
+	{
+		return false;
+	}
+	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){}
+bool LLDir::setCacheDir(const std::string &path){ return true; }
+void LLDir::dumpCurrentDirectories() {}
+
+std::string LLDir::getExpandedFilename(ELLPath location, 
+									   const std::string &filename) const 
+{
+	return "";
+}
+
+std::string LLUpdateDownloader::downloadMarkerPath(void)
+{
+	return "";
+}
+
+void LLUpdateDownloader::resume(void) {}
+
+/*
+#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
 *****************************************************************************/
@@ -96,9 +161,9 @@ namespace tut
 		bool got_usage_error = false;
 		try
 		{
-			updater.setParams("1.0",test_url, "update" ,test_channel, test_version);
+			updater.initialize("1.0",test_url, "update" ,test_channel, test_version);
 			updater.startChecking();
-			updater.setParams("1.0", "other_url", "update", test_channel, test_version);
+			updater.initialize("1.0", "other_url", "update", test_channel, test_version);
 		}
 		catch(LLUpdaterService::UsageError)
 		{
@@ -112,7 +177,7 @@ namespace tut
     {
         DEBUG;
 		LLUpdaterService updater;
-		updater.setParams("1.0", test_url, "update", test_channel, test_version);
+		updater.initialize("1.0", test_url, "update", test_channel, test_version);
 		updater.startChecking();
 		ensure(updater.isChecking());
 		updater.stopChecking();
-- 
cgit v1.2.3


From 41ec2e01ddf12c7d9fc57a115b1e6047560c7e5e Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Wed, 10 Nov 2010 14:30:11 -0800
Subject: copy script to temp if needed before installing.

---
 .../updater/llupdateinstaller.cpp                  | 44 ++++++++++++++++++++--
 .../viewer_components/updater/llupdateinstaller.h  | 10 ++++-
 2 files changed, 50 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index 1bb2101df1..52744b0479 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -24,15 +24,53 @@
  */
 
 #include "linden_common.h"
+#include <apr_file_io.h>
+#include "llapr.h"
 #include "llprocesslauncher.h"
 #include "llupdateinstaller.h"
+#include "lldir.h"
 
 
-void ll_install_update(std::string const & script, std::string const & updatePath)
+namespace {
+	class 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) throw RelocateError();
+		
+		return newPath;
+	}
+}
+
+
+int ll_install_update(std::string const & script, std::string const & updatePath, LLInstallScriptMode mode)
 {
+	std::string finalPath;
+	switch(mode) {
+		case LL_COPY_INSTALL_SCRIPT_TO_TEMP:
+			try {
+				finalPath = copy_to_temp(updatePath);
+			}
+			catch (RelocateError &) {
+				return -1;
+			}
+			break;
+		case LL_RUN_INSTALL_SCRIPT_IN_PLACE:
+			finalPath = updatePath;
+			break;
+		default:
+			llassert(!"unpossible copy mode");
+	}
+	
 	LLProcessLauncher launcher;
 	launcher.setExecutable(script);
-	launcher.addArgument(updatePath);
-	launcher.launch();
+	launcher.addArgument(finalPath);
+	int result = launcher.launch();
 	launcher.orphan();
+	
+	return result;
 }
diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h
index 991fe2afe1..310bfe4348 100644
--- a/indra/viewer_components/updater/llupdateinstaller.h
+++ b/indra/viewer_components/updater/llupdateinstaller.h
@@ -30,13 +30,21 @@
 #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.
 //
-void ll_install_update(std::string const & script, std::string const & updatePath);
+int ll_install_update(
+					   std::string const & script, // Script to execute.
+					   std::string const & updatePath, // Path to update file.
+					   LLInstallScriptMode mode=LL_COPY_INSTALL_SCRIPT_TO_TEMP); // Run in place or copy to temp?
 
 
 #endif
-- 
cgit v1.2.3


From dcf4ddacd81e3864525c44f145514911116daebd Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Wed, 10 Nov 2010 15:15:25 -0800
Subject: fix race between resume and download check.

---
 indra/viewer_components/updater/llupdaterservice.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 4eb317e668..28d9075efa 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -137,9 +137,9 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
 
 void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
 									  const std::string& url, 
-									 const std::string& path,
-									 const std::string& channel,
-									 const std::string& version)
+									  const std::string& path,
+									  const std::string& channel,
+									  const std::string& version)
 {
 	if(mIsChecking)
 	{
@@ -226,6 +226,7 @@ bool LLUpdaterServiceImpl::checkForResume()
 	llstat stat_info;
 	if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info))
 	{
+		mIsChecking = true;
 		mUpdateDownloader.resume();
 		result = true;
 	}
-- 
cgit v1.2.3


From 94942671fa81ad0da3682af31b715ca49f8e3bef Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Wed, 10 Nov 2010 15:23:26 -0800
Subject: fix resume crash.

---
 .../viewer_components/updater/llupdatedownloader.cpp | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 208cc48c12..21555dc3ff 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -57,6 +57,7 @@ private:
 	LLSD mDownloadData;
 	llofstream mDownloadStream;
 	std::string mDownloadRecordPath;
+	curl_slist * mHeaderList;
 	
 	void initializeCurlGet(std::string const & url, bool processHeader);
 	void resumeDownloading(size_t startByte);
@@ -154,7 +155,8 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
 	LLThread("LLUpdateDownloader"),
 	mCancelled(false),
 	mClient(client),
-	mCurl(0)
+	mCurl(0),
+	mHeaderList(0)
 {
 	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
 	llverify(code == CURLE_OK); // TODO: real error handling here. 
@@ -302,6 +304,11 @@ void LLUpdateDownloader::Implementation::run(void)
 		LLFile::remove(mDownloadRecordPath);
 		mClient.downloadError("curl error");
 	}
+	
+	if(mHeaderList) {
+		curl_slist_free_all(mHeaderList);
+		mHeaderList = 0;
+	}
 }
 
 
@@ -330,17 +337,18 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u
 
 void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)
 {
+	LL_INFOS("UpdateDownload") << "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;
-	curl_slist * headerList = 0;
-	headerList = curl_slist_append(headerList, rangeHeaderFormat.str().c_str());
-	if(headerList == 0) throw DownloadError("cannot add Range header");
-	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, headerList));
-	curl_slist_free_all(headerList);
+	mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str());
+	if(mHeaderList == 0) throw DownloadError("cannot add Range header");
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList));
 	
 	mDownloadStream.open(mDownloadData["path"].asString(),
 						 std::ios_base::out | std::ios_base::binary | std::ios_base::app);
-- 
cgit v1.2.3


From 41517715844c986aab169502c94f39a9f507eb55 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Wed, 10 Nov 2010 19:21:03 -0800
Subject: CHOP-151 Hooked up app exit callback, cleaned up early exit. Rev. by
 Brad

---
 indra/llui/llui.cpp                                |  5 +-
 indra/newview/llappviewer.cpp                      | 66 +++++++++++------
 .../viewer_components/updater/llupdaterservice.cpp | 86 ++++++++++++++--------
 .../updater/tests/llupdaterservice_test.cpp        | 12 +--
 4 files changed, 111 insertions(+), 58 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index ff9af21e54..19c42bf61a 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1620,7 +1620,10 @@ void LLUI::initClass(const settings_map_t& settings,
 
 void LLUI::cleanupClass()
 {
-	sImageProvider->cleanUp();
+	if(sImageProvider)
+	{
+		sImageProvider->cleanUp();
+	}
 }
 
 void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 10c03954bc..c06f0c18e8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -661,6 +661,14 @@ bool LLAppViewer::init()
     initThreads();
     writeSystemInfo();
 
+	// Initialize updater service (now that we have an io pump)
+	initUpdater();
+	if(isQuitting())
+	{
+		// Early out here because updater set the quitting flag.
+		return true;
+	}
+
 	//////////////////////////////////////////////////////////////////////////////
 	//////////////////////////////////////////////////////////////////////////////
 	//////////////////////////////////////////////////////////////////////////////
@@ -979,9 +987,6 @@ bool LLAppViewer::mainLoop()
 	LLHTTPClient::setPump(*gServicePump);
 	LLCurl::setCAFile(gDirUtilp->getCAFile());
 	
-	// Initialize updater service (now that we have an io pump)
-	initUpdater();
-	
 	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
 
 	LLVoiceChannel::initClass();
@@ -1364,11 +1369,14 @@ bool LLAppViewer::cleanup()
 	llinfos << "Cleaning Up" << llendflush;
 
 	// Must clean up texture references before viewer window is destroyed.
-	LLHUDManager::getInstance()->updateEffects();
-	LLHUDObject::updateAll();
-	LLHUDManager::getInstance()->cleanupEffects();
-	LLHUDObject::cleanupHUDObjects();
-	llinfos << "HUD Objects cleaned up" << llendflush;
+	if(LLHUDManager::instanceExists())
+	{
+		LLHUDManager::getInstance()->updateEffects();
+		LLHUDObject::updateAll();
+		LLHUDManager::getInstance()->cleanupEffects();
+		LLHUDObject::cleanupHUDObjects();
+		llinfos << "HUD Objects cleaned up" << llendflush;
+	}
 
 	LLKeyframeDataCache::clear();
 	
@@ -1380,8 +1388,10 @@ bool LLAppViewer::cleanup()
 	// Note: this is where gWorldMap used to be deleted.
 
 	// Note: this is where gHUDManager used to be deleted.
-	LLHUDManager::getInstance()->shutdownClass();
-	
+	if(LLHUDManager::instanceExists())
+	{
+		LLHUDManager::getInstance()->shutdownClass();
+	}
 
 	delete gAssetStorage;
 	gAssetStorage = NULL;
@@ -1683,7 +1693,10 @@ bool LLAppViewer::cleanup()
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
 	llinfos << "Auditing VFS" << llendl;
-	gVFS->audit();
+	if(gVFS)
+	{
+		gVFS->audit();
+	}
 #endif
 
 	llinfos << "Misc Cleanup" << llendflush;
@@ -2383,8 +2396,13 @@ void LLAppViewer::initUpdater()
 	std::string service_path = gSavedSettings.getString("UpdaterServicePath");
 	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
 
-	mUpdater->initialize(protocol_version, url, service_path, channel, version);
-	mUpdater->setCheckPeriod(check_period);
+	mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this));
+	mUpdater->initialize(protocol_version, 
+						 url, 
+						 service_path, 
+						 channel, 
+						 version);
+ 	mUpdater->setCheckPeriod(check_period);
 	if(gSavedSettings.getBOOL("UpdaterServiceActive"))
 	{
 		mUpdater->startChecking();
@@ -2550,15 +2568,18 @@ void LLAppViewer::cleanupSavedSettings()
 
 	// save window position if not maximized
 	// as we don't track it in callbacks
-	BOOL maximized = gViewerWindow->mWindow->getMaximized();
-	if (!maximized)
+	if(NULL != gViewerWindow)
 	{
-		LLCoordScreen window_pos;
-
-		if (gViewerWindow->mWindow->getPosition(&window_pos))
+		BOOL maximized = gViewerWindow->mWindow->getMaximized();
+		if (!maximized)
 		{
-			gSavedSettings.setS32("WindowX", window_pos.mX);
-			gSavedSettings.setS32("WindowY", window_pos.mY);
+			LLCoordScreen window_pos;
+
+			if (gViewerWindow->mWindow->getPosition(&window_pos))
+			{
+				gSavedSettings.setS32("WindowX", window_pos.mX);
+				gSavedSettings.setS32("WindowY", window_pos.mY);
+			}
 		}
 	}
 
@@ -4297,7 +4318,10 @@ void LLAppViewer::disconnectViewer()
 
 	// This is where we used to call gObjectList.destroy() and then delete gWorldp.
 	// Now we just ask the LLWorld singleton to cleanly shut down.
-	LLWorld::getInstance()->destroyClass();
+	if(LLWorld::instanceExists())
+	{
+		LLWorld::getInstance()->destroyClass();
+	}
 
 	// call all self-registered classes
 	LLDestroyClassList::instance().fireCallbacks();
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 28d9075efa..466b27f6fe 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -68,6 +68,7 @@ class LLUpdaterServiceImpl :
 	
 	unsigned int mCheckPeriod;
 	bool mIsChecking;
+	bool mIsDownloading;
 	
 	LLUpdateChecker mUpdateChecker;
 	LLUpdateDownloader mUpdateDownloader;
@@ -115,14 +116,14 @@ public:
 	bool onMainLoop(LLSD const & event);	
 
 private:
-	void retry(void);
-
+	void restartTimer(unsigned int seconds);
 };
 
 const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
 
 LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
+	mIsDownloading(false),
 	mCheckPeriod(0),
 	mUpdateChecker(*this),
 	mUpdateDownloader(*this)
@@ -141,10 +142,10 @@ void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
 									  const std::string& channel,
 									  const std::string& version)
 {
-	if(mIsChecking)
+	if(mIsChecking || mIsDownloading)
 	{
-		throw LLUpdaterService::UsageError("Call LLUpdaterService::stopCheck()"
-			" before setting params.");
+		throw LLUpdaterService::UsageError("LLUpdaterService::initialize call "
+										   "while updater is running.");
 	}
 		
 	mProtocolVersion = protocol_version;
@@ -167,16 +168,20 @@ void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
 
 void LLUpdaterServiceImpl::startChecking()
 {
-	if(!mIsChecking)
+	if(mUrl.empty() || mChannel.empty() || mVersion.empty())
 	{
-		if(mUrl.empty() || mChannel.empty() || mVersion.empty())
-		{
-			throw LLUpdaterService::UsageError("Set params before call to "
-				"LLUpdaterService::startCheck().");
-		}
-		mIsChecking = true;
-	
-		mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
+		throw LLUpdaterService::UsageError("Set params before call to "
+			"LLUpdaterService::startCheck().");
+	}
+
+	mIsChecking = true;
+
+	if(!mIsDownloading)
+	{
+		// Checking can only occur during the mainloop.
+		// reset the timer to 0 so that the next mainloop event 
+		// triggers a check;
+		restartTimer(0); 
 	}
 }
 
@@ -185,6 +190,7 @@ void LLUpdaterServiceImpl::stopChecking()
 	if(mIsChecking)
 	{
 		mIsChecking = false;
+		mTimer.stop();
 	}
 }
 
@@ -205,16 +211,21 @@ bool LLUpdaterServiceImpl::checkForInstall()
 		// Found an update info - now lets see if its valid.
 		LLSD update_info;
 		LLSDSerialize::fromXMLDocument(update_info, update_marker);
+		update_marker.close();
+		LLFile::remove(update_marker_path());
 
 		// Get the path to the installer file.
 		LLSD path = update_info.get("path");
 		if(path.isDefined() && !path.asString().empty())
 		{
 			// install!
+
+			if(mAppExitCallback)
+			{
+				mAppExitCallback();
+			}
 		}
 
-		update_marker.close();
-		LLFile::remove(update_marker_path());
 		result = true;
 	}
 	return result;
@@ -226,7 +237,7 @@ bool LLUpdaterServiceImpl::checkForResume()
 	llstat stat_info;
 	if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info))
 	{
-		mIsChecking = true;
+		mIsDownloading = true;
 		mUpdateDownloader.resume();
 		result = true;
 	}
@@ -235,13 +246,18 @@ bool LLUpdaterServiceImpl::checkForResume()
 
 void LLUpdaterServiceImpl::error(std::string const & message)
 {
-	retry();
+	if(mIsChecking)
+	{
+		restartTimer(mCheckPeriod);
+	}
 }
 
 void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion,
 										  LLURI const & uri,
 										  std::string const & hash)
 {
+	mTimer.stop();
+	mIsDownloading = true;
 	mUpdateDownloader.download(uri, hash);
 }
 
@@ -249,50 +265,60 @@ void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion,
 										  LLURI const & uri,
 										  std::string const & hash)
 {
+	mTimer.stop();
+	mIsDownloading = true;
 	mUpdateDownloader.download(uri, hash);
 }
 
 void LLUpdaterServiceImpl::upToDate(void)
 {
-	retry();
+	if(mIsChecking)
+	{
+		restartTimer(mCheckPeriod);
+	}
 }
 
 void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) 
 { 
+	mIsDownloading = false;
+
 	// Save out the download data to the SecondLifeUpdateReady
-	// marker file.
+	// marker file. 
 	llofstream update_marker(update_marker_path());
 	LLSDSerialize::toPrettyXML(data, update_marker);
-
-	// Stop checking.
-	stopChecking();
-
-	// Wait for restart...?
 }
 
 void LLUpdaterServiceImpl::downloadError(std::string const & message) 
 { 
-	retry(); 
+	mIsDownloading = false;
+
+	// Restart the 
+	if(mIsChecking)
+	{
+		restartTimer(mCheckPeriod); 
+	}
 }
 
-void LLUpdaterServiceImpl::retry(void)
+void LLUpdaterServiceImpl::restartTimer(unsigned int seconds)
 {
 	LL_INFOS("UpdaterService") << "will check for update again in " << 
 	mCheckPeriod << " seconds" << LL_ENDL; 
 	mTimer.start();
-	mTimer.setTimerExpirySec(mCheckPeriod);
+	mTimer.setTimerExpirySec(seconds);
 	LLEventPumps::instance().obtain("mainloop").listen(
 		sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
 }
 
 bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 {
-	if(mTimer.hasExpired())
+	if(mTimer.getStarted() && mTimer.hasExpired())
 	{
 		mTimer.stop();
 		LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 		mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
-	} else {
+	} 
+	else 
+	{
 		// Keep on waiting...
 	}
 	
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 57732ad0a5..aa30fa717d 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -102,12 +102,12 @@ void LLUpdateDownloader::resume(void) {}
 
 /*
 #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(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() {}
-- 
cgit v1.2.3


From 6e15957d909787ba612004903f04335a593b5348 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 11 Nov 2010 09:40:30 -0800
Subject: run install script on successful download

---
 indra/newview/viewer_manifest.py                   | 10 ++++---
 .../updater/llupdateinstaller.cpp                  | 13 +++++----
 .../viewer_components/updater/llupdaterservice.cpp | 33 ++++++++++++++++++++--
 .../updater/tests/llupdaterservice_test.cpp        |  6 ++++
 4 files changed, 50 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index f95697adb6..0073641ed4 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -571,14 +571,16 @@ class DarwinManifest(ViewerManifest):
 
             # copy additional libs in <bundle>/Contents/MacOS/
             self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib")
+			
+					
+            if self.prefix(src="../viewer_components/updater", dst="MacOS"):
+                self.path("update_install")
+                self.end_prefix()
+
 
             # most everything goes in the Resources directory
             if self.prefix(src="", dst="Resources"):
                 super(DarwinManifest, self).construct()
-		
-                if self.prefix(src="../viewer_components/updater", dst=""):
-                    self.path("update_install")
-                    self.end_prefix()
 
                 if self.prefix("cursors_mac"):
                     self.path("*.tif")
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index 52744b0479..10d5edc6a0 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -49,26 +49,29 @@ namespace {
 
 int ll_install_update(std::string const & script, std::string const & updatePath, LLInstallScriptMode mode)
 {
-	std::string finalPath;
+	std::string actualScriptPath;
 	switch(mode) {
 		case LL_COPY_INSTALL_SCRIPT_TO_TEMP:
 			try {
-				finalPath = copy_to_temp(updatePath);
+				actualScriptPath = copy_to_temp(script);
 			}
 			catch (RelocateError &) {
 				return -1;
 			}
 			break;
 		case LL_RUN_INSTALL_SCRIPT_IN_PLACE:
-			finalPath = updatePath;
+			actualScriptPath = script;
 			break;
 		default:
 			llassert(!"unpossible copy mode");
 	}
 	
+	llinfos << "UpdateInstaller: installing " << updatePath << " using " <<
+		actualScriptPath << LL_ENDL;
+	
 	LLProcessLauncher launcher;
-	launcher.setExecutable(script);
-	launcher.addArgument(finalPath);
+	launcher.setExecutable(actualScriptPath);
+	launcher.addArgument(updatePath);
 	int result = launcher.launch();
 	launcher.orphan();
 	
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 466b27f6fe..43551d6cea 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -30,6 +30,7 @@
 #include "lltimer.h"
 #include "llupdaterservice.h"
 #include "llupdatechecker.h"
+#include "llupdateinstaller.h"
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/weak_ptr.hpp>
@@ -52,6 +53,26 @@ namespace
 		return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, 
 											  UPDATE_MARKER_FILENAME);
 	}
+	
+	std::string install_script_path(void)
+	{
+#ifdef LL_WINDOWS
+		std::string scriptFile = "update_install.bat";
+#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
+		return LL_RUN_INSTALL_SCRIPT_IN_PLACE;
+#endif
+	};
+	
 }
 
 class LLUpdaterServiceImpl : 
@@ -218,11 +239,17 @@ bool LLUpdaterServiceImpl::checkForInstall()
 		LLSD path = update_info.get("path");
 		if(path.isDefined() && !path.asString().empty())
 		{
-			// install!
-
-			if(mAppExitCallback)
+			int result = ll_install_update(install_script_path(),
+										   update_info["path"].asString(),
+										   install_script_mode());	
+			
+			if((result == 0) && mAppExitCallback)
 			{
 				mAppExitCallback();
+			} else if(result != 0) {
+				llwarns << "failed to run update install script" << LL_ENDL;
+			} else {
+				; // No op.
 			}
 		}
 
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index aa30fa717d..9b56a04ff6 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -30,6 +30,7 @@
 #include "../llupdaterservice.h"
 #include "../llupdatechecker.h"
 #include "../llupdatedownloader.h"
+#include "../llupdateinstaller.h"
 
 #include "../../../test/lltut.h"
 //#define DEBUG_ON
@@ -100,6 +101,11 @@ std::string LLUpdateDownloader::downloadMarkerPath(void)
 
 void LLUpdateDownloader::resume(void) {}
 
+int ll_install_update(std::string const &, std::string const &, LLInstallScriptMode)
+{
+	return 0;
+}
+
 /*
 #pragma warning(disable: 4273)
 llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename,
-- 
cgit v1.2.3


From 4e22d63352dd65085cfbba9c22070271ecdd4bcf Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 11 Nov 2010 11:05:46 -0800
Subject: Add very basic windows install script.

---
 indra/newview/viewer_manifest.py                                   | 4 ++++
 indra/viewer_components/updater/CMakeLists.txt                     | 7 +++++++
 indra/viewer_components/updater/scripts/windows/update_install.bat | 1 +
 3 files changed, 12 insertions(+)
 create mode 100644 indra/viewer_components/updater/scripts/windows/update_install.bat

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 0073641ed4..55d64fd3a6 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -251,6 +251,10 @@ class WindowsManifest(ViewerManifest):
         if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
                        dst=""):
 
+            if self.prefix(src="../../viewer_components/updater", dst=""):
+                self.path("update_install.bat")
+                self.end_prefix()
+
             self.enable_crt_manifest_check()
 
             # Get kdu dll, continue if missing.
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index c5ccfbf66a..469c0cf05e 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -89,6 +89,13 @@ if(DARWIN)
 		update_installer_targets
 		"update_install"
 		)
+elseif(WINDOWS)
+	copy_if_different(
+		"${CMAKE_CURRENT_SOURCE_DIR}/scripts/windows"
+		"${CMAKE_CURRENT_BINARY_DIR}"
+		update_installer_targets
+		"update_install.bat"
+		)
 endif()
 add_custom_target(copy_update_install ALL DEPENDS ${update_installer_targets})
 add_dependencies(llupdaterservice copy_update_install)
diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat
new file mode 100644
index 0000000000..def33c1346
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/windows/update_install.bat
@@ -0,0 +1 @@
+start /WAIT %1
\ No newline at end of file
-- 
cgit v1.2.3


From 7a7f89db6d9c5e6b2c6c89ea39c0302907a0442b Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 11 Nov 2010 11:46:24 -0800
Subject: fix termination issues with thread safe queue in main loop repeater
 service.

---
 indra/llcommon/llthreadsafequeue.cpp |  6 +++---
 indra/newview/llappviewer.cpp        |  4 +++-
 indra/newview/llmainlooprepeater.cpp | 12 +++++++++---
 indra/newview/llmainlooprepeater.h   |  2 +-
 4 files changed, 16 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
index a7141605ef..8a73e632a9 100644
--- a/indra/llcommon/llthreadsafequeue.cpp
+++ b/indra/llcommon/llthreadsafequeue.cpp
@@ -53,13 +53,13 @@ LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * po
 
 LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
 {
-	if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
 	if(mQueue != 0) {
 		if(apr_queue_size(mQueue) != 0) llwarns << 
-			"terminating queue which still contains elements;" << 
-			"memory will be leaked" << LL_ENDL;
+			"terminating queue which still contains " << apr_queue_size(mQueue) <<
+			" elements;" << "memory will be leaked" << LL_ENDL;
 		apr_queue_term(mQueue);
 	}
+	if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
 }
 
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c06f0c18e8..76d518b610 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -812,7 +812,7 @@ bool LLAppViewer::init()
 	}
 	
 	// Initialize the repeater service.
-	LLMainLoopRepeater::getInstance()->start();
+	LLMainLoopRepeater::instance().start();
 	
 	//
 	// Initialize the window
@@ -1737,6 +1737,8 @@ bool LLAppViewer::cleanup()
 		llinfos << "File launched." << llendflush;
 	}
 
+	LLMainLoopRepeater::instance().stop();
+
 	ll_close_fail_log();
 
     llinfos << "Goodbye!" << llendflush;
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
index c2eba97641..ddc925a73b 100644
--- a/indra/newview/llmainlooprepeater.cpp
+++ b/indra/newview/llmainlooprepeater.cpp
@@ -36,7 +36,7 @@
 
 
 LLMainLoopRepeater::LLMainLoopRepeater(void):
-	mQueue(gAPRPoolp, 1024)
+	mQueue(0)
 {
 	; // No op.
 }
@@ -44,6 +44,9 @@ LLMainLoopRepeater::LLMainLoopRepeater(void):
 
 void LLMainLoopRepeater::start(void)
 {
+	if(mQueue != 0) return;
+
+	mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 1024);
 	mMainLoopConnection = LLEventPumps::instance().
 		obtain("mainloop").listen("stupid name here", boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
 	mRepeaterConnection = LLEventPumps::instance().
@@ -55,13 +58,16 @@ void LLMainLoopRepeater::stop(void)
 {
 	mMainLoopConnection.release();
 	mRepeaterConnection.release();
+
+	delete mQueue;
+	mQueue = 0;
 }
 
 
 bool LLMainLoopRepeater::onMainLoop(LLSD const &)
 {
 	LLSD message;
-	while(mQueue.tryPopBack(message)) {
+	while(mQueue->tryPopBack(message)) {
 		std::string pump = message["pump"].asString();
 		if(pump.length() == 0 ) continue; // No pump.
 		LLEventPumps::instance().obtain(pump).post(message["payload"]);
@@ -73,7 +79,7 @@ bool LLMainLoopRepeater::onMainLoop(LLSD const &)
 bool LLMainLoopRepeater::onMessage(LLSD const & event)
 {
 	try {
-		mQueue.pushFront(event);
+		mQueue->pushFront(event);
 	} catch(LLThreadSafeQueueError & e) {
 		llwarns << "could not repeat message (" << e.what() << ")" << 
 			event.asString() << LL_ENDL;
diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h
index 96b83b4916..f84c0ca94c 100644
--- a/indra/newview/llmainlooprepeater.h
+++ b/indra/newview/llmainlooprepeater.h
@@ -55,7 +55,7 @@ public:
 private:
 	LLTempBoundListener mMainLoopConnection;
 	LLTempBoundListener mRepeaterConnection;
-	LLThreadSafeQueue<LLSD> mQueue;
+	LLThreadSafeQueue<LLSD> * mQueue;
 	
 	bool onMainLoop(LLSD const &);
 	bool onMessage(LLSD const & event);
-- 
cgit v1.2.3


From 830afa5b27092668517b2f5670e892143de3cf66 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 11 Nov 2010 16:45:38 -0800
Subject: hacking mac updater to install from local dmg

---
 indra/llcommon/llthread.cpp                        |  2 +
 indra/mac_updater/mac_updater.cpp                  | 48 ++++++++++++++++++++--
 .../updater/scripts/darwin/update_install          |  5 +--
 3 files changed, 47 insertions(+), 8 deletions(-)
 mode change 100644 => 100755 indra/viewer_components/updater/scripts/darwin/update_install

(limited to 'indra')

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 2408be74b9..148aaf8aed 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -147,6 +147,8 @@ void LLThread::shutdown()
 		{
 			// This thread just wouldn't stop, even though we gave it time
 			llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
+			// Put a stake in its heart.
+			apr_thread_exit(mAPRThreadp, -1);
 			return;
 		}
 		mAPRThreadp = NULL;
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index 23980ffac2..5f6ea4d33b 100644
--- a/indra/mac_updater/mac_updater.cpp
+++ b/indra/mac_updater/mac_updater.cpp
@@ -26,6 +26,9 @@
 
 #include "linden_common.h"
 
+#include <boost/format.hpp>
+
+#include <libgen.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -62,6 +65,7 @@ Boolean gCancelled = false;
 const char *gUpdateURL;
 const char *gProductName;
 const char *gBundleID;
+const char *gDmgFile;
 
 void *updatethreadproc(void*);
 
@@ -334,6 +338,10 @@ int parse_args(int argc, char **argv)
 		{
 			gBundleID = argv[j];
 		}
+		else if ((!strcmp(argv[j], "-dmg")) && (++j < argc)) 
+		{
+			gDmgFile = argv[j];
+		}
 	}
 
 	return 0;
@@ -361,10 +369,11 @@ int main(int argc, char **argv)
 	gUpdateURL  = NULL;
 	gProductName = NULL;
 	gBundleID = NULL;
+	gDmgFile = NULL;
 	parse_args(argc, argv);
-	if (!gUpdateURL)
+	if ((gUpdateURL == NULL) && (gDmgFile == NULL))
 	{
-		llinfos << "Usage: mac_updater -url <url> [-name <product_name>] [-program <program_name>]" << llendl;
+		llinfos << "Usage: mac_updater -url <url> | -dmg <dmg file> [-name <product_name>] [-program <program_name>]" << llendl;
 		exit(1);
 	}
 	else
@@ -700,10 +709,14 @@ static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app)
 						// Looks promising.  Check to see if it has the right bundle identifier.
 						if(isFSRefViewerBundle(&ref))
 						{
+							llinfos << name << " is the one" << llendl;
 							// This is the one.  Return it.
 							*app = ref;
 							found = true;
+						} else {
+							llinfos << name << " is not the bundle we are looking for; move along" << llendl;
 						}
+
 					}
 				}
 			}
@@ -921,6 +934,22 @@ void *updatethreadproc(void*)
 
 #endif // 0 *HACK for DEV-11935
 		
+		// Skip downloading the file if the dmg was passed on the command line.
+		std::string dmgName;
+		if(gDmgFile != NULL) {
+			dmgName = basename((char *)gDmgFile);
+			char * dmgDir = dirname((char *)gDmgFile);
+			strncpy(tempDir, dmgDir, sizeof(tempDir));
+			err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL);
+			if(err != noErr) throw 0;
+			chdir(tempDir);
+			goto begin_install;
+		} else {
+			// Continue on to download file.
+			dmgName = "SecondLife.dmg";
+		}
+
+		
 		strncat(temp, "/SecondLifeUpdate_XXXXXX", (sizeof(temp) - strlen(temp)) - 1);
 		if(mkdtemp(temp) == NULL)
 		{
@@ -979,14 +1008,17 @@ void *updatethreadproc(void*)
 			fclose(downloadFile);
 			downloadFile = NULL;
 		}
-		
+
+	begin_install:
 		sendProgress(0, 0, CFSTR("Mounting image..."));
 		LLFile::mkdir("mnt", 0700);
 		
 		// NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder,
 		//		but if our cleanup fails, this makes it much harder for the user to unmount the image.
 		std::string mountOutput;
-		FILE* mounter = popen("hdiutil attach SecondLife.dmg -mountpoint mnt", "r");		/* Flawfinder: ignore */
+		boost::format cmdFormat("hdiutil attach %s -mountpoint mnt");
+		cmdFormat % dmgName;
+		FILE* mounter = popen(cmdFormat.str().c_str(), "r");		/* Flawfinder: ignore */
 		
 		if(mounter == NULL)
 		{
@@ -1077,7 +1109,11 @@ void *updatethreadproc(void*)
 			// Move aside old version (into work directory)
 			err = FSMoveObject(&targetRef, &tempDirRef, &asideRef);
 			if(err != noErr)
+			{
+				llwarns << "failed to move aside old version (error code " << 
+					err << ")" << llendl;
 				throw 0;
+			}
 
 			// Grab the path for later use.
 			err = FSRefMakePath(&asideRef, (UInt8*)aside, sizeof(aside));
@@ -1175,6 +1211,10 @@ void *updatethreadproc(void*)
 		llinfos << "Moving work directory to the trash." << llendl;
 
 		err = FSMoveObject(&tempDirRef, &trashFolderRef, NULL);
+		if(err != noErr) {
+			llwarns << "failed to move files to trash, (error code " <<
+				err << ")" << llendl;
+		}
 
 //		snprintf(temp, sizeof(temp), "rm -rf '%s'", tempDir);
 //		printf("%s\n", temp);
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install
old mode 100644
new mode 100755
index 24d344ca52..c061d2818f
--- a/indra/viewer_components/updater/scripts/darwin/update_install
+++ b/indra/viewer_components/updater/scripts/darwin/update_install
@@ -1,6 +1,3 @@
 #! /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
+open ../Resources/mac-updater.app --args -dmg "$1" -name "Second Life Viewer 2"
-- 
cgit v1.2.3


From bfa393f933ccf11105daf5258f373efc764b736f Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Thu, 11 Nov 2010 19:05:05 -0800
Subject: CHOP-178 Add a non-interactive moe to the windows installer. Rev by
 Brad

---
 .../installers/windows/installer_template.nsi      | 55 +++++++++++++++-------
 1 file changed, 39 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index d5712f80cf..4e8ed807ee 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -85,6 +85,8 @@ AutoCloseWindow true					; after all files install, close window
 InstallDir "$PROGRAMFILES\${INSTNAME}"
 InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" ""
 DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
+Page directory dirPre
+Page instfiles
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Variables
@@ -95,6 +97,8 @@ Var INSTFLAGS
 Var INSTSHORTCUT
 Var COMMANDLINE         ; command line passed to this installer, set in .onInit
 Var SHORTCUT_LANG_PARAM ; "--set InstallLanguage de", passes language to viewer
+Var SKIP_DIALOGS        ; set from command line in  .onInit. autoinstall 
+                        ; GUI and the defaults.
 
 ;;; Function definitions should go before file includes, because calls to
 ;;; DLLs like LangDLL trigger an implicit file include, so if that call is at
@@ -110,6 +114,9 @@ Var SHORTCUT_LANG_PARAM ; "--set InstallLanguage de", passes language to viewer
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function .onInstSuccess
     Push $R0	# Option value, unused
+
+    StrCmp $SKIP_DIALOGS "true" label_launch 
+
     ${GetOptions} $COMMANDLINE "/AUTOSTART" $R0
     # If parameter was there (no error) just launch
     # Otherwise ask
@@ -128,6 +135,13 @@ label_no_launch:
 	Pop $R0
 FunctionEnd
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Pre-directory page callback
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Function dirPre
+    StrCmp $SKIP_DIALOGS "true" 0 +2
+	Abort
+FunctionEnd    
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Make sure we're not on Windows 98 / ME
@@ -145,7 +159,8 @@ Function CheckWindowsVersion
 	StrCmp $R0 "NT" win_ver_bad
 	Return
 win_ver_bad:
-	MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort
+	StrCmp $SKIP_DIALOGS "true" +2 ; If skip_dialogs is set just install
+            MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort
 	Return
 win_ver_abort:
 	Quit
@@ -184,13 +199,13 @@ FunctionEnd
 ; If it has, allow user to bail out of install process.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function CheckIfAlreadyCurrent
-  Push $0
-	ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version"
-    StrCmp $0 ${VERSION_LONG} 0 DONE
-	MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK DONE
+    Push $0
+    ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version"
+    StrCmp $0 ${VERSION_LONG} 0 continue_install
+    StrCmp $SKIP_DIALOGS "true" continue_install
+    MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK continue_install
     Quit
-
-  DONE:
+continue_install:
     Pop $0
     Return
 FunctionEnd
@@ -203,7 +218,9 @@ Function CloseSecondLife
   Push $0
   FindWindow $0 "Second Life" ""
   IntCmp $0 0 DONE
-  MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL
+  
+  StrCmp $SKIP_DIALOGS "true" CLOSE
+    MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL
 
   CANCEL_INSTALL:
     Quit
@@ -659,23 +676,29 @@ FunctionEnd
 Function .onInit
     Push $0
     ${GetParameters} $COMMANDLINE              ; get our command line
+
+    ${GetOptions} $COMMANDLINE "/SKIP_DIALOGS" $0   
+    IfErrors +2 0 ; If error jump past setting SKIP_DIALOGS
+        StrCpy $SKIP_DIALOGS "true"
+
     ${GetOptions} $COMMANDLINE "/LANGID=" $0   ; /LANGID=1033 implies US English
     ; If no language (error), then proceed
-    IfErrors lbl_check_silent
+    IfErrors lbl_configure_default_lang
     ; No error means we got a language, so use it
     StrCpy $LANGUAGE $0
     Goto lbl_return
 
-lbl_check_silent:
-    ; For silent installs, no language prompt, use default
-    IfSilent lbl_return
-    
-	; If we currently have a version of SL installed, default to the language of that install
+lbl_configure_default_lang:
+    ; If we currently have a version of SL installed, default to the language of that install
     ; Otherwise don't change $LANGUAGE and it will default to the OS UI language.
-	ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage"
-    IfErrors lbl_build_menu
+    ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage"
+    IfErrors +2 0 ; If error skip the copy instruction 
 	StrCpy $LANGUAGE $0
 
+    ; For silent installs, no language prompt, use default
+    IfSilent lbl_return
+    StrCmp $SKIP_DIALOGS "true" lbl_return
+  
 lbl_build_menu:
 	Push ""
     # Use separate file so labels can be UTF-16 but we can still merge changes
-- 
cgit v1.2.3


From 1368a94f014884588b343802eef5fd2c7888390a Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 12 Nov 2010 12:23:30 -0800
Subject: do not resume or install if current viewer version doesn't match the
 recorded version which started the process.

---
 .../updater/llupdatedownloader.cpp                 |  2 +
 .../viewer_components/updater/llupdaterservice.cpp | 71 +++++++++++++++++++---
 indra/viewer_components/updater/llupdaterservice.h |  3 +
 3 files changed, 67 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 21555dc3ff..ab441aa747 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -35,6 +35,7 @@
 #include "llsdserialize.h"
 #include "llthread.h"
 #include "llupdatedownloader.h"
+#include "llupdaterservice.h"
 
 
 class LLUpdateDownloader::Implementation:
@@ -360,6 +361,7 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std
 {
 	mDownloadData["url"] = uri.asString();
 	mDownloadData["hash"] = hash;
+	mDownloadData["current_version"] = ll_get_version();
 	LLSD path = uri.pathArray();
 	if(path.size() == 0) throw DownloadError("no file path");
 	std::string fileName = path[path.size() - 1].asString();
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 43551d6cea..6cc872f2ca 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -31,6 +31,7 @@
 #include "llupdaterservice.h"
 #include "llupdatechecker.h"
 #include "llupdateinstaller.h"
+#include "llversionviewer.h"
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/weak_ptr.hpp>
@@ -237,7 +238,23 @@ bool LLUpdaterServiceImpl::checkForInstall()
 
 		// Get the path to the installer file.
 		LLSD path = update_info.get("path");
-		if(path.isDefined() && !path.asString().empty())
+		if(update_info["current_version"].asString() != ll_get_version())
+		{
+			// This viewer is not the same version as the one that downloaded
+			// the update.  Do not install this update.
+			if(!path.asString().empty())
+			{
+				llinfos << "ignoring update dowloaded by different client version" << llendl;
+				LLFile::remove(path.asString());
+			}
+			else
+			{
+				; // Nothing to clean up.
+			}
+			
+			result = false;
+		} 
+		else if(path.isDefined() && !path.asString().empty())
 		{
 			int result = ll_install_update(install_script_path(),
 										   update_info["path"].asString(),
@@ -251,9 +268,9 @@ bool LLUpdaterServiceImpl::checkForInstall()
 			} else {
 				; // No op.
 			}
+			
+			result = true;
 		}
-
-		result = true;
 	}
 	return result;
 }
@@ -261,14 +278,33 @@ bool LLUpdaterServiceImpl::checkForInstall()
 bool LLUpdaterServiceImpl::checkForResume()
 {
 	bool result = false;
-	llstat stat_info;
-	if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info))
+	std::string download_marker_path = mUpdateDownloader.downloadMarkerPath();
+	if(LLFile::isfile(download_marker_path))
 	{
-		mIsDownloading = true;
-		mUpdateDownloader.resume();
-		result = true;
+		llifstream download_marker_stream(download_marker_path, 
+								 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();
+			if(download_info["current_version"].asString() == ll_get_version())
+			{
+				mIsDownloading = true;
+				mUpdateDownloader.resume();
+				result = true;
+			}
+			else 
+			{
+				// The viewer that started this download is not the same as this viewer; ignore.
+				llinfos << "ignoring partial download from different viewer version" << llendl;
+				std::string path = download_info["path"].asString();
+				if(!path.empty()) LLFile::remove(path);
+				LLFile::remove(download_marker_path);
+			}
+		} 
 	}
-	return false;
+	return result;
 }
 
 void LLUpdaterServiceImpl::error(std::string const & message)
@@ -406,3 +442,20 @@ void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callbac
 {
 	return mImpl->setAppExitCallback(aecb);
 }
+
+
+std::string const & ll_get_version(void) {
+	static std::string version("");
+	
+	if (version.empty()) {
+		std::ostringstream stream;
+		stream << LL_VERSION_MAJOR << "."
+		<< LL_VERSION_MINOR << "."
+		<< LL_VERSION_PATCH << "."
+		<< LL_VERSION_BUILD;
+		version = stream.str();
+	}
+	
+	return version;
+}
+
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 42ec3a2cab..ec20dc6e05 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -68,4 +68,7 @@ private:
 	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
-- 
cgit v1.2.3


From ec7d36f6cfbed53a30d918415dfa3e429a645ce1 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 15 Nov 2010 09:38:20 -0800
Subject: added mechanism for install scripts to indicate a failed install and
 for update service to note the failure; modified mac installer to write
 marker on error.

---
 indra/mac_updater/mac_updater.cpp                  | 35 ++++++++++++++++++----
 .../updater/llupdateinstaller.cpp                  | 11 +++++++
 .../viewer_components/updater/llupdateinstaller.h  |  7 +++++
 .../viewer_components/updater/llupdaterservice.cpp | 14 ++++++++-
 .../updater/scripts/darwin/update_install          |  8 ++++-
 .../updater/tests/llupdaterservice_test.cpp        |  6 ++++
 6 files changed, 74 insertions(+), 7 deletions(-)
 mode change 100644 => 100755 indra/viewer_components/updater/scripts/darwin/update_install

(limited to 'indra')

diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index 5f6ea4d33b..5d19e8a889 100644
--- a/indra/mac_updater/mac_updater.cpp
+++ b/indra/mac_updater/mac_updater.cpp
@@ -66,6 +66,7 @@ const char *gUpdateURL;
 const char *gProductName;
 const char *gBundleID;
 const char *gDmgFile;
+const char *gMarkerPath;
 
 void *updatethreadproc(void*);
 
@@ -342,6 +343,10 @@ int parse_args(int argc, char **argv)
 		{
 			gDmgFile = argv[j];
 		}
+		else if ((!strcmp(argv[j], "-marker")) && (++j < argc)) 
+		{
+			gMarkerPath = argv[j];;
+		}
 	}
 
 	return 0;
@@ -370,6 +375,7 @@ int main(int argc, char **argv)
 	gProductName = NULL;
 	gBundleID = NULL;
 	gDmgFile = NULL;
+	gMarkerPath = NULL;
 	parse_args(argc, argv);
 	if ((gUpdateURL == NULL) && (gDmgFile == NULL))
 	{
@@ -497,11 +503,18 @@ int main(int argc, char **argv)
 					NULL,
 					&retval_mac);
 		}
-
+		
+		if(gMarkerPath != 0)
+		{
+			// Create a install fail marker that can be used by the viewer to
+			// detect install problems.
+			std::ofstream stream(gMarkerPath);
+			if(stream) stream << -1;
+		}
+		exit(-1);
+	} else {
+		exit(0);
 	}
-	
-	// Don't dispose of things, just exit.  This keeps the update thread from potentially getting hosed.
-	exit(0);
 
 	if(gWindow != NULL)
 	{
@@ -713,6 +726,7 @@ static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app)
 							// This is the one.  Return it.
 							*app = ref;
 							found = true;
+							break;
 						} else {
 							llinfos << name << " is not the bundle we are looking for; move along" << llendl;
 						}
@@ -721,9 +735,13 @@ static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app)
 				}
 			}
 		}
-		while(!err && !found);
+		while(!err);
+		
+		llinfos << "closing the iterator" << llendl;
 		
 		FSCloseIterator(iterator);
+		
+		llinfos << "closed" << llendl;
 	}
 	
 	if(!err && !found)
@@ -1084,12 +1102,19 @@ void *updatethreadproc(void*)
 			throw 0;
 		}
 
+		sendProgress(0, 0, CFSTR("Searching for the app bundle..."));
 		err = findAppBundleOnDiskImage(&mountRef, &sourceRef);
 		if(err != noErr)
 		{
 			llinfos << "Couldn't find application bundle on mounted disk image." << llendl;
 			throw 0;
 		}
+		else
+		{
+			llinfos << "found the bundle." << llendl;
+		}
+
+		sendProgress(0, 0, CFSTR("Preparing to copy files..."));
 		
 		FSRef asideRef;
 		char aside[MAX_PATH];		/* Flawfinder: ignore */
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index 10d5edc6a0..6e69bcf28b 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -72,8 +72,19 @@ int ll_install_update(std::string const & script, std::string const & updatePath
 	LLProcessLauncher launcher;
 	launcher.setExecutable(actualScriptPath);
 	launcher.addArgument(updatePath);
+	launcher.addArgument(ll_install_failed_marker_path().c_str());
 	int result = launcher.launch();
 	launcher.orphan();
 	
 	return result;
 }
+
+
+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
index 310bfe4348..6ce08ce6fa 100644
--- a/indra/viewer_components/updater/llupdateinstaller.h
+++ b/indra/viewer_components/updater/llupdateinstaller.h
@@ -47,4 +47,11 @@ int ll_install_update(
 					   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
index 6cc872f2ca..a1ad3e3381 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -378,7 +378,19 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 	{
 		mTimer.stop();
 		LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
-		mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
+
+		// Check for failed install.
+		if(LLFile::isfile(ll_install_failed_marker_path()))
+		{
+			// TODO: notify the user.
+			llinfos << "found marker " << ll_install_failed_marker_path() << llendl;
+			llinfos << "last install attempt failed" << llendl;
+			LLFile::remove(ll_install_failed_marker_path());
+		}
+		else
+		{
+			mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
+		}
 	} 
 	else 
 	{
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install
old mode 100644
new mode 100755
index c061d2818f..b174b3570a
--- a/indra/viewer_components/updater/scripts/darwin/update_install
+++ b/indra/viewer_components/updater/scripts/darwin/update_install
@@ -1,3 +1,9 @@
 #! /bin/bash
 
-open ../Resources/mac-updater.app --args -dmg "$1" -name "Second Life Viewer 2"
+#
+# The first argument contains the path to the installer app.  The second a path
+# to a marker file which should be created if the installer fails.q
+#
+
+open ../Resources/mac-updater.app --args -dmg "$1" -name "Second Life Viewer 2" -marker "$2"
+exit 0
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 9b56a04ff6..25fd1b034d 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -106,6 +106,12 @@ int ll_install_update(std::string const &, std::string const &, LLInstallScriptM
 	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,
-- 
cgit v1.2.3


From a89024fb372bb293d24d860fb70156b5cf48d6f3 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 15 Nov 2010 09:57:00 -0800
Subject: write marker on windows installer fail.

---
 indra/viewer_components/updater/scripts/windows/update_install.bat | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat
index def33c1346..9cdc51847a 100644
--- a/indra/viewer_components/updater/scripts/windows/update_install.bat
+++ b/indra/viewer_components/updater/scripts/windows/update_install.bat
@@ -1 +1,2 @@
-start /WAIT %1
\ No newline at end of file
+start /WAIT %1
+IF ERRORLEVEL 1 ECHO ERRORLEVEL > %2
-- 
cgit v1.2.3


From f47c42bb10cd3291ce966be7b209b422646dff19 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 15 Nov 2010 14:26:45 -0800
Subject: create marker on error; use /SKIP_DIALOGS option in installer to run
 without user input.

---
 indra/viewer_components/updater/scripts/windows/update_install.bat | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat
index 9cdc51847a..44ccef010b 100644
--- a/indra/viewer_components/updater/scripts/windows/update_install.bat
+++ b/indra/viewer_components/updater/scripts/windows/update_install.bat
@@ -1,2 +1,2 @@
-start /WAIT %1
+start /WAIT %1 /SKIP_DIALOGS
 IF ERRORLEVEL 1 ECHO ERRORLEVEL > %2
-- 
cgit v1.2.3


From 35fc90e8aaebc10a5a01c58247c29c8103220578 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Mon, 15 Nov 2010 14:37:32 -0800
Subject: CHOP-179 Added --file option to linux-updater for local install

---
 indra/linux_updater/linux_updater.cpp | 149 +++++++++++++++++++---------------
 1 file changed, 82 insertions(+), 67 deletions(-)

(limited to 'indra')

diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index be4d810860..16660de6bb 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -49,6 +49,7 @@ const guint ROTATE_IMAGE_TIMEOUT = 8000;
 typedef struct _updater_app_state {
 	std::string app_name;
 	std::string url;
+	std::string file;
 	std::string image_dir;
 	std::string dest_dir;
 	std::string strings_dirs;
@@ -266,85 +267,95 @@ gpointer worker_thread_cb(gpointer data)
 	CURLcode result;
 	FILE *package_file;
 	GError *error = NULL;
-	char *tmp_filename = NULL;
 	int fd;
 
 	//g_return_val_if_fail (data != NULL, NULL);
 	app_state = (UpdaterAppState *) data;
 
 	try {
-		// create temporary file to store the package.
-		fd = g_file_open_tmp
-			("secondlife-update-XXXXXX", &tmp_filename, &error);
-		if (error != NULL)
-		{
-			llerrs << "Unable to create temporary file: "
-			       << error->message
-			       << llendl;
 
-			g_error_free(error);
-			throw 0;
-		}
-
-		package_file = fdopen(fd, "wb");
-		if (package_file == NULL)
+		if(!app_state->url.empty())
 		{
-			llerrs << "Failed to create temporary file: "
-			       << tmp_filename
-			       << llendl;
+			char* tmp_local_filename = NULL;
+			// create temporary file to store the package.
+			fd = g_file_open_tmp
+				("secondlife-update-XXXXXX", &tmp_local_filename, &error);
+			if (error != NULL)
+			{
+				llerrs << "Unable to create temporary file: "
+					   << error->message
+					   << llendl;
 
-			gdk_threads_enter();
-			display_error(app_state->window,
-				      LLTrans::getString("UpdaterFailDownloadTitle"),
-				      LLTrans::getString("UpdaterFailUpdateDescriptive"));
-			gdk_threads_leave();
-			throw 0;
-		}
+				g_error_free(error);
+				throw 0;
+			}
+			
+			if(tmp_local_filename != NULL)
+			{
+				app_state->file = tmp_local_filename;
+				g_free(tmp_local_filename);
+			}
 
-		// initialize curl and start downloading the package
-		llinfos << "Downloading package: " << app_state->url << llendl;
+			package_file = fdopen(fd, "wb");
+			if (package_file == NULL)
+			{
+				llerrs << "Failed to create temporary file: "
+					   << app_state->file.c_str()
+					   << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
 
-		curl = curl_easy_init();
-		if (curl == NULL)
-		{
-			llerrs << "Failed to initialize libcurl" << llendl;
+			// initialize curl and start downloading the package
+			llinfos << "Downloading package: " << app_state->url << llendl;
 
-			gdk_threads_enter();
-			display_error(app_state->window,
-				      LLTrans::getString("UpdaterFailDownloadTitle"),
-				      LLTrans::getString("UpdaterFailUpdateDescriptive"));
-			gdk_threads_leave();
-			throw 0;
-		}
+			curl = curl_easy_init();
+			if (curl == NULL)
+			{
+				llerrs << "Failed to initialize libcurl" << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
 
-		curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
-		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
-		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
-		curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
-		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
-		curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, 
-				 &download_progress_cb);
-		curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
+			curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
+			curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
+			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
+			curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
+			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, 
+							 &download_progress_cb);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
 
-		result = curl_easy_perform(curl);
-		fclose(package_file);
-		curl_easy_cleanup(curl);
+			result = curl_easy_perform(curl);
+			fclose(package_file);
+			curl_easy_cleanup(curl);
 
-		if (result)
-		{
-			llerrs << "Failed to download update: " 
-			       << app_state->url 
-			       << llendl;
+			if (result)
+			{
+				llerrs << "Failed to download update: " 
+					   << app_state->url 
+					   << llendl;
 
-			gdk_threads_enter();
-			display_error(app_state->window,
-				      LLTrans::getString("UpdaterFailDownloadTitle"),
-				      LLTrans::getString("UpdaterFailUpdateDescriptive"));
-			gdk_threads_leave();
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
 
-			throw 0;
+				throw 0;
+			}
 		}
-
+		
 		// now pulse the progres bar back and forth while the package is
 		// being unpacked
 		gdk_threads_enter();
@@ -357,7 +368,7 @@ gpointer worker_thread_cb(gpointer data)
 
 		// *TODO: if the destination is not writable, terminate this
 		// thread and show file chooser?
-		if (!install_package(tmp_filename, app_state->dest_dir))
+		if (!install_package(app_state->file.c_str(), app_state->dest_dir))
 		{
 			llwarns << "Failed to install package to destination: "
 				<< app_state->dest_dir
@@ -393,11 +404,11 @@ gpointer worker_thread_cb(gpointer data)
 	}
 
 	// FIXME: delete package file also if delete-event is raised on window
-	if (tmp_filename != NULL)
+	if(!app_state->url.empty() && !app_state->file.empty())
 	{
-		if (gDirUtilp->fileExists(tmp_filename))
+		if (gDirUtilp->fileExists(app_state->file))
 		{
-			LLFile::remove(tmp_filename);
+			LLFile::remove(app_state->file);
 		}
 	}
 
@@ -712,7 +723,7 @@ BOOL spawn_viewer(UpdaterAppState *app_state)
 
 void show_usage_and_exit()
 {
-	std::cout << "Usage: linux-updater --url URL --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
+	std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
 		  << "[--image-dir PATH]"
 		  << std::endl;
 	exit(1);
@@ -728,6 +739,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 		{
 			app_state->url = argv[i];
 		}
+		else if ((!strcmp(argv[i], "--file")) && (++i < argc))
+		{
+			app_state->file = argv[i];
+		}
 		else if ((!strcmp(argv[i], "--name")) && (++i < argc))
 		{
 			app_state->app_name = argv[i];
@@ -756,7 +771,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 	}
 
 	if (app_state->app_name.empty() 
-	    || app_state->url.empty() 
+	    || (app_state->url.empty() && app_state->file.empty())  
 	    || app_state->dest_dir.empty())
 	{
 		show_usage_and_exit();
-- 
cgit v1.2.3


From 64876ea9459ed0e0f1673c5ec9ae67abea2280e2 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 16 Nov 2010 09:43:23 -0800
Subject: better error checking when writing downloaded file.

---
 indra/viewer_components/updater/llupdatedownloader.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index ab441aa747..eccc25aeee 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -275,9 +275,14 @@ size_t LLUpdateDownloader::Implementation::onHeader(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.
+	if((size == 0) || (buffer == 0)) return 0; 
 	
 	mDownloadStream.write(reinterpret_cast<const char *>(buffer), size);
-	return size;
+	if(mDownloadStream.bad()) {
+		return 0;
+	} else {
+		return size;
+	}
 }
 
 
-- 
cgit v1.2.3


From ad354324ca444d1fc71653e2ade799053a8d6f01 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 16 Nov 2010 15:21:35 -0800
Subject: clean up installer file after install.

---
 indra/viewer_components/updater/scripts/windows/update_install.bat | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat
index 44ccef010b..42e148a707 100644
--- a/indra/viewer_components/updater/scripts/windows/update_install.bat
+++ b/indra/viewer_components/updater/scripts/windows/update_install.bat
@@ -1,2 +1,3 @@
 start /WAIT %1 /SKIP_DIALOGS
-IF ERRORLEVEL 1 ECHO ERRORLEVEL > %2
+IF ERRORLEVEL 1 ECHO %ERRORLEVEL% > %2
+DEL %1
-- 
cgit v1.2.3


From 13b77e3622de18ac8d06fdfffceb08990eb908f9 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Tue, 16 Nov 2010 16:21:17 -0800
Subject: CHOP-179 Linux install uses linux-updater. Rev. by Alain

---
 indra/newview/viewer_manifest.py                   | 13 +++++--------
 indra/viewer_components/updater/CMakeLists.txt     | 22 ----------------------
 .../viewer_components/updater/llupdaterservice.cpp |  6 ++++--
 .../updater/scripts/linux/update_install           |  5 +++++
 4 files changed, 14 insertions(+), 32 deletions(-)
 create mode 100755 indra/viewer_components/updater/scripts/linux/update_install

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 55d64fd3a6..5d35778e3e 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -247,13 +247,12 @@ class WindowsManifest(ViewerManifest):
         
         self.disable_manifest_check()
 
+        self.path("../viewer_components/updater/scripts/windows/update_install.bat")
+
         # Get shared libs from the shared libs staging directory
         if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
                        dst=""):
 
-            if self.prefix(src="../../viewer_components/updater", dst=""):
-                self.path("update_install.bat")
-                self.end_prefix()
 
             self.enable_crt_manifest_check()
 
@@ -575,12 +574,8 @@ class DarwinManifest(ViewerManifest):
 
             # copy additional libs in <bundle>/Contents/MacOS/
             self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib")
-			
-					
-            if self.prefix(src="../viewer_components/updater", dst="MacOS"):
-                self.path("update_install")
-                self.end_prefix()
 
+            self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install")
 
             # most everything goes in the Resources directory
             if self.prefix(src="", dst="Resources"):
@@ -857,6 +852,8 @@ class LinuxManifest(ViewerManifest):
             # recurse
             self.end_prefix("res-sdl")
 
+        self.path("../viewer_components/updater/scripts/linux/update_install", "bin/update_install")
+
         # plugins
         if self.prefix(src="", dst="bin/llplugin"):
             self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 469c0cf05e..0e288bb496 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -80,25 +80,3 @@ 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"
-		)
-elseif(WINDOWS)
-	copy_if_different(
-		"${CMAKE_CURRENT_SOURCE_DIR}/scripts/windows"
-		"${CMAKE_CURRENT_BINARY_DIR}"
-		update_installer_targets
-		"update_install.bat"
-		)
-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/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index a1ad3e3381..976e639098 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -353,9 +353,11 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)
 
 void LLUpdaterServiceImpl::downloadError(std::string const & message) 
 { 
+	LL_INFOS("UpdaterService") << "Error downloading: " << message << LL_ENDL;
+
 	mIsDownloading = false;
 
-	// Restart the 
+	// Restart the timer on error
 	if(mIsChecking)
 	{
 		restartTimer(mCheckPeriod); 
@@ -365,7 +367,7 @@ void LLUpdaterServiceImpl::downloadError(std::string const & message)
 void LLUpdaterServiceImpl::restartTimer(unsigned int seconds)
 {
 	LL_INFOS("UpdaterService") << "will check for update again in " << 
-	mCheckPeriod << " seconds" << LL_ENDL; 
+	seconds << " seconds" << LL_ENDL; 
 	mTimer.start();
 	mTimer.setTimerExpirySec(seconds);
 	LLEventPumps::instance().obtain("mainloop").listen(
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
new file mode 100755
index 0000000000..acedaad25c
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/linux/update_install
@@ -0,0 +1,5 @@
+#! /bin/bash
+INSTALL_DIR=$(cd "$(dirname $0)/.." ; pwd)
+export LD_LIBRARY_PATH=$INSTALL_DIR/lib
+bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer 2" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml"
+
-- 
cgit v1.2.3


From 74a60346b2f04157862786d31d7181885092b766 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 16 Nov 2010 16:22:37 -0800
Subject: remove downloaded file on error.

---
 indra/viewer_components/updater/llupdatedownloader.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index eccc25aeee..4820f1f452 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -308,6 +308,7 @@ void LLUpdateDownloader::Implementation::run(void)
 		LL_WARNS("UpdateDownload") << "download failed with error '" << 
 			curl_easy_strerror(code) << "'" << LL_ENDL;
 		LLFile::remove(mDownloadRecordPath);
+		if(mDownloadData.has("path")) LLFile::remove(mDownloadData["path"].asString());
 		mClient.downloadError("curl error");
 	}
 	
-- 
cgit v1.2.3


From dd6213abf4f70cfb9d221572f9dc4d597d8fa0dc Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Tue, 16 Nov 2010 18:34:58 -0800
Subject: CHOP-209 Added marker creation, fixed updater crash bug

---
 indra/linux_updater/linux_updater.cpp                   | 17 ++++++++++-------
 .../updater/scripts/linux/update_install                |  3 +++
 2 files changed, 13 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index 16660de6bb..a7f886b389 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -114,7 +114,7 @@ BOOL install_package(std::string package_file, std::string destination);
 BOOL spawn_viewer(UpdaterAppState *app_state);
 
 extern "C" {
-	void on_window_closed(GtkWidget *sender, gpointer state);
+	void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state);
 	gpointer worker_thread_cb(gpointer *data);
 	int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow);
 	gboolean rotate_image_cb(gpointer data);
@@ -221,7 +221,7 @@ std::string next_image_filename(std::string& image_path)
 	return image_path + "/" + image_filename;
 }
 
-void on_window_closed(GtkWidget *sender, gpointer data)
+void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data)
 {
 	UpdaterAppState *app_state;
 
@@ -786,10 +786,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 
 int main(int argc, char **argv)
 {
-	UpdaterAppState app_state;
+	UpdaterAppState* app_state = new UpdaterAppState;
 	GThread *worker_thread;
 
-	parse_args_and_init(argc, argv, &app_state);
+	parse_args_and_init(argc, argv, app_state);
 
 	// Initialize logger, and rename old log file
 	gDirUtilp->initAppDirs("SecondLife");
@@ -812,17 +812,20 @@ int main(int argc, char **argv)
 	gtk_init(&argc, &argv);
 
 	// create UI
-	updater_app_ui_init(&app_state);
+	updater_app_ui_init(app_state);
 
 	//llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl;
 
 	// create download thread
 	worker_thread = g_thread_create
-		(GThreadFunc(worker_thread_cb), &app_state, FALSE, NULL);
+		(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL);
 
 	gdk_threads_enter();
 	gtk_main();
 	gdk_threads_leave();
 
-	return (app_state.failure == FALSE) ? 0 : 1;
+	bool success = app_state->failure != FALSE;
+	delete app_state;
+	return success ? 0 : 1;
 }
+
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
index acedaad25c..7d8a27607c 100755
--- a/indra/viewer_components/updater/scripts/linux/update_install
+++ b/indra/viewer_components/updater/scripts/linux/update_install
@@ -3,3 +3,6 @@ INSTALL_DIR=$(cd "$(dirname $0)/.." ; pwd)
 export LD_LIBRARY_PATH=$INSTALL_DIR/lib
 bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer 2" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml"
 
+if [ $? -ne 0 ]
+   then touch $2
+fi
\ No newline at end of file
-- 
cgit v1.2.3


From c61d89f61d0b696e6e73105ed7be7580bf1b3437 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Wed, 17 Nov 2010 12:24:37 -0800
Subject: CHOP-203 Fixed linux release bug - exclude update_install from symbol
 strippage

---
 indra/newview/viewer_manifest.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 5d35778e3e..4e5d6271df 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -882,7 +882,7 @@ class LinuxManifest(ViewerManifest):
 
         if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
             print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"
-            self.run_command("find %(d)r/bin %(d)r/lib -type f | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
+            self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
 
         # Fix access permissions
         self.run_command("""
-- 
cgit v1.2.3


From 8e0e5e0bd9fd3e699a36b6babfacab3c0f61935b Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Wed, 17 Nov 2010 15:20:53 -0800
Subject: CHOP-203 Deleting the update file after installer run.

---
 indra/linux_updater/linux_updater.cpp                  | 18 +++++++++---------
 .../updater/scripts/linux/update_install               |  4 +++-
 2 files changed, 12 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index a7f886b389..cbdb3ddfe0 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -403,15 +403,6 @@ gpointer worker_thread_cb(gpointer data)
 		app_state->failure = TRUE;
 	}
 
-	// FIXME: delete package file also if delete-event is raised on window
-	if(!app_state->url.empty() && !app_state->file.empty())
-	{
-		if (gDirUtilp->fileExists(app_state->file))
-		{
-			LLFile::remove(app_state->file);
-		}
-	}
-
 	gdk_threads_enter();
 	updater_app_quit(app_state);
 	gdk_threads_leave();
@@ -824,6 +815,15 @@ int main(int argc, char **argv)
 	gtk_main();
 	gdk_threads_leave();
 
+	// Delete the file only if created from url download.
+	if(!app_state->url.empty() && !app_state->file.empty())
+	{
+		if (gDirUtilp->fileExists(app_state->file))
+		{
+			LLFile::remove(app_state->file);
+		}
+	}
+
 	bool success = app_state->failure != FALSE;
 	delete app_state;
 	return success ? 0 : 1;
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
index 7d8a27607c..fef5ef7d09 100755
--- a/indra/viewer_components/updater/scripts/linux/update_install
+++ b/indra/viewer_components/updater/scripts/linux/update_install
@@ -5,4 +5,6 @@ bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life View
 
 if [ $? -ne 0 ]
    then touch $2
-fi
\ No newline at end of file
+fi
+
+rm -f $1
-- 
cgit v1.2.3


From c212695cd96f94248b0da2085aeb23c54a5ca76b Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Wed, 17 Nov 2010 16:27:50 -0800
Subject: post events for dowload success and error.

---
 .../viewer_components/updater/llupdaterservice.cpp | 24 +++++++++++++++++++++-
 indra/viewer_components/updater/llupdaterservice.h | 10 +++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 976e639098..6a40246497 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -135,7 +135,7 @@ public:
 	void downloadComplete(LLSD const & data);
 	void downloadError(std::string const & message);
 
-	bool onMainLoop(LLSD const & event);	
+	bool onMainLoop(LLSD const & event);
 
 private:
 	void restartTimer(unsigned int seconds);
@@ -349,6 +349,13 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)
 	// marker file. 
 	llofstream update_marker(update_marker_path());
 	LLSDSerialize::toPrettyXML(data, update_marker);
+	
+	LLSD event;
+	event["pump"] = LLUpdaterService::pumpName();
+	LLSD payload;
+	payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE);
+	event["payload"] = payload;
+	LLEventPumps::instance().obtain("mainlooprepeater").post(event);
 }
 
 void LLUpdaterServiceImpl::downloadError(std::string const & message) 
@@ -362,6 +369,14 @@ void LLUpdaterServiceImpl::downloadError(std::string const & message)
 	{
 		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);
 }
 
 void LLUpdaterServiceImpl::restartTimer(unsigned int seconds)
@@ -405,6 +420,13 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 
 //-----------------------------------------------------------------------
 // Facade interface
+
+std::string const & LLUpdaterService::pumpName(void)
+{
+	static std::string name("updater_service");
+	return name;
+}
+
 LLUpdaterService::LLUpdaterService()
 {
 	if(gUpdater.expired())
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index ec20dc6e05..8d0b95be86 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -39,6 +39,16 @@ public:
 	public:
 		UsageError(const std::string& msg) : std::runtime_error(msg) {}
 	};
+	
+	// Name of the event pump through which update events will be delivered.
+	static std::string const & pumpName(void);
+	
+	// Type codes for events posted by this service.  Stored the event's 'type' element.
+	enum UpdateEvent {
+		INVALID,
+		DOWNLOAD_COMPLETE,
+		DOWNLOAD_ERROR
+	};
 
 	LLUpdaterService();
 	~LLUpdaterService();
-- 
cgit v1.2.3


From 5c35547ade48123cb571714de42ffe42b232480d Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Wed, 17 Nov 2010 16:50:38 -0800
Subject: CHOP-135 Added Pref UI to Setup panel. Rev. by Brad

---
 .../default/xui/en/panel_preferences_setup.xml     | 26 +++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 140d16e37f..79013e7e27 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -29,7 +29,7 @@
    layout="topleft"
    left_delta="50"
    name=" Mouse Sensitivity"
-   top_pad="10"
+   top_pad="5"
    width="150">
     Mouse sensitivity
   </text>
@@ -76,7 +76,7 @@
    left_delta="50"
    name="Maximum bandwidth"
    mouse_opaque="false"
-   top_pad="10"
+   top_pad="5"
    width="200">
     Maximum bandwidth
   </text>
@@ -115,7 +115,7 @@
    layout="topleft"
    left="77"
    name="connection_port_enabled"
-   top_pad="20"
+   top_pad="10"
    width="256">
     <check_box.commit_callback
      function="Notification.Show"
@@ -147,7 +147,7 @@
    left="80"
    mouse_opaque="false"
    name="cache_size_label_l"
-   top_pad="20"
+   top_pad="10"
    width="200">
     Cache size
   </text>
@@ -239,7 +239,7 @@
          layout="topleft"
          left="30"
          name="Web:"
-         top_pad="5"
+         top_pad="10"
          width="300">
     Web:
   </text>
@@ -386,4 +386,20 @@
    name="web_proxy_port"
    top_delta="0"
    width="145" />
+
+  <check_box
+    top_delta="2"
+    enabled="true"
+    follows="left|top"
+    height="18"
+    initial_value="true"
+    control_name="UpdaterServiceActive"
+    label="Automatically download and install [APP_NAME] updates"
+    left="30"
+    mouse_opaque="true"
+    name="updater_service_active"
+    radio_style="false"
+    width="400"
+    top_pad="10"/>
+
 </panel>
-- 
cgit v1.2.3


From 098fa21c4f812b94348c0631c29babff68968d3d Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Wed, 17 Nov 2010 17:06:21 -0800
Subject: Work on CHOP-135: Hooking up setting UpdaterServiceActive to
 functionality. Paired with Mani. Toggling the setting now calls
 LLUpdaterService::startChecking() and LLUpdaterService::stopChecking(), which
 enable and disable the service.

---
 indra/newview/llviewercontrol.cpp                    | 14 ++++++++++++++
 indra/viewer_components/updater/llupdaterservice.cpp | 17 +++++++++++------
 2 files changed, 25 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index f579c433e1..f65811598f 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -70,6 +70,7 @@
 #include "llpaneloutfitsinventory.h"
 #include "llpanellogin.h"
 #include "llpaneltopinfobar.h"
+#include "llupdaterservice.h"
 
 #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
 BOOL 				gHackGodmode = FALSE;
@@ -488,6 +489,18 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
 	return true;
 }
 
+void toggle_updater_service_active(LLControlVariable* control, const LLSD& new_value)
+{
+    if(new_value.asBoolean())
+    {
+        LLUpdaterService().startChecking();
+    }
+    else
+    {
+        LLUpdaterService().stopChecking();
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////
 
 void settings_setup_listeners()
@@ -635,6 +648,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2));
 	gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
 	gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
+	gSavedSettings.getControl("UpdaterServiceActive")->getSignal()->connect(&toggle_updater_service_active);
 	gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
 }
 
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 6a40246497..58f2c7da76 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -175,12 +175,6 @@ void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
 	mPath = path;
 	mChannel = channel;
 	mVersion = version;
-
-	// Check to see if an install is ready.
-	if(!checkForInstall())
-	{
-		checkForResume();
-	}	
 }
 
 void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
@@ -198,6 +192,12 @@ void LLUpdaterServiceImpl::startChecking()
 
 	mIsChecking = true;
 
+    // Check to see if an install is ready.
+	if(!checkForInstall())
+	{
+		checkForResume();
+	}
+
 	if(!mIsDownloading)
 	{
 		// Checking can only occur during the mainloop.
@@ -214,6 +214,11 @@ void LLUpdaterServiceImpl::stopChecking()
 		mIsChecking = false;
 		mTimer.stop();
 	}
+
+    if(mIsDownloading)
+    {
+        this->mUpdateDownloader.cancel();
+    }
 }
 
 bool LLUpdaterServiceImpl::isChecking()
-- 
cgit v1.2.3


From 0018762228c627b27ccc0d98528cfe745ca5d53e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 18 Nov 2010 12:12:44 -0500
Subject: Dummy out LLUpdateDownloader::cancel() too for testing.

---
 indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 25fd1b034d..390879352c 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -100,6 +100,7 @@ std::string LLUpdateDownloader::downloadMarkerPath(void)
 }
 
 void LLUpdateDownloader::resume(void) {}
+void LLUpdateDownloader::cancel(void) {}
 
 int ll_install_update(std::string const &, std::string const &, LLInstallScriptMode)
 {
-- 
cgit v1.2.3


From cf3ded4491751231056b220525970e125d813e6a Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Thu, 18 Nov 2010 12:15:49 -0800
Subject: First draft of CHOP-106 downloaded update ready notification.
 Reviewed by mani.

---
 indra/newview/llappviewer.cpp                        | 14 ++++++++++++++
 indra/newview/llmainlooprepeater.cpp                 |  4 ++--
 indra/newview/skins/default/xui/en/notifications.xml |  8 ++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 76d518b610..0c6c77566f 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2385,6 +2385,17 @@ bool LLAppViewer::initConfiguration()
 	return true; // Config was successful.
 }
 
+namespace {
+    // *TODO - decide if there's a better place for this function.
+    // do we need a file llupdaterui.cpp or something? -brad
+    bool notify_update(LLSD const & evt)
+    {
+        LLNotificationsUtil::add("DownloadBackground");
+        // let others also handle this event by default
+        return false;
+    }
+};
+
 void LLAppViewer::initUpdater()
 {
 	// Initialize the updater service.
@@ -2409,6 +2420,9 @@ void LLAppViewer::initUpdater()
 	{
 		mUpdater->startChecking();
 	}
+
+    LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName());
+    updater_pump.listen("notify_update", notify_update);
 }
 
 void LLAppViewer::checkForCrash(void)
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
index ddc925a73b..5c020e6d98 100644
--- a/indra/newview/llmainlooprepeater.cpp
+++ b/indra/newview/llmainlooprepeater.cpp
@@ -48,9 +48,9 @@ void LLMainLoopRepeater::start(void)
 
 	mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 1024);
 	mMainLoopConnection = LLEventPumps::instance().
-		obtain("mainloop").listen("stupid name here", boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
+		obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
 	mRepeaterConnection = LLEventPumps::instance().
-		obtain("mainlooprepeater").listen("other stupid name here", boost::bind(&LLMainLoopRepeater::onMessage, this, _1));
+		obtain("mainlooprepeater").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMessage, this, _1));
 }
 
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 1f747ab997..40d5f75de2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2869,6 +2869,14 @@ Download to your Applications folder?
      yestext="Download"/>
   </notification>
 
+  <notification
+   icon="notifytip.tga"
+   name="DownloadBackground"
+   type="notifytip">
+An updated version of [APP_NAME] has been downloaded.
+It will be applied the next time you restart [APP_NAME]
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="DeedObjectToGroup"
-- 
cgit v1.2.3


From 3625a0f2362d2285d925052aedc69d27713e416d Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 18 Nov 2010 13:25:44 -0800
Subject: inform user on failed install--needs proper user dialog ;-)

---
 indra/newview/llappviewer.cpp                        | 16 ++++++++++++++--
 indra/newview/skins/default/xui/en/notifications.xml | 10 ++++++++++
 indra/viewer_components/updater/llupdaterservice.cpp |  4 ++++
 indra/viewer_components/updater/llupdaterservice.h   |  3 ++-
 4 files changed, 30 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 0c6c77566f..93fd75f74b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2390,8 +2390,20 @@ namespace {
     // do we need a file llupdaterui.cpp or something? -brad
     bool notify_update(LLSD const & evt)
     {
-        LLNotificationsUtil::add("DownloadBackground");
-        // let others also handle this event by default
+		switch (evt["type"].asInteger())
+		{
+			case LLUpdaterService::DOWNLOAD_COMPLETE:
+				LLNotificationsUtil::add("DownloadBackground");
+				break;
+			case LLUpdaterService::INSTALL_ERROR:
+				LLNotificationsUtil::add("FailedUpdateInstall");
+				break;
+			default:
+				llinfos << "unhandled update event " << evt << llendl;
+				break;
+		}
+
+		// let others also handle this event by default
         return false;
     }
 };
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 40d5f75de2..a342db8442 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2869,6 +2869,16 @@ Download to your Applications folder?
      yestext="Download"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="FailedUpdateInstall"
+   type="alertmodal">
+Gadzooks, I failed to install the latest update.
+Get thee to the interwebs and install it thyself.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
   <notification
    icon="notifytip.tga"
    name="DownloadBackground"
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 58f2c7da76..b49f6d04b0 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -408,6 +408,10 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 			llinfos << "found marker " << ll_install_failed_marker_path() << llendl;
 			llinfos << "last install attempt failed" << llendl;
 			LLFile::remove(ll_install_failed_marker_path());
+			
+			LLSD event;
+			event["type"] = LLSD(LLUpdaterService::INSTALL_ERROR);
+			LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).post(event);
 		}
 		else
 		{
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 8d0b95be86..3655136f3c 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -47,7 +47,8 @@ public:
 	enum UpdateEvent {
 		INVALID,
 		DOWNLOAD_COMPLETE,
-		DOWNLOAD_ERROR
+		DOWNLOAD_ERROR,
+		INSTALL_ERROR
 	};
 
 	LLUpdaterService();
-- 
cgit v1.2.3


From a5e3ac21b4f0764a9fdb51537abecd265764b4b9 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Thu, 18 Nov 2010 14:49:03 -0800
Subject: CHOP-187 Fixed linux updater return code to return 0 on success

---
 indra/linux_updater/linux_updater.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index cbdb3ddfe0..8aabb5ca60 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -824,7 +824,7 @@ int main(int argc, char **argv)
 		}
 	}
 
-	bool success = app_state->failure != FALSE;
+	bool success = !app_state->failure;
 	delete app_state;
 	return success ? 0 : 1;
 }
-- 
cgit v1.2.3


From 0e52564f0a36365c2ce5f5263d15778394741fde Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Thu, 18 Nov 2010 15:11:42 -0800
Subject: Fix for mac build error.

---
 indra/newview/llappviewer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 0c6c77566f..548bebcfa9 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2422,7 +2422,7 @@ void LLAppViewer::initUpdater()
 	}
 
     LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName());
-    updater_pump.listen("notify_update", notify_update);
+    updater_pump.listen("notify_update", &notify_update);
 }
 
 void LLAppViewer::checkForCrash(void)
-- 
cgit v1.2.3


From 86e84a1313f9fcb78b3e6b490dcf1604829ef175 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Thu, 18 Nov 2010 15:40:21 -0800
Subject: conform to coding standard.

---
 indra/viewer_components/updater/llupdaterservice.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 3655136f3c..55824af188 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -44,7 +44,7 @@ public:
 	static std::string const & pumpName(void);
 	
 	// Type codes for events posted by this service.  Stored the event's 'type' element.
-	enum UpdateEvent {
+	enum eUpdateEvent {
 		INVALID,
 		DOWNLOAD_COMPLETE,
 		DOWNLOAD_ERROR,
-- 
cgit v1.2.3


From c893c55d8a1328a134c956b70e6fef7fd7053d47 Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Thu, 18 Nov 2010 17:03:01 -0800
Subject: Fixing bugs discovered in merge with viewer development

---
 indra/newview/llspeakbutton.cpp                                 | 7 +++++--
 indra/newview/llspeakingindicatormanager.cpp                    | 5 ++++-
 indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 2 +-
 3 files changed, 10 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index 3dce66f394..c76ecae4a2 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -134,8 +134,11 @@ LLSpeakButton::LLSpeakButton(const Params& p)
 
 LLSpeakButton::~LLSpeakButton()
 {
-	LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn);
-	LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
+	if(LLTransientFloaterMgr::instanceExists())
+	{
+		LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn);
+		LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
+	}
 }
 
 void LLSpeakButton::setSpeakToolTip(const std::string& msg)
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index ede1d6bebe..9b38bf22ff 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -308,7 +308,10 @@ void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker
 
 void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
 {
-	SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator);
+	if(SpeakingIndicatorManager::instanceExists())
+	{
+		SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator);
+	}
 }
 
 // EOF
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 390879352c..04ed4e6364 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -61,7 +61,7 @@ class LLDir_Mock : public LLDir
 
 	BOOL getNextFileInDir(const std::string &dirname, 
 						  const std::string &mask, 
-						  std::string &fname, BOOL wrap) 
+						  std::string &fname) 
 	{
 		return false;
 	}
-- 
cgit v1.2.3


From 8c2026d6b71f133deafa6b0e19baf69632a2510a Mon Sep 17 00:00:00 2001
From: "Mark Palange (Mani)" <palange@lindenlab.com>
Date: Thu, 18 Nov 2010 21:57:27 -0800
Subject: CHOP-135 Bug fixes.

---
 indra/llcommon/llfile.cpp                          |  5 ++
 indra/newview/llappviewer.cpp                      |  3 +-
 indra/newview/llchiclet.cpp                        |  8 +-
 indra/newview/lltransientfloatermgr.cpp            |  5 +-
 .../updater/llupdatedownloader.cpp                 |  6 +-
 .../viewer_components/updater/llupdaterservice.cpp | 85 +++++++++++++---------
 indra/viewer_components/updater/llupdaterservice.h |  2 +-
 7 files changed, 71 insertions(+), 43 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 289ce0bc2c..8f02391e75 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -318,7 +318,12 @@ void llofstream::close()
 	if(is_open())
 	{
 		if (_Filebuffer->close() == 0)
+		{
 			_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
+		}
+		delete _Filebuffer;
+		_Filebuffer = NULL;
+		_ShouldClose = false;
 	}
 }
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 1fd8b02530..b6f52e3e15 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2433,7 +2433,8 @@ void LLAppViewer::initUpdater()
  	mUpdater->setCheckPeriod(check_period);
 	if(gSavedSettings.getBOOL("UpdaterServiceActive"))
 	{
-		mUpdater->startChecking();
+		bool install_if_ready = true;
+		mUpdater->startChecking(install_if_ready);
 	}
 
     LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName());
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 8f385160e9..885d553524 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1092,9 +1092,11 @@ LLChicletPanel::LLChicletPanel(const Params&p)
 
 LLChicletPanel::~LLChicletPanel()
 {
-	LLTransientFloaterMgr::getInstance()->removeControlView(mLeftScrollButton);
-	LLTransientFloaterMgr::getInstance()->removeControlView(mRightScrollButton);
-
+	if(LLTransientFloaterMgr::instanceExists())
+	{
+		LLTransientFloaterMgr::getInstance()->removeControlView(mLeftScrollButton);
+		LLTransientFloaterMgr::getInstance()->removeControlView(mRightScrollButton);
+	}
 }
 
 void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index 78dd602f39..6deab96b45 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -36,8 +36,11 @@
 
 LLTransientFloaterMgr::LLTransientFloaterMgr()
 {
-	gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(
+	if(gViewerWindow)
+	{
+		gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(
 			&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));
+	}
 
 	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
 	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 4820f1f452..c17a50e242 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -204,7 +204,11 @@ bool LLUpdateDownloader::Implementation::isDownloading(void)
 
 void LLUpdateDownloader::Implementation::resume(void)
 {
-	if(isDownloading()) mClient.downloadError("download in progress");
+	mCancelled = false;
+
+	if(isDownloading()) {
+		mClient.downloadError("download in progress");
+	}
 
 	mDownloadRecordPath = downloadMarkerPath();
 	llifstream dataStream(mDownloadRecordPath);
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index b49f6d04b0..cc60eaead2 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -112,13 +112,13 @@ public:
 	
 	void setCheckPeriod(unsigned int seconds);
 
-	void startChecking();
+	void startChecking(bool install_if_ready);
 	void stopChecking();
 	bool isChecking();
 	
 	void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;}
 
-	bool checkForInstall(); // Test if a local install is ready.
+	bool checkForInstall(bool launchInstaller); // Test if a local install is ready.
 	bool checkForResume(); // Test for resumeable d/l.
 
 	// LLUpdateChecker::Client:
@@ -139,6 +139,7 @@ public:
 
 private:
 	void restartTimer(unsigned int seconds);
+	void stopTimer();
 };
 
 const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
@@ -182,7 +183,7 @@ void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
 	mCheckPeriod = seconds;
 }
 
-void LLUpdaterServiceImpl::startChecking()
+void LLUpdaterServiceImpl::startChecking(bool install_if_ready)
 {
 	if(mUrl.empty() || mChannel.empty() || mVersion.empty())
 	{
@@ -193,17 +194,18 @@ void LLUpdaterServiceImpl::startChecking()
 	mIsChecking = true;
 
     // Check to see if an install is ready.
-	if(!checkForInstall())
+	bool has_install = checkForInstall(install_if_ready);
+	if(!has_install)
 	{
-		checkForResume();
-	}
+		checkForResume(); // will set mIsDownloading to true if resuming
 
-	if(!mIsDownloading)
-	{
-		// Checking can only occur during the mainloop.
-		// reset the timer to 0 so that the next mainloop event 
-		// triggers a check;
-		restartTimer(0); 
+		if(!mIsDownloading)
+		{
+			// Checking can only occur during the mainloop.
+			// reset the timer to 0 so that the next mainloop event 
+			// triggers a check;
+			restartTimer(0); 
+		}
 	}
 }
 
@@ -212,12 +214,13 @@ void LLUpdaterServiceImpl::stopChecking()
 	if(mIsChecking)
 	{
 		mIsChecking = false;
-		mTimer.stop();
+		stopTimer();
 	}
 
     if(mIsDownloading)
     {
-        this->mUpdateDownloader.cancel();
+        mUpdateDownloader.cancel();
+		mIsDownloading = false;
     }
 }
 
@@ -226,9 +229,9 @@ bool LLUpdaterServiceImpl::isChecking()
 	return mIsChecking;
 }
 
-bool LLUpdaterServiceImpl::checkForInstall()
+bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)
 {
-	bool result = false; // return true if install is found.
+	bool foundInstall = false; // return true if install is found.
 
 	llifstream update_marker(update_marker_path(), 
 							 std::ios::in | std::ios::binary);
@@ -239,7 +242,6 @@ bool LLUpdaterServiceImpl::checkForInstall()
 		LLSD update_info;
 		LLSDSerialize::fromXMLDocument(update_info, update_marker);
 		update_marker.close();
-		LLFile::remove(update_marker_path());
 
 		// Get the path to the installer file.
 		LLSD path = update_info.get("path");
@@ -251,33 +253,39 @@ bool LLUpdaterServiceImpl::checkForInstall()
 			{
 				llinfos << "ignoring update dowloaded by different client version" << llendl;
 				LLFile::remove(path.asString());
+				LLFile::remove(update_marker_path());
 			}
 			else
 			{
 				; // Nothing to clean up.
 			}
 			
-			result = false;
+			foundInstall = false;
 		} 
 		else if(path.isDefined() && !path.asString().empty())
 		{
-			int result = ll_install_update(install_script_path(),
-										   update_info["path"].asString(),
-										   install_script_mode());	
-			
-			if((result == 0) && mAppExitCallback)
+			if(launchInstaller)
 			{
-				mAppExitCallback();
-			} else if(result != 0) {
-				llwarns << "failed to run update install script" << LL_ENDL;
-			} else {
-				; // No op.
+				LLFile::remove(update_marker_path());
+
+				int result = ll_install_update(install_script_path(),
+											   update_info["path"].asString(),
+											   install_script_mode());	
+				
+				if((result == 0) && mAppExitCallback)
+				{
+					mAppExitCallback();
+				} else if(result != 0) {
+					llwarns << "failed to run update install script" << LL_ENDL;
+				} else {
+					; // No op.
+				}
 			}
 			
-			result = true;
+			foundInstall = true;
 		}
 	}
-	return result;
+	return foundInstall;
 }
 
 bool LLUpdaterServiceImpl::checkForResume()
@@ -324,7 +332,7 @@ void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion,
 										  LLURI const & uri,
 										  std::string const & hash)
 {
-	mTimer.stop();
+	stopTimer();
 	mIsDownloading = true;
 	mUpdateDownloader.download(uri, hash);
 }
@@ -333,7 +341,7 @@ void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion,
 										  LLURI const & uri,
 										  std::string const & hash)
 {
-	mTimer.stop();
+	stopTimer();
 	mIsDownloading = true;
 	mUpdateDownloader.download(uri, hash);
 }
@@ -394,12 +402,17 @@ void LLUpdaterServiceImpl::restartTimer(unsigned int seconds)
 		sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
 }
 
+void LLUpdaterServiceImpl::stopTimer()
+{
+	mTimer.stop();
+	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
+}
+
 bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 {
 	if(mTimer.getStarted() && mTimer.hasExpired())
 	{
-		mTimer.stop();
-		LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
+		stopTimer();
 
 		// Check for failed install.
 		if(LLFile::isfile(ll_install_failed_marker_path()))
@@ -468,9 +481,9 @@ void LLUpdaterService::setCheckPeriod(unsigned int seconds)
 	mImpl->setCheckPeriod(seconds);
 }
 	
-void LLUpdaterService::startChecking()
+void LLUpdaterService::startChecking(bool install_if_ready)
 {
-	mImpl->startChecking();
+	mImpl->startChecking(install_if_ready);
 }
 
 void LLUpdaterService::stopChecking()
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 55824af188..752a6f834b 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -62,7 +62,7 @@ public:
 
 	void setCheckPeriod(unsigned int seconds);
 	
-	void startChecking();
+	void startChecking(bool install_if_ready = false);
 	void stopChecking();
 	bool isChecking();
 
-- 
cgit v1.2.3


From 8d21105a8c2b6bff98b4f3b91a614a4710d4b7ea Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 19 Nov 2010 12:04:01 -0800
Subject: dull boring notification message.

---
 indra/newview/skins/default/xui/en/notifications.xml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 0663583543..9536bf2cf7 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2873,8 +2873,9 @@ Download to your Applications folder?
    icon="alertmodal.tga"
    name="FailedUpdateInstall"
    type="alertmodal">
-Gadzooks, I failed to install the latest update.
-Get thee to the interwebs and install it thyself.
+An error occurred installing the viewer update.
+Please download and install the latest viewer from
+http://secondlife.com/download.
     <usetemplate
      name="okbutton"
      yestext="OK"/>
-- 
cgit v1.2.3