diff options
author | Kelly Washington <kelly@lindenlab.com> | 2007-05-30 17:39:09 +0000 |
---|---|---|
committer | Kelly Washington <kelly@lindenlab.com> | 2007-05-30 17:39:09 +0000 |
commit | 3e9872a297c3cf3f929e688e0e89a78f6bc050f5 (patch) | |
tree | ab3877f764cc27dbdca0b683f07e6ea3a3ac8a23 /indra/mac_updater/mac_updater.cpp | |
parent | 7b61f1d0ec30e97fd3b7c5caf4b0e675c6e9a1f5 (diff) |
merge -r61423:62602 svn/branches/maintenance --> release
Diffstat (limited to 'indra/mac_updater/mac_updater.cpp')
-rw-r--r-- | indra/mac_updater/mac_updater.cpp | 194 |
1 files changed, 143 insertions, 51 deletions
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index 4b56148f10..91bf24ec11 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -517,8 +517,7 @@ bool isDirWritable(FSRef &dir) static void utf8str_to_HFSUniStr255(HFSUniStr255 *dest, const char* src) { - LLWString wstr = utf8str_to_wstring(src); - llutf16string utf16str = wstring_to_utf16str(wstr); + llutf16string utf16str = utf8str_to_utf16str(src); dest->length = utf16str.size(); if(dest->length > 255) @@ -530,6 +529,13 @@ static void utf8str_to_HFSUniStr255(HFSUniStr255 *dest, const char* src) memcpy(dest->unicode, utf16str.data(), sizeof(UniChar)* dest->length); /* Flawfinder: ignore */ } +static std::string HFSUniStr255_to_utf8str(const HFSUniStr255* src) +{ + llutf16string string16((U16*)&(src->unicode), src->length); + std::string result = utf16str_to_utf8str(string16); + return result; +} + int restoreObject(const char* aside, const char* target, const char* path, const char* object) { char source[PATH_MAX]; /* Flawfinder: ignore */ @@ -578,6 +584,123 @@ void filterFile(const char* filename) system(temp); /* Flawfinder: ignore */ } +static bool isFSRefViewerBundle(FSRef *targetRef) +{ + bool result = false; + CFURLRef targetURL = NULL; + CFBundleRef targetBundle = NULL; + CFStringRef targetBundleID = NULL; + + targetURL = CFURLCreateFromFSRef(NULL, targetRef); + + if(targetURL == NULL) + { + llinfos << "Error creating target URL." << llendl; + } + else + { + targetBundle = CFBundleCreate(NULL, targetURL); + } + + if(targetBundle == NULL) + { + llinfos << "Failed to create target bundle." << llendl; + } + else + { + targetBundleID = CFBundleGetIdentifier(targetBundle); + } + + if(targetBundleID == NULL) + { + llinfos << "Couldn't retrieve target bundle ID." << llendl; + } + else + { + if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo) + { + // This is the bundle we're looking for. + result = true; + } + else + { + llinfos << "Target bundle ID mismatch." << llendl; + } + } + + // Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. + if(targetURL != NULL) + CFRelease(targetURL); + if(targetBundle != NULL) + CFRelease(targetBundle); + + return result; +} + +// Search through the directory specified by 'parent' for an item that appears to be a Second Life viewer. +static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) +{ + FSIterator iterator; + bool found = false; + + OSErr err = FSOpenIterator( parent, kFSIterateFlat, &iterator ); + if(!err) + { + do + { + ItemCount actualObjects = 0; + Boolean containerChanged = false; + FSCatalogInfo info; + FSRef ref; + HFSUniStr255 unicodeName; + err = FSGetCatalogInfoBulk( + iterator, + 1, + &actualObjects, + &containerChanged, + kFSCatInfoNodeFlags, + &info, + &ref, + NULL, + &unicodeName ); + + if(actualObjects == 0) + break; + + if(!err) + { + // Call succeeded and not done with the iteration. + std::string name = HFSUniStr255_to_utf8str(&unicodeName); + + llinfos << "Considering \"" << name << "\"" << llendl; + + if(info.nodeFlags & kFSNodeIsDirectoryMask) + { + // This is a directory. See if it's a .app + if(name.find(".app") != std::string::npos) + { + // Looks promising. Check to see if it has the right bundle identifier. + if(isFSRefViewerBundle(&ref)) + { + // This is the one. Return it. + *app = ref; + found = true; + } + } + } + } + } + while(!err && !found); + + FSCloseIterator(iterator); + } + + if(!err && !found) + err = fnfErr; + + return err; +} + void *updatethreadproc(void*) { char tempDir[PATH_MAX] = ""; /* Flawfinder: ignore */ @@ -650,57 +773,15 @@ void *updatethreadproc(void*) // Sanity check: make sure the target is a bundle with the right identifier if(err == noErr) { - CFURLRef targetURL = NULL; - CFBundleRef targetBundle = NULL; - CFStringRef targetBundleID = NULL; - // Assume the worst... err = -1; - - targetURL = CFURLCreateFromFSRef(NULL, &targetRef); - if(targetURL == NULL) - { - llinfos << "Error creating target URL." << llendl; - } - else + if(isFSRefViewerBundle(&targetRef)) { - targetBundle = CFBundleCreate(NULL, targetURL); - } - - if(targetBundle == NULL) - { - llinfos << "Failed to create target bundle." << llendl; - } - else - { - targetBundleID = CFBundleGetIdentifier(targetBundle); - } - - if(targetBundleID == NULL) - { - llinfos << "Couldn't retrieve target bundle ID." << llendl; - } - else - { - if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo) - { - // This is the bundle we're looking for. - err = noErr; - replacingTarget = true; - } - else - { - llinfos << "Target bundle ID mismatch." << llendl; - } + // This is the bundle we're looking for. + err = noErr; + replacingTarget = true; } - - // Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. - if(targetURL != NULL) - CFRelease(targetURL); - if(targetBundle != NULL) - CFRelease(targetBundle); - } // Make sure the target's parent directory is writable. @@ -923,13 +1004,24 @@ void *updatethreadproc(void*) // Get an FSRef to the new application on the disk image FSRef sourceRef; - snprintf(temp, sizeof(temp), "%s/mnt/Second Life.app", tempDir); + FSRef mountRef; + snprintf(temp, sizeof(temp), "%s/mnt", tempDir); - llinfos << "Source application is: " << temp << llendl; + llinfos << "Disk image mount point is: " << temp << llendl; - err = FSPathMakeRef((UInt8 *)temp, &sourceRef, NULL); + err = FSPathMakeRef((UInt8 *)temp, &mountRef, NULL); if(err != noErr) + { + llinfos << "Couldn't make FSRef to disk image mount point." << llendl; throw 0; + } + + err = findAppBundleOnDiskImage(&mountRef, &sourceRef); + if(err != noErr) + { + llinfos << "Couldn't find application bundle on mounted disk image." << llendl; + throw 0; + } FSRef asideRef; char aside[MAX_PATH]; /* Flawfinder: ignore */ |