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.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.cpp')
-rw-r--r-- | linden/indra/llvfs/lldir.cpp | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/linden/indra/llvfs/lldir.cpp b/linden/indra/llvfs/lldir.cpp new file mode 100644 index 0000000..b0d9d92 --- /dev/null +++ b/linden/indra/llvfs/lldir.cpp | |||
@@ -0,0 +1,480 @@ | |||
1 | /** | ||
2 | * @file lldir.cpp | ||
3 | * @brief implementation of directory utilities base class | ||
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 | #include "linden_common.h" | ||
29 | |||
30 | #if !LL_WINDOWS | ||
31 | #include <sys/stat.h> | ||
32 | #include <sys/types.h> | ||
33 | #else | ||
34 | #include <direct.h> | ||
35 | #endif | ||
36 | |||
37 | #include "lldir.h" | ||
38 | #include "llerror.h" | ||
39 | #include "lluuid.h" | ||
40 | |||
41 | #if LL_WINDOWS | ||
42 | #include "lldir_win32.h" | ||
43 | LLDir_Win32 gDirUtil; | ||
44 | #elif LL_DARWIN | ||
45 | #include "lldir_mac.h" | ||
46 | LLDir_Mac gDirUtil; | ||
47 | #else | ||
48 | #include "lldir_linux.h" | ||
49 | LLDir_Linux gDirUtil; | ||
50 | #endif | ||
51 | |||
52 | LLDir *gDirUtilp = (LLDir *)&gDirUtil; | ||
53 | |||
54 | LLDir::LLDir() | ||
55 | : mAppName(""), | ||
56 | mExecutablePathAndName(""), | ||
57 | mExecutableFilename(""), | ||
58 | mExecutableDir(""), | ||
59 | mAppRODataDir(""), | ||
60 | mOSUserDir(""), | ||
61 | mOSUserAppDir(""), | ||
62 | mLindenUserDir(""), | ||
63 | mCAFile(""), | ||
64 | mTempDir(""), | ||
65 | mDirDelimiter("") | ||
66 | { | ||
67 | } | ||
68 | |||
69 | LLDir::~LLDir() | ||
70 | { | ||
71 | } | ||
72 | |||
73 | |||
74 | S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) | ||
75 | { | ||
76 | S32 count = 0; | ||
77 | std::string filename; | ||
78 | std::string fullpath; | ||
79 | S32 result; | ||
80 | while (getNextFileInDir(dirname, mask, filename, FALSE)) | ||
81 | { | ||
82 | if ((filename == ".") || (filename == "..")) | ||
83 | { | ||
84 | // skipping directory traversal filenames | ||
85 | count++; | ||
86 | continue; | ||
87 | } | ||
88 | fullpath = dirname; | ||
89 | fullpath += getDirDelimiter(); | ||
90 | fullpath += filename; | ||
91 | |||
92 | S32 retry_count = 0; | ||
93 | while (retry_count < 5) | ||
94 | { | ||
95 | if (0 != LLFile::remove(fullpath.c_str())) | ||
96 | { | ||
97 | result = errno; | ||
98 | llwarns << "Problem removing " << fullpath << " - errorcode: " | ||
99 | << result << " attempt " << retry_count << llendl; | ||
100 | ms_sleep(1000); | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | if (retry_count) | ||
105 | { | ||
106 | llwarns << "Successfully removed " << fullpath << llendl; | ||
107 | } | ||
108 | break; | ||
109 | } | ||
110 | retry_count++; | ||
111 | } | ||
112 | count++; | ||
113 | } | ||
114 | return count; | ||
115 | } | ||
116 | |||
117 | const std::string LLDir::findFile(const std::string &filename, | ||
118 | const std::string searchPath1, | ||
119 | const std::string searchPath2, | ||
120 | const std::string searchPath3) | ||
121 | { | ||
122 | std::vector<std::string> search_paths; | ||
123 | search_paths.push_back(searchPath1); | ||
124 | search_paths.push_back(searchPath2); | ||
125 | search_paths.push_back(searchPath3); | ||
126 | |||
127 | std::vector<std::string>::iterator search_path_iter; | ||
128 | for (search_path_iter = search_paths.begin(); | ||
129 | search_path_iter != search_paths.end(); | ||
130 | ++search_path_iter) | ||
131 | { | ||
132 | if (!search_path_iter->empty()) | ||
133 | { | ||
134 | std::string filename_and_path = (*search_path_iter) + getDirDelimiter() + filename; | ||
135 | if (fileExists(filename_and_path)) | ||
136 | { | ||
137 | return filename_and_path; | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | return ""; | ||
142 | } | ||
143 | |||
144 | |||
145 | const std::string &LLDir::getExecutablePathAndName() const | ||
146 | { | ||
147 | return mExecutablePathAndName; | ||
148 | } | ||
149 | |||
150 | const std::string &LLDir::getExecutableFilename() const | ||
151 | { | ||
152 | return mExecutableFilename; | ||
153 | } | ||
154 | |||
155 | const std::string &LLDir::getExecutableDir() const | ||
156 | { | ||
157 | return mExecutableDir; | ||
158 | } | ||
159 | |||
160 | const std::string &LLDir::getWorkingDir() const | ||
161 | { | ||
162 | return mWorkingDir; | ||
163 | } | ||
164 | |||
165 | const std::string &LLDir::getAppName() const | ||
166 | { | ||
167 | return mAppName; | ||
168 | } | ||
169 | |||
170 | const std::string &LLDir::getAppRODataDir() const | ||
171 | { | ||
172 | return mAppRODataDir; | ||
173 | } | ||
174 | |||
175 | const std::string &LLDir::getOSUserDir() const | ||
176 | { | ||
177 | return mOSUserDir; | ||
178 | } | ||
179 | |||
180 | const std::string &LLDir::getOSUserAppDir() const | ||
181 | { | ||
182 | return mOSUserAppDir; | ||
183 | } | ||
184 | |||
185 | const std::string &LLDir::getLindenUserDir() const | ||
186 | { | ||
187 | return mLindenUserDir; | ||
188 | } | ||
189 | |||
190 | const std::string &LLDir::getChatLogsDir() const | ||
191 | { | ||
192 | return mChatLogsDir; | ||
193 | } | ||
194 | |||
195 | const std::string &LLDir::getPerAccountChatLogsDir() const | ||
196 | { | ||
197 | return mPerAccountChatLogsDir; | ||
198 | } | ||
199 | |||
200 | const std::string &LLDir::getTempDir() const | ||
201 | { | ||
202 | return mTempDir; | ||
203 | } | ||
204 | |||
205 | const std::string &LLDir::getCAFile() const | ||
206 | { | ||
207 | return mCAFile; | ||
208 | } | ||
209 | |||
210 | const std::string &LLDir::getDirDelimiter() const | ||
211 | { | ||
212 | return mDirDelimiter; | ||
213 | } | ||
214 | |||
215 | const std::string &LLDir::getSkinDir() const | ||
216 | { | ||
217 | return mSkinDir; | ||
218 | } | ||
219 | |||
220 | std::string LLDir::getExpandedFilename(ELLPath location, const std::string &filename) const | ||
221 | { | ||
222 | std::string prefix; | ||
223 | switch (location) | ||
224 | { | ||
225 | case LL_PATH_NONE: | ||
226 | // Do nothing | ||
227 | break; | ||
228 | |||
229 | case LL_PATH_APP_SETTINGS: | ||
230 | prefix = getAppRODataDir(); | ||
231 | prefix += mDirDelimiter; | ||
232 | prefix += "app_settings"; | ||
233 | break; | ||
234 | |||
235 | case LL_PATH_CHARACTER: | ||
236 | prefix = getAppRODataDir(); | ||
237 | prefix += mDirDelimiter; | ||
238 | prefix += "character"; | ||
239 | break; | ||
240 | |||
241 | case LL_PATH_MOTIONS: | ||
242 | prefix = getAppRODataDir(); | ||
243 | prefix += mDirDelimiter; | ||
244 | prefix += "motions"; | ||
245 | break; | ||
246 | |||
247 | case LL_PATH_HELP: | ||
248 | prefix = "help"; | ||
249 | break; | ||
250 | |||
251 | case LL_PATH_CACHE: | ||
252 | if (getOSUserAppDir().empty()) | ||
253 | { | ||
254 | prefix = "data"; | ||
255 | } | ||
256 | else | ||
257 | { | ||
258 | prefix = getOSUserAppDir(); | ||
259 | prefix += mDirDelimiter; | ||
260 | prefix += "cache"; | ||
261 | } | ||
262 | break; | ||
263 | |||
264 | case LL_PATH_USER_SETTINGS: | ||
265 | prefix = getOSUserAppDir(); | ||
266 | prefix += mDirDelimiter; | ||
267 | prefix += "user_settings"; | ||
268 | break; | ||
269 | |||
270 | case LL_PATH_PER_SL_ACCOUNT: | ||
271 | prefix = getLindenUserDir(); | ||
272 | break; | ||
273 | |||
274 | case LL_PATH_CHAT_LOGS: | ||
275 | prefix = getChatLogsDir(); | ||
276 | break; | ||
277 | |||
278 | case LL_PATH_PER_ACCOUNT_CHAT_LOGS: | ||
279 | prefix = getPerAccountChatLogsDir(); | ||
280 | break; | ||
281 | |||
282 | case LL_PATH_LOGS: | ||
283 | prefix = getOSUserAppDir(); | ||
284 | prefix += mDirDelimiter; | ||
285 | prefix += "logs"; | ||
286 | break; | ||
287 | |||
288 | case LL_PATH_TEMP: | ||
289 | prefix = getTempDir(); | ||
290 | break; | ||
291 | |||
292 | case LL_PATH_TOP_SKIN: | ||
293 | prefix = getSkinDir(); | ||
294 | break; | ||
295 | |||
296 | case LL_PATH_SKINS: | ||
297 | prefix = getAppRODataDir(); | ||
298 | prefix += mDirDelimiter; | ||
299 | prefix += "skins"; | ||
300 | break; | ||
301 | |||
302 | case LL_PATH_MOZILLA_PROFILE: | ||
303 | prefix = getOSUserAppDir(); | ||
304 | prefix += mDirDelimiter; | ||
305 | prefix += "browser_profile"; | ||
306 | break; | ||
307 | |||
308 | default: | ||
309 | llassert(0); | ||
310 | } | ||
311 | |||
312 | std::string expanded_filename; | ||
313 | if (!filename.empty()) | ||
314 | { | ||
315 | if (!prefix.empty()) | ||
316 | { | ||
317 | expanded_filename += prefix; | ||
318 | expanded_filename += mDirDelimiter; | ||
319 | expanded_filename += filename; | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | expanded_filename = filename; | ||
324 | } | ||
325 | } | ||
326 | else | ||
327 | if (!prefix.empty()) | ||
328 | { | ||
329 | // Directory only, no file name. | ||
330 | expanded_filename = prefix; | ||
331 | } | ||
332 | else | ||
333 | { | ||
334 | expanded_filename.assign(""); | ||
335 | } | ||
336 | |||
337 | //llinfos << "*** EXPANDED FILENAME: <" << mExpandedFilename << ">" << llendl; | ||
338 | |||
339 | return expanded_filename; | ||
340 | } | ||
341 | |||
342 | std::string LLDir::getTempFilename() const | ||
343 | { | ||
344 | LLUUID random_uuid; | ||
345 | char uuid_str[64]; | ||
346 | |||
347 | random_uuid.generate(); | ||
348 | random_uuid.toString(uuid_str); | ||
349 | |||
350 | std::string temp_filename = getTempDir(); | ||
351 | temp_filename += mDirDelimiter; | ||
352 | temp_filename += uuid_str; | ||
353 | temp_filename += ".tmp"; | ||
354 | |||
355 | return temp_filename; | ||
356 | } | ||
357 | |||
358 | void LLDir::setLindenUserDir(const std::string &first, const std::string &last) | ||
359 | { | ||
360 | // if both first and last aren't set, assume we're grabbing the cached dir | ||
361 | if (!first.empty() && !last.empty()) | ||
362 | { | ||
363 | // some platforms have case-sensitive filesystems, so be | ||
364 | // utterly consistent with our firstname/lastname case. | ||
365 | LLString firstlower(first); | ||
366 | LLString::toLower(firstlower); | ||
367 | LLString lastlower(last); | ||
368 | LLString::toLower(lastlower); | ||
369 | mLindenUserDir = getOSUserAppDir(); | ||
370 | mLindenUserDir += mDirDelimiter; | ||
371 | mLindenUserDir += firstlower.c_str(); | ||
372 | mLindenUserDir += "_"; | ||
373 | mLindenUserDir += lastlower.c_str(); | ||
374 | } | ||
375 | else | ||
376 | { | ||
377 | llerrs << "Invalid name for LLDir::setLindenUserDir" << llendl; | ||
378 | } | ||
379 | |||
380 | dumpCurrentDirectories(); | ||
381 | } | ||
382 | |||
383 | void LLDir::setChatLogsDir(const std::string &path) | ||
384 | { | ||
385 | if (!path.empty() ) | ||
386 | { | ||
387 | mChatLogsDir = path; | ||
388 | } | ||
389 | else | ||
390 | { | ||
391 | llwarns << "Invalid name for LLDir::setChatLogsDir" << llendl; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last) | ||
396 | { | ||
397 | // if both first and last aren't set, assume we're grabbing the cached dir | ||
398 | if (!first.empty() && !last.empty()) | ||
399 | { | ||
400 | // some platforms have case-sensitive filesystems, so be | ||
401 | // utterly consistent with our firstname/lastname case. | ||
402 | LLString firstlower(first); | ||
403 | LLString::toLower(firstlower); | ||
404 | LLString lastlower(last); | ||
405 | LLString::toLower(lastlower); | ||
406 | mPerAccountChatLogsDir = getChatLogsDir(); | ||
407 | mPerAccountChatLogsDir += mDirDelimiter; | ||
408 | mPerAccountChatLogsDir += firstlower.c_str(); | ||
409 | mPerAccountChatLogsDir += "_"; | ||
410 | mPerAccountChatLogsDir += lastlower.c_str(); | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | llwarns << "Invalid name for LLDir::setPerAccountChatLogsDir" << llendl; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | void LLDir::setSkinFolder(const std::string &skin_folder) | ||
419 | { | ||
420 | mSkinDir = getAppRODataDir(); | ||
421 | mSkinDir += mDirDelimiter; | ||
422 | mSkinDir += "skins"; | ||
423 | mSkinDir += mDirDelimiter; | ||
424 | mSkinDir += skin_folder; | ||
425 | } | ||
426 | |||
427 | void LLDir::dumpCurrentDirectories() | ||
428 | { | ||
429 | llinfos << "Current Directories:" << llendl; | ||
430 | |||
431 | llinfos << " CurPath: " << getCurPath() << llendl; | ||
432 | llinfos << " AppName: " << getAppName() << llendl; | ||
433 | llinfos << " ExecutableFilename: " << getExecutableFilename() << llendl; | ||
434 | llinfos << " ExecutableDir: " << getExecutableDir() << llendl; | ||
435 | llinfos << " ExecutablePathAndName: " << getExecutablePathAndName() << llendl; | ||
436 | llinfos << " WorkingDir: " << getWorkingDir() << llendl; | ||
437 | llinfos << " AppRODataDir: " << getAppRODataDir() << llendl; | ||
438 | llinfos << " OSUserDir: " << getOSUserDir() << llendl; | ||
439 | llinfos << " OSUserAppDir: " << getOSUserAppDir() << llendl; | ||
440 | llinfos << " LindenUserDir: " << getLindenUserDir() << llendl; | ||
441 | llinfos << " TempDir: " << getTempDir() << llendl; | ||
442 | llinfos << " CAFile: " << getCAFile() << llendl; | ||
443 | llinfos << " SkinDir: " << getSkinDir() << llendl; | ||
444 | } | ||
445 | |||
446 | |||
447 | void dir_exists_or_crash(const std::string &dir_name) | ||
448 | { | ||
449 | #if LL_WINDOWS | ||
450 | // *FIX: lame - it doesn't do the same thing on windows. not so | ||
451 | // important since we don't deploy simulator to windows boxes. | ||
452 | LLFile::mkdir(dir_name.c_str(), 0700); | ||
453 | #else | ||
454 | struct stat dir_stat; | ||
455 | if(0 != LLFile::stat(dir_name.c_str(), &dir_stat)) | ||
456 | { | ||
457 | S32 stat_rv = errno; | ||
458 | if(ENOENT == stat_rv) | ||
459 | { | ||
460 | if(0 != LLFile::mkdir(dir_name.c_str(), 0700)) // octal | ||
461 | { | ||
462 | llerrs << "Unable to create directory: " << dir_name << llendl; | ||
463 | } | ||
464 | } | ||
465 | else | ||
466 | { | ||
467 | llerrs << "Unable to stat: " << dir_name << " errno = " << stat_rv | ||
468 | << llendl; | ||
469 | } | ||
470 | } | ||
471 | else | ||
472 | { | ||
473 | // data_dir exists, make sure it's a directory. | ||
474 | if(!S_ISDIR(dir_stat.st_mode)) | ||
475 | { | ||
476 | llerrs << "Data directory collision: " << dir_name << llendl; | ||
477 | } | ||
478 | } | ||
479 | #endif | ||
480 | } | ||