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