PageRenderTime 33ms CodeModel.GetById 10ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llvfs/lldir_mac.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 300 lines | 188 code | 57 blank | 55 comment | 28 complexity | f5fe66b2b28d84c8f7c007e0f10ba04a MD5 | raw file
  1/** 
  2 * @file lldir_mac.cpp
  3 * @brief Implementation of directory utilities for Mac OS X
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#if LL_DARWIN
 28
 29#include "linden_common.h"
 30
 31#include "lldir_mac.h"
 32#include "llerror.h"
 33#include "llrand.h"
 34#include <sys/types.h>
 35#include <sys/stat.h>
 36#include <unistd.h>
 37#include <glob.h>
 38
 39#include <Carbon/Carbon.h>
 40
 41// --------------------------------------------------------------------------------
 42
 43static OSStatus CFCreateDirectory(FSRef	*parentRef, CFStringRef name, FSRef *newRef)
 44{
 45	OSStatus		result = noErr;
 46	HFSUniStr255	uniStr;
 47	
 48	uniStr.length = CFStringGetLength(name);
 49	CFStringGetCharacters(name, CFRangeMake(0, uniStr.length), uniStr.unicode);
 50	result = FSMakeFSRefUnicode(parentRef, uniStr.length, uniStr.unicode, kTextEncodingMacRoman, newRef);
 51	if (result != noErr)
 52	{
 53		result = FSCreateDirectoryUnicode(parentRef, uniStr.length, uniStr.unicode, 0, NULL, newRef, NULL, NULL);
 54	}
 55
 56	return result;
 57}
 58
 59// --------------------------------------------------------------------------------
 60
 61static void CFStringRefToLLString(CFStringRef stringRef, std::string &llString, bool releaseWhenDone)
 62{
 63	if (stringRef)
 64	{
 65		long stringSize = CFStringGetLength(stringRef) + 1;
 66		long bufferSize = CFStringGetMaximumSizeForEncoding(stringSize,kCFStringEncodingUTF8);
 67		char* buffer = new char[bufferSize];
 68		memset(buffer, 0, bufferSize);
 69		if (CFStringGetCString(stringRef, buffer, bufferSize, kCFStringEncodingUTF8))
 70			llString = buffer;
 71		delete[] buffer;
 72		if (releaseWhenDone)
 73			CFRelease(stringRef);
 74	}
 75}
 76
 77// --------------------------------------------------------------------------------
 78
 79static void CFURLRefToLLString(CFURLRef urlRef, std::string &llString, bool releaseWhenDone)
 80{
 81	if (urlRef)
 82	{
 83		CFURLRef	absoluteURLRef = CFURLCopyAbsoluteURL(urlRef);
 84		if (absoluteURLRef)
 85		{
 86			CFStringRef	stringRef = CFURLCopyFileSystemPath(absoluteURLRef, kCFURLPOSIXPathStyle);
 87			CFStringRefToLLString(stringRef, llString, true);
 88			CFRelease(absoluteURLRef);
 89		}
 90		if (releaseWhenDone)
 91			CFRelease(urlRef);
 92	}
 93}
 94
 95// --------------------------------------------------------------------------------
 96
 97static void FSRefToLLString(FSRef *fsRef, std::string &llString)
 98{
 99	OSStatus	error = noErr;
100	char		path[MAX_PATH];
101	
102	error = FSRefMakePath(fsRef, (UInt8*) path, sizeof(path));
103	if (error == noErr)
104		llString = path;
105}
106
107// --------------------------------------------------------------------------------
108
109LLDir_Mac::LLDir_Mac()
110{
111	mDirDelimiter = "/";
112	mCurrentDirIndex = -1;
113	mCurrentDirCount = -1;
114	
115	CFBundleRef		mainBundleRef = NULL;
116	CFURLRef		executableURLRef = NULL;
117	CFStringRef		stringRef = NULL;
118	OSStatus		error = noErr;
119	FSRef			fileRef;
120	CFStringRef		secondLifeString = CFSTR("SecondLife");
121	
122	mainBundleRef = CFBundleGetMainBundle();
123		
124	executableURLRef = CFBundleCopyExecutableURL(mainBundleRef);
125	
126	if (executableURLRef != NULL)
127	{
128		// mExecutablePathAndName
129		CFURLRefToLLString(executableURLRef, mExecutablePathAndName, false);
130		
131		// mExecutableFilename
132		stringRef = CFURLCopyLastPathComponent(executableURLRef);
133		CFStringRefToLLString(stringRef, mExecutableFilename, true);
134		
135		// mExecutableDir
136		CFURLRef	executableParentURLRef = CFURLCreateCopyDeletingLastPathComponent(NULL, executableURLRef);
137		CFURLRefToLLString(executableParentURLRef, mExecutableDir, true);
138		
139		// mAppRODataDir
140
141		
142		// *NOTE: When running in a dev tree, use the copy of
143		// skins in indra/newview/ rather than in the application bundle.  This
144		// mirrors Windows dev environment behavior and allows direct checkin
145		// of edited skins/xui files. JC
146		
147		// MBW -- This keeps the mac application from finding other things.
148		// If this is really for skins, it should JUST apply to skins.
149
150		CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
151		CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true);
152		
153		U32 build_dir_pos = mExecutableDir.rfind("/build-darwin-");
154		if (build_dir_pos != std::string::npos)
155		{
156			// ...we're in a dev checkout
157			mSkinBaseDir = mExecutableDir.substr(0, build_dir_pos)
158				+ "/indra/newview/skins";
159			llinfos << "Running in dev checkout with mSkinBaseDir "
160				<< mSkinBaseDir << llendl;
161		}
162		else
163		{
164			// ...normal installation running
165			mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
166		}
167		
168		// mOSUserDir
169		error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef);
170		if (error == noErr)
171		{
172			FSRef	newFileRef;
173			
174			// Create the directory
175			error = CFCreateDirectory(&fileRef, secondLifeString, &newFileRef);
176			if (error == noErr)
177			{
178				// Save the full path to the folder
179				FSRefToLLString(&newFileRef, mOSUserDir);
180				
181				// Create our sub-dirs
182				(void) CFCreateDirectory(&newFileRef, CFSTR("data"), NULL);
183				//(void) CFCreateDirectory(&newFileRef, CFSTR("cache"), NULL);
184				(void) CFCreateDirectory(&newFileRef, CFSTR("logs"), NULL);
185				(void) CFCreateDirectory(&newFileRef, CFSTR("user_settings"), NULL);
186				(void) CFCreateDirectory(&newFileRef, CFSTR("browser_profile"), NULL);
187			}
188		}
189		
190		//mOSCacheDir
191		FSRef cacheDirRef;
192		error = FSFindFolder(kUserDomain, kCachedDataFolderType, true, &cacheDirRef);
193		if (error == noErr)
194		{
195			FSRefToLLString(&cacheDirRef, mOSCacheDir);
196			(void)CFCreateDirectory(&cacheDirRef, CFSTR("SecondLife"),NULL);
197		}
198		
199		// mOSUserAppDir
200		mOSUserAppDir = mOSUserDir;
201		
202		// mTempDir
203		error = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, true, &fileRef);
204		if (error == noErr)
205		{
206			FSRef	tempRef;
207			error = CFCreateDirectory(&fileRef, secondLifeString, &tempRef);
208			if (error == noErr)
209				FSRefToLLString(&tempRef, mTempDir);
210		}
211		
212		mWorkingDir = getCurPath();
213
214		mLLPluginDir = mAppRODataDir + mDirDelimiter + "llplugin";
215				
216		CFRelease(executableURLRef);
217		executableURLRef = NULL;
218	}
219}
220
221LLDir_Mac::~LLDir_Mac()
222{
223}
224
225// Implementation
226
227
228void LLDir_Mac::initAppDirs(const std::string &app_name,
229							const std::string& app_read_only_data_dir)
230{
231	// Allow override so test apps can read newview directory
232	if (!app_read_only_data_dir.empty())
233	{
234		mAppRODataDir = app_read_only_data_dir;
235		mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
236	}
237	mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
238
239	//dumpCurrentDirectories();
240}
241
242U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &mask)
243{
244	U32 file_count = 0;
245	glob_t g;
246
247	std::string tmp_str;
248	tmp_str = dirname;
249	tmp_str += mask;
250	
251	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
252	{
253		file_count = g.gl_pathc;
254
255		globfree(&g);
256	}
257
258	return (file_count);
259}
260
261std::string LLDir_Mac::getCurPath()
262{
263	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
264	getcwd(tmp_str, LL_MAX_PATH);
265	return tmp_str;
266}
267
268
269
270BOOL LLDir_Mac::fileExists(const std::string &filename) const
271{
272	struct stat stat_data;
273	// Check the age of the file
274	// Now, we see if the files we've gathered are recent...
275	int res = stat(filename.c_str(), &stat_data);
276	if (!res)
277	{
278		return TRUE;
279	}
280	else
281	{
282		return FALSE;
283	}
284}
285
286
287/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
288{
289	return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
290		"SLPlugin.app/Contents/MacOS/SLPlugin";
291}
292
293/*virtual*/ std::string LLDir_Mac::getLLPluginFilename(std::string base_name)
294{
295	return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
296		base_name + ".dylib";
297}
298
299
300#endif // LL_DARWIN