aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llvfs/lldir.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.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.cpp')
-rw-r--r--linden/indra/llvfs/lldir.cpp480
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"
43LLDir_Win32 gDirUtil;
44#elif LL_DARWIN
45#include "lldir_mac.h"
46LLDir_Mac gDirUtil;
47#else
48#include "lldir_linux.h"
49LLDir_Linux gDirUtil;
50#endif
51
52LLDir *gDirUtilp = (LLDir *)&gDirUtil;
53
54LLDir::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
69LLDir::~LLDir()
70{
71}
72
73
74S32 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
117const 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
145const std::string &LLDir::getExecutablePathAndName() const
146{
147 return mExecutablePathAndName;
148}
149
150const std::string &LLDir::getExecutableFilename() const
151{
152 return mExecutableFilename;
153}
154
155const std::string &LLDir::getExecutableDir() const
156{
157 return mExecutableDir;
158}
159
160const std::string &LLDir::getWorkingDir() const
161{
162 return mWorkingDir;
163}
164
165const std::string &LLDir::getAppName() const
166{
167 return mAppName;
168}
169
170const std::string &LLDir::getAppRODataDir() const
171{
172 return mAppRODataDir;
173}
174
175const std::string &LLDir::getOSUserDir() const
176{
177 return mOSUserDir;
178}
179
180const std::string &LLDir::getOSUserAppDir() const
181{
182 return mOSUserAppDir;
183}
184
185const std::string &LLDir::getLindenUserDir() const
186{
187 return mLindenUserDir;
188}
189
190const std::string &LLDir::getChatLogsDir() const
191{
192 return mChatLogsDir;
193}
194
195const std::string &LLDir::getPerAccountChatLogsDir() const
196{
197 return mPerAccountChatLogsDir;
198}
199
200const std::string &LLDir::getTempDir() const
201{
202 return mTempDir;
203}
204
205const std::string &LLDir::getCAFile() const
206{
207 return mCAFile;
208}
209
210const std::string &LLDir::getDirDelimiter() const
211{
212 return mDirDelimiter;
213}
214
215const std::string &LLDir::getSkinDir() const
216{
217 return mSkinDir;
218}
219
220std::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
342std::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
358void 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
383void 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
395void 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
418void 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
427void 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
447void 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}