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 | |
| parent | 7b61f1d0ec30e97fd3b7c5caf4b0e675c6e9a1f5 (diff) | |
merge -r61423:62602 svn/branches/maintenance --> release
Diffstat (limited to 'indra/mac_updater')
| -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 */ | 
