aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llvfs/lldir_mac.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llvfs/lldir_mac.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llvfs/lldir_mac.cpp')
-rw-r--r--linden/indra/llvfs/lldir_mac.cpp381
1 files changed, 381 insertions, 0 deletions
diff --git a/linden/indra/llvfs/lldir_mac.cpp b/linden/indra/llvfs/lldir_mac.cpp
new file mode 100644
index 0000000..683b961
--- /dev/null
+++ b/linden/indra/llvfs/lldir_mac.cpp
@@ -0,0 +1,381 @@
1/**
2 * @file lldir_mac.cpp
3 * @brief Implementation of directory utilities for linux
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#if LL_DARWIN
29
30#include "linden_common.h"
31
32#include "lldir_mac.h"
33#include "llerror.h"
34#include "llrand.h"
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <unistd.h>
38#include <glob.h>
39
40#include <Carbon/Carbon.h>
41
42// --------------------------------------------------------------------------------
43
44static OSStatus CFCreateDirectory(FSRef *parentRef, CFStringRef name, FSRef *newRef)
45{
46 OSStatus result = noErr;
47 HFSUniStr255 uniStr;
48
49 uniStr.length = CFStringGetLength(name);
50 CFStringGetCharacters(name, CFRangeMake(0, uniStr.length), uniStr.unicode);
51 result = FSMakeFSRefUnicode(parentRef, uniStr.length, uniStr.unicode, kTextEncodingMacRoman, newRef);
52 if (result != noErr)
53 {
54 result = FSCreateDirectoryUnicode(parentRef, uniStr.length, uniStr.unicode, 0, NULL, newRef, NULL, NULL);
55 }
56
57 return result;
58}
59
60// --------------------------------------------------------------------------------
61
62static void CFStringRefToLLString(CFStringRef stringRef, std::string &llString, bool releaseWhenDone)
63{
64 if (stringRef)
65 {
66 long bufferSize = CFStringGetLength(stringRef) + 1;
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 CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
141 CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true);
142
143 // mOSUserDir
144 error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef);
145 if (error == noErr)
146 {
147 FSRef newFileRef;
148
149 // Create the directory
150 error = CFCreateDirectory(&fileRef, secondLifeString, &newFileRef);
151 if (error == noErr)
152 {
153 // Save the full path to the folder
154 FSRefToLLString(&newFileRef, mOSUserDir);
155
156 // Create our sub-dirs
157 (void) CFCreateDirectory(&newFileRef, CFSTR("data"), NULL);
158 (void) CFCreateDirectory(&newFileRef, CFSTR("cache"), NULL);
159 (void) CFCreateDirectory(&newFileRef, CFSTR("logs"), NULL);
160 (void) CFCreateDirectory(&newFileRef, CFSTR("user_settings"), NULL);
161 (void) CFCreateDirectory(&newFileRef, CFSTR("browser_profile"), NULL);
162 }
163 }
164
165 // mOSUserAppDir
166 mOSUserAppDir = mOSUserDir;
167
168 // mTempDir
169 error = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, true, &fileRef);
170 if (error == noErr)
171 {
172 FSRef tempRef;
173 error = CFCreateDirectory(&fileRef, secondLifeString, &tempRef);
174 if (error == noErr)
175 FSRefToLLString(&tempRef, mTempDir);
176 }
177
178 // Set the working dir to <bundle>/Contents/Resources
179 (void) chdir(mAppRODataDir.c_str());
180
181 // Canonically, since we set it here...
182 mWorkingDir = mAppRODataDir;
183
184 CFRelease(executableURLRef);
185 executableURLRef = NULL;
186 }
187}
188
189LLDir_Mac::~LLDir_Mac()
190{
191}
192
193// Implementation
194
195
196void LLDir_Mac::initAppDirs(const std::string &app_name)
197{
198 mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
199
200 //dumpCurrentDirectories();
201}
202
203U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &mask)
204{
205 U32 file_count = 0;
206 glob_t g;
207
208 std::string tmp_str;
209 tmp_str = dirname;
210 tmp_str += mask;
211
212 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
213 {
214 file_count = g.gl_pathc;
215
216 globfree(&g);
217 }
218
219 return (file_count);
220}
221
222// get the next file in the directory
223// automatically wrap if we've hit the end
224BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
225{
226 glob_t g;
227 BOOL result = FALSE;
228 fname = "";
229
230 if(!(dirname == mCurrentDir))
231 {
232 // different dir specified, close old search
233 mCurrentDirIndex = -1;
234 mCurrentDirCount = -1;
235 mCurrentDir = dirname;
236 }
237
238 std::string tmp_str;
239 tmp_str = dirname;
240 tmp_str += mask;
241
242 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
243 {
244 if(g.gl_pathc > 0)
245 {
246 if(g.gl_pathc != mCurrentDirCount)
247 {
248 // Number of matches has changed since the last search, meaning a file has been added or deleted.
249 // Reset the index.
250 mCurrentDirIndex = -1;
251 mCurrentDirCount = g.gl_pathc;
252 }
253
254 mCurrentDirIndex++;
255
256 if((mCurrentDirIndex >= g.gl_pathc) && wrap)
257 {
258 mCurrentDirIndex = 0;
259 }
260
261 if(mCurrentDirIndex < g.gl_pathc)
262 {
263// llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
264
265 // The API wants just the filename, not the full path.
266 //fname = g.gl_pathv[mCurrentDirIndex];
267
268 char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
269
270 if(s == NULL)
271 s = g.gl_pathv[mCurrentDirIndex];
272 else if(s[0] == '/')
273 s++;
274
275 fname = s;
276
277 result = TRUE;
278 }
279 }
280
281 globfree(&g);
282 }
283
284 return(result);
285}
286
287// get a random file in the directory
288void LLDir_Mac::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
289{
290 U32 which_file;
291 glob_t g;
292 fname = "";
293
294 std::string tmp_str;
295 tmp_str = dirname;
296 tmp_str += mask;
297
298 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
299 {
300 if(g.gl_pathc > 0)
301 {
302
303 which_file = gLindenLabRandomNumber.llrand() % g.gl_pathc;
304
305// llinfos << "getRandomFileInDir: returning number " << which_file << ", path is " << g.gl_pathv[which_file] << llendl;
306 // The API wants just the filename, not the full path.
307 //fname = g.gl_pathv[which_file];
308
309 char *s = strrchr(g.gl_pathv[which_file], '/');
310
311 if(s == NULL)
312 s = g.gl_pathv[which_file];
313 else if(s[0] == '/')
314 s++;
315
316 fname = s;
317 }
318
319 globfree(&g);
320 }
321}
322
323S32 LLDir_Mac::deleteFilesInDir(const std::string &dirname, const std::string &mask)
324{
325 glob_t g;
326 S32 result = 0;
327
328 std::string tmp_str;
329 tmp_str = dirname;
330 tmp_str += mask;
331
332 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
333 {
334 int i;
335
336 for(i = 0; i < g.gl_pathc; i++)
337 {
338// llinfos << "deleteFilesInDir: deleting number " << i << ", path is " << g.gl_pathv[i] << llendl;
339
340 if(unlink(g.gl_pathv[i]) != 0)
341 {
342 result = errno;
343
344 llwarns << "Problem removing " << g.gl_pathv[i] << " - errorcode: "
345 << result << llendl;
346 }
347 }
348
349 globfree(&g);
350 }
351
352 return(result);
353}
354
355std::string LLDir_Mac::getCurPath()
356{
357 char tmp_str[LL_MAX_PATH];
358 getcwd(tmp_str, LL_MAX_PATH);
359 return tmp_str;
360}
361
362
363
364BOOL LLDir_Mac::fileExists(const std::string &filename)
365{
366 struct stat stat_data;
367 // Check the age of the file
368 // Now, we see if the files we've gathered are recent...
369 int res = stat(filename.c_str(), &stat_data);
370 if (!res)
371 {
372 return TRUE;
373 }
374 else
375 {
376 return FALSE;
377 }
378}
379
380
381#endif // LL_DARWIN