PageRenderTime 31ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/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
Possible License(s): LGPL-2.1
  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. #if LL_DARWIN
  27. #include "linden_common.h"
  28. #include "lldir_mac.h"
  29. #include "llerror.h"
  30. #include "llrand.h"
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include <unistd.h>
  34. #include <glob.h>
  35. #include <Carbon/Carbon.h>
  36. // --------------------------------------------------------------------------------
  37. static OSStatus CFCreateDirectory(FSRef *parentRef, CFStringRef name, FSRef *newRef)
  38. {
  39. OSStatus result = noErr;
  40. HFSUniStr255 uniStr;
  41. uniStr.length = CFStringGetLength(name);
  42. CFStringGetCharacters(name, CFRangeMake(0, uniStr.length), uniStr.unicode);
  43. result = FSMakeFSRefUnicode(parentRef, uniStr.length, uniStr.unicode, kTextEncodingMacRoman, newRef);
  44. if (result != noErr)
  45. {
  46. result = FSCreateDirectoryUnicode(parentRef, uniStr.length, uniStr.unicode, 0, NULL, newRef, NULL, NULL);
  47. }
  48. return result;
  49. }
  50. // --------------------------------------------------------------------------------
  51. static void CFStringRefToLLString(CFStringRef stringRef, std::string &llString, bool releaseWhenDone)
  52. {
  53. if (stringRef)
  54. {
  55. long stringSize = CFStringGetLength(stringRef) + 1;
  56. long bufferSize = CFStringGetMaximumSizeForEncoding(stringSize,kCFStringEncodingUTF8);
  57. char* buffer = new char[bufferSize];
  58. memset(buffer, 0, bufferSize);
  59. if (CFStringGetCString(stringRef, buffer, bufferSize, kCFStringEncodingUTF8))
  60. llString = buffer;
  61. delete[] buffer;
  62. if (releaseWhenDone)
  63. CFRelease(stringRef);
  64. }
  65. }
  66. // --------------------------------------------------------------------------------
  67. static void CFURLRefToLLString(CFURLRef urlRef, std::string &llString, bool releaseWhenDone)
  68. {
  69. if (urlRef)
  70. {
  71. CFURLRef absoluteURLRef = CFURLCopyAbsoluteURL(urlRef);
  72. if (absoluteURLRef)
  73. {
  74. CFStringRef stringRef = CFURLCopyFileSystemPath(absoluteURLRef, kCFURLPOSIXPathStyle);
  75. CFStringRefToLLString(stringRef, llString, true);
  76. CFRelease(absoluteURLRef);
  77. }
  78. if (releaseWhenDone)
  79. CFRelease(urlRef);
  80. }
  81. }
  82. // --------------------------------------------------------------------------------
  83. static void FSRefToLLString(FSRef *fsRef, std::string &llString)
  84. {
  85. OSStatus error = noErr;
  86. char path[MAX_PATH];
  87. error = FSRefMakePath(fsRef, (UInt8*) path, sizeof(path));
  88. if (error == noErr)
  89. llString = path;
  90. }
  91. // --------------------------------------------------------------------------------
  92. LLDir_Mac::LLDir_Mac()
  93. {
  94. mDirDelimiter = "/";
  95. mCurrentDirIndex = -1;
  96. mCurrentDirCount = -1;
  97. CFBundleRef mainBundleRef = NULL;
  98. CFURLRef executableURLRef = NULL;
  99. CFStringRef stringRef = NULL;
  100. OSStatus error = noErr;
  101. FSRef fileRef;
  102. CFStringRef secondLifeString = CFSTR("SecondLife");
  103. mainBundleRef = CFBundleGetMainBundle();
  104. executableURLRef = CFBundleCopyExecutableURL(mainBundleRef);
  105. if (executableURLRef != NULL)
  106. {
  107. // mExecutablePathAndName
  108. CFURLRefToLLString(executableURLRef, mExecutablePathAndName, false);
  109. // mExecutableFilename
  110. stringRef = CFURLCopyLastPathComponent(executableURLRef);
  111. CFStringRefToLLString(stringRef, mExecutableFilename, true);
  112. // mExecutableDir
  113. CFURLRef executableParentURLRef = CFURLCreateCopyDeletingLastPathComponent(NULL, executableURLRef);
  114. CFURLRefToLLString(executableParentURLRef, mExecutableDir, true);
  115. // mAppRODataDir
  116. // *NOTE: When running in a dev tree, use the copy of
  117. // skins in indra/newview/ rather than in the application bundle. This
  118. // mirrors Windows dev environment behavior and allows direct checkin
  119. // of edited skins/xui files. JC
  120. // MBW -- This keeps the mac application from finding other things.
  121. // If this is really for skins, it should JUST apply to skins.
  122. CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
  123. CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true);
  124. U32 build_dir_pos = mExecutableDir.rfind("/build-darwin-");
  125. if (build_dir_pos != std::string::npos)
  126. {
  127. // ...we're in a dev checkout
  128. mSkinBaseDir = mExecutableDir.substr(0, build_dir_pos)
  129. + "/indra/newview/skins";
  130. llinfos << "Running in dev checkout with mSkinBaseDir "
  131. << mSkinBaseDir << llendl;
  132. }
  133. else
  134. {
  135. // ...normal installation running
  136. mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
  137. }
  138. // mOSUserDir
  139. error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef);
  140. if (error == noErr)
  141. {
  142. FSRef newFileRef;
  143. // Create the directory
  144. error = CFCreateDirectory(&fileRef, secondLifeString, &newFileRef);
  145. if (error == noErr)
  146. {
  147. // Save the full path to the folder
  148. FSRefToLLString(&newFileRef, mOSUserDir);
  149. // Create our sub-dirs
  150. (void) CFCreateDirectory(&newFileRef, CFSTR("data"), NULL);
  151. //(void) CFCreateDirectory(&newFileRef, CFSTR("cache"), NULL);
  152. (void) CFCreateDirectory(&newFileRef, CFSTR("logs"), NULL);
  153. (void) CFCreateDirectory(&newFileRef, CFSTR("user_settings"), NULL);
  154. (void) CFCreateDirectory(&newFileRef, CFSTR("browser_profile"), NULL);
  155. }
  156. }
  157. //mOSCacheDir
  158. FSRef cacheDirRef;
  159. error = FSFindFolder(kUserDomain, kCachedDataFolderType, true, &cacheDirRef);
  160. if (error == noErr)
  161. {
  162. FSRefToLLString(&cacheDirRef, mOSCacheDir);
  163. (void)CFCreateDirectory(&cacheDirRef, CFSTR("SecondLife"),NULL);
  164. }
  165. // mOSUserAppDir
  166. mOSUserAppDir = mOSUserDir;
  167. // mTempDir
  168. error = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, true, &fileRef);
  169. if (error == noErr)
  170. {
  171. FSRef tempRef;
  172. error = CFCreateDirectory(&fileRef, secondLifeString, &tempRef);
  173. if (error == noErr)
  174. FSRefToLLString(&tempRef, mTempDir);
  175. }
  176. mWorkingDir = getCurPath();
  177. mLLPluginDir = mAppRODataDir + mDirDelimiter + "llplugin";
  178. CFRelease(executableURLRef);
  179. executableURLRef = NULL;
  180. }
  181. }
  182. LLDir_Mac::~LLDir_Mac()
  183. {
  184. }
  185. // Implementation
  186. void LLDir_Mac::initAppDirs(const std::string &app_name,
  187. const std::string& app_read_only_data_dir)
  188. {
  189. // Allow override so test apps can read newview directory
  190. if (!app_read_only_data_dir.empty())
  191. {
  192. mAppRODataDir = app_read_only_data_dir;
  193. mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
  194. }
  195. mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
  196. //dumpCurrentDirectories();
  197. }
  198. U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &mask)
  199. {
  200. U32 file_count = 0;
  201. glob_t g;
  202. std::string tmp_str;
  203. tmp_str = dirname;
  204. tmp_str += mask;
  205. if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
  206. {
  207. file_count = g.gl_pathc;
  208. globfree(&g);
  209. }
  210. return (file_count);
  211. }
  212. std::string LLDir_Mac::getCurPath()
  213. {
  214. char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
  215. getcwd(tmp_str, LL_MAX_PATH);
  216. return tmp_str;
  217. }
  218. BOOL LLDir_Mac::fileExists(const std::string &filename) const
  219. {
  220. struct stat stat_data;
  221. // Check the age of the file
  222. // Now, we see if the files we've gathered are recent...
  223. int res = stat(filename.c_str(), &stat_data);
  224. if (!res)
  225. {
  226. return TRUE;
  227. }
  228. else
  229. {
  230. return FALSE;
  231. }
  232. }
  233. /*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
  234. {
  235. return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
  236. "SLPlugin.app/Contents/MacOS/SLPlugin";
  237. }
  238. /*virtual*/ std::string LLDir_Mac::getLLPluginFilename(std::string base_name)
  239. {
  240. return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
  241. base_name + ".dylib";
  242. }
  243. #endif // LL_DARWIN