diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llvfs/lldir_mac.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 381 |
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 | |||
44 | static 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 | |||
62 | static 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 | |||
79 | static 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 | |||
97 | static 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 | |||
109 | LLDir_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 | |||
189 | LLDir_Mac::~LLDir_Mac() | ||
190 | { | ||
191 | } | ||
192 | |||
193 | // Implementation | ||
194 | |||
195 | |||
196 | void LLDir_Mac::initAppDirs(const std::string &app_name) | ||
197 | { | ||
198 | mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem"); | ||
199 | |||
200 | //dumpCurrentDirectories(); | ||
201 | } | ||
202 | |||
203 | U32 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 | ||
224 | BOOL 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 | ||
288 | void 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 | |||
323 | S32 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 | |||
355 | std::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 | |||
364 | BOOL 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 | ||