summaryrefslogtreecommitdiff
path: root/indra/mac_updater/mac_updater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/mac_updater/mac_updater.cpp')
-rw-r--r--indra/mac_updater/mac_updater.cpp113
1 files changed, 94 insertions, 19 deletions
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index e4d100d1ec..809f66cb1d 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>
@@ -61,6 +64,9 @@ Boolean gCancelled = false;
const char *gUpdateURL;
const char *gProductName;
+const char *gBundleID;
+const char *gDmgFile;
+const char *gMarkerPath;
void *updatethreadproc(void*);
@@ -329,6 +335,18 @@ int parse_args(int argc, char **argv)
{
gProductName = argv[j];
}
+ else if ((!strcmp(argv[j], "-bundleid")) && (++j < argc))
+ {
+ gBundleID = argv[j];
+ }
+ else if ((!strcmp(argv[j], "-dmg")) && (++j < argc))
+ {
+ gDmgFile = argv[j];
+ }
+ else if ((!strcmp(argv[j], "-marker")) && (++j < argc))
+ {
+ gMarkerPath = argv[j];;
+ }
}
return 0;
@@ -355,10 +373,13 @@ int main(int argc, char **argv)
//
gUpdateURL = NULL;
gProductName = NULL;
+ gBundleID = NULL;
+ gDmgFile = NULL;
+ gMarkerPath = 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
@@ -372,6 +393,14 @@ int main(int argc, char **argv)
{
gProductName = "Second Life";
}
+ if (gBundleID)
+ {
+ llinfos << "Bundle ID is: " << gBundleID << llendl;
+ }
+ else
+ {
+ gBundleID = "com.secondlife.indra.viewer";
+ }
}
llinfos << "Starting " << gProductName << " Updater" << llendl;
@@ -474,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)
{
@@ -592,7 +628,8 @@ static bool isFSRefViewerBundle(FSRef *targetRef)
CFURLRef targetURL = NULL;
CFBundleRef targetBundle = NULL;
CFStringRef targetBundleID = NULL;
-
+ CFStringRef sourceBundleID = NULL;
+
targetURL = CFURLCreateFromFSRef(NULL, targetRef);
if(targetURL == NULL)
@@ -619,7 +656,8 @@ static bool isFSRefViewerBundle(FSRef *targetRef)
}
else
{
- if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo)
+ sourceBundleID = CFStringCreateWithCString(NULL, gBundleID, kCFStringEncodingUTF8);
+ if(CFStringCompare(sourceBundleID, targetBundleID, 0) == kCFCompareEqualTo)
{
// This is the bundle we're looking for.
result = true;
@@ -684,17 +722,26 @@ 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;
+ break;
+ } else {
+ llinfos << name << " is not the bundle we are looking for; move along" << llendl;
}
+
}
}
}
}
- while(!err && !found);
+ while(!err);
+
+ llinfos << "closing the iterator" << llendl;
FSCloseIterator(iterator);
+
+ llinfos << "closed" << llendl;
}
if(!err && !found)
@@ -905,6 +952,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)
{
@@ -963,14 +1026,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)
{
@@ -1036,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 */
@@ -1061,7 +1134,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));
@@ -1153,16 +1230,14 @@ void *updatethreadproc(void*)
// Move work directory to the trash
if(tempDir[0] != 0)
{
-// chdir("/");
-// FSDeleteObjects(tempDirRef);
-
llinfos << "Moving work directory to the trash." << llendl;
- err = FSMoveObject(&tempDirRef, &trashFolderRef, NULL);
-
-// snprintf(temp, sizeof(temp), "rm -rf '%s'", tempDir);
-// printf("%s\n", temp);
-// system(temp);
+ FSRef trashRef;
+ OSStatus err = FSMoveObjectToTrashSync(&tempDirRef, &trashRef, 0);
+ if(err != noErr) {
+ llwarns << "failed to move files to trash, (error code " <<
+ err << ")" << llendl;
+ }
}
if(!gCancelled && !gFailure && (target[0] != 0))