lldir.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #if !LL_WINDOWS
00035 #include <sys/stat.h>
00036 #include <sys/types.h>
00037 #include <errno.h>
00038 #else
00039 #include <direct.h>
00040 #endif
00041 
00042 #include "lldir.h"
00043 #include "llerror.h"
00044 #include "lluuid.h"
00045 
00046 #if LL_WINDOWS
00047 #include "lldir_win32.h"
00048 LLDir_Win32 gDirUtil;
00049 #elif LL_DARWIN
00050 #include "lldir_mac.h"
00051 LLDir_Mac gDirUtil;
00052 #elif LL_SOLARIS
00053 #include "lldir_solaris.h"
00054 LLDir_Solaris gDirUtil;
00055 #else
00056 #include "lldir_linux.h"
00057 LLDir_Linux gDirUtil;
00058 #endif
00059 
00060 LLDir *gDirUtilp = (LLDir *)&gDirUtil;
00061 
00062 LLDir::LLDir()
00063 :       mAppName(""),
00064         mExecutablePathAndName(""),
00065         mExecutableFilename(""),
00066         mExecutableDir(""),
00067         mAppRODataDir(""),
00068         mOSUserDir(""),
00069         mOSUserAppDir(""),
00070         mLindenUserDir(""),
00071         mCAFile(""),
00072         mTempDir(""),
00073         mDirDelimiter("")
00074 {
00075 }
00076 
00077 LLDir::~LLDir()
00078 {
00079 }
00080 
00081 
00082 S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
00083 {
00084         S32 count = 0;
00085         std::string filename; 
00086         std::string fullpath;
00087         S32 result;
00088         while (getNextFileInDir(dirname, mask, filename, FALSE))
00089         {
00090                 if ((filename == ".") || (filename == ".."))
00091                 {
00092                         // skipping directory traversal filenames
00093                         count++;
00094                         continue;
00095                 }
00096                 fullpath = dirname;
00097                 fullpath += getDirDelimiter();
00098                 fullpath += filename;
00099 
00100                 S32 retry_count = 0;
00101                 while (retry_count < 5)
00102                 {
00103                         if (0 != LLFile::remove(fullpath.c_str()))
00104                         {
00105                                 result = errno;
00106                                 llwarns << "Problem removing " << fullpath << " - errorcode: "
00107                                                 << result << " attempt " << retry_count << llendl;
00108                                 ms_sleep(1000);
00109                         }
00110                         else
00111                         {
00112                                 if (retry_count)
00113                                 {
00114                                         llwarns << "Successfully removed " << fullpath << llendl;
00115                                 }
00116                                 break;
00117                         }
00118                         retry_count++;
00119                 }
00120                 count++;
00121         }
00122         return count;
00123 }
00124 
00125 const std::string LLDir::findFile(const std::string &filename, 
00126                                                    const std::string searchPath1, 
00127                                                    const std::string searchPath2, 
00128                                                    const std::string searchPath3)
00129 {
00130         std::vector<std::string> search_paths;
00131         search_paths.push_back(searchPath1);
00132         search_paths.push_back(searchPath2);
00133         search_paths.push_back(searchPath3);
00134 
00135         std::vector<std::string>::iterator search_path_iter;
00136         for (search_path_iter = search_paths.begin();
00137                 search_path_iter != search_paths.end();
00138                 ++search_path_iter)
00139         {
00140                 if (!search_path_iter->empty())
00141                 {
00142                         std::string filename_and_path = (*search_path_iter) + getDirDelimiter() + filename;
00143                         if (fileExists(filename_and_path))
00144                         {
00145                                 return filename_and_path;
00146                         }
00147                 }
00148         }
00149         return "";
00150 }
00151 
00152 
00153 const std::string &LLDir::getExecutablePathAndName() const
00154 {
00155         return mExecutablePathAndName;
00156 }
00157 
00158 const std::string &LLDir::getExecutableFilename() const
00159 {
00160         return mExecutableFilename;
00161 }
00162 
00163 const std::string &LLDir::getExecutableDir() const
00164 {
00165         return mExecutableDir;
00166 }
00167 
00168 const std::string &LLDir::getWorkingDir() const
00169 {
00170         return mWorkingDir;
00171 }
00172 
00173 const std::string &LLDir::getAppName() const
00174 {
00175         return mAppName;
00176 }
00177 
00178 const std::string &LLDir::getAppRODataDir() const
00179 {
00180         return mAppRODataDir;
00181 }
00182 
00183 const std::string &LLDir::getOSUserDir() const
00184 {
00185         return mOSUserDir;
00186 }
00187 
00188 const std::string &LLDir::getOSUserAppDir() const
00189 {
00190         return mOSUserAppDir;
00191 }
00192 
00193 const std::string &LLDir::getLindenUserDir() const
00194 {
00195         return mLindenUserDir;
00196 }
00197 
00198 const std::string &LLDir::getChatLogsDir() const
00199 {
00200         return mChatLogsDir;
00201 }
00202 
00203 const std::string &LLDir::getPerAccountChatLogsDir() const
00204 {
00205         return mPerAccountChatLogsDir;
00206 }
00207 
00208 const std::string &LLDir::getTempDir() const
00209 {
00210         return mTempDir;
00211 }
00212 
00213 const std::string  LLDir::getCacheDir(bool get_default) const
00214 {
00215         if (mCacheDir.empty() || get_default)
00216         {
00217                 std::string res;
00218                 if (getOSUserAppDir().empty())
00219                 {
00220                         res = "data";
00221                 }
00222                 else
00223                 {
00224                         res = getOSUserAppDir() + mDirDelimiter + "cache";
00225                 }
00226                 return res;
00227         }
00228         else
00229         {
00230                 return mCacheDir;
00231         }
00232 }
00233 
00234 const std::string &LLDir::getCAFile() const
00235 {
00236         return mCAFile;
00237 }
00238 
00239 const std::string &LLDir::getDirDelimiter() const
00240 {
00241         return mDirDelimiter;
00242 }
00243 
00244 const std::string &LLDir::getSkinDir() const
00245 {
00246         return mSkinDir;
00247 }
00248 
00249 std::string LLDir::getExpandedFilename(ELLPath location, const std::string& filename) const
00250 {
00251         return getExpandedFilename(location, "", filename);
00252 }
00253 
00254 std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subdir, const std::string& in_filename) const
00255 {
00256         std::string prefix;
00257         switch (location)
00258         {
00259         case LL_PATH_NONE:
00260                 // Do nothing
00261                 break;
00262 
00263         case LL_PATH_APP_SETTINGS:
00264                 prefix = getAppRODataDir();
00265                 prefix += mDirDelimiter;
00266                 prefix += "app_settings";
00267                 break;
00268                 
00269         case LL_PATH_CHARACTER:
00270                 prefix = getAppRODataDir();
00271                 prefix += mDirDelimiter;
00272                 prefix += "character";
00273                 break;
00274                 
00275         case LL_PATH_MOTIONS:
00276                 prefix = getAppRODataDir();
00277                 prefix += mDirDelimiter;
00278                 prefix += "motions";
00279                 break;
00280                 
00281         case LL_PATH_HELP:
00282                 prefix = "help";
00283                 break;
00284                 
00285         case LL_PATH_CACHE:
00286             prefix = getCacheDir();
00287                 break;
00288                 
00289         case LL_PATH_USER_SETTINGS:
00290                 prefix = getOSUserAppDir();
00291                 prefix += mDirDelimiter;
00292                 prefix += "user_settings";
00293                 break;
00294 
00295         case LL_PATH_PER_SL_ACCOUNT:
00296                 prefix = getLindenUserDir();
00297                 break;
00298                 
00299         case LL_PATH_CHAT_LOGS:
00300                 prefix = getChatLogsDir();
00301                 break;
00302                 
00303         case LL_PATH_PER_ACCOUNT_CHAT_LOGS:
00304                 prefix = getPerAccountChatLogsDir();
00305                 break;
00306 
00307         case LL_PATH_LOGS:
00308                 prefix = getOSUserAppDir();
00309                 prefix += mDirDelimiter;
00310                 prefix += "logs";
00311                 break;
00312 
00313         case LL_PATH_TEMP:
00314                 prefix = getTempDir();
00315                 break;
00316 
00317         case LL_PATH_TOP_SKIN:
00318                 prefix = getSkinDir();
00319                 break;
00320 
00321         case LL_PATH_SKINS:
00322                 prefix = getAppRODataDir();
00323                 prefix += mDirDelimiter;
00324                 prefix += "skins";
00325                 break;
00326 
00327         case LL_PATH_HTML:
00328                 prefix = getAppRODataDir();
00329                 prefix += mDirDelimiter;
00330                 prefix += "skins";
00331                 prefix += mDirDelimiter;
00332                 prefix += "html";
00333                 break;
00334 
00335         case LL_PATH_MOZILLA_PROFILE:
00336                 prefix = getOSUserAppDir();
00337                 prefix += mDirDelimiter;
00338                 prefix += "browser_profile";
00339                 break;
00340                 
00341         default:
00342                 llassert(0);
00343         }
00344 
00345         std::string filename = in_filename;
00346         if (!subdir.empty())
00347         {
00348                 filename = subdir + mDirDelimiter + in_filename;
00349         }
00350         else
00351         {
00352                 filename = in_filename;
00353         }
00354         
00355         std::string expanded_filename;
00356         if (!filename.empty())
00357         {
00358                 if (!prefix.empty())
00359                 {
00360                         expanded_filename += prefix;
00361                         expanded_filename += mDirDelimiter;
00362                         expanded_filename += filename;
00363                 }
00364                 else
00365                 {
00366                         expanded_filename = filename;
00367                 }
00368         }
00369         else if (!prefix.empty())
00370         {
00371                 // Directory only, no file name.
00372                 expanded_filename = prefix;
00373         }
00374         else
00375         {
00376                 expanded_filename.assign("");
00377         }
00378 
00379         //llinfos << "*** EXPANDED FILENAME: <" << mExpandedFilename << ">" << llendl;
00380 
00381         return expanded_filename;
00382 }
00383 
00384 std::string LLDir::getTempFilename() const
00385 {
00386         LLUUID random_uuid;
00387         char uuid_str[64];      /* Flawfinder: ignore */ 
00388 
00389         random_uuid.generate();
00390         random_uuid.toString(uuid_str);
00391 
00392         std::string temp_filename = getTempDir();
00393         temp_filename += mDirDelimiter;
00394         temp_filename += uuid_str;
00395         temp_filename += ".tmp";
00396 
00397         return temp_filename;
00398 }
00399 
00400 void LLDir::setLindenUserDir(const std::string &first, const std::string &last)
00401 {
00402         // if both first and last aren't set, assume we're grabbing the cached dir
00403         if (!first.empty() && !last.empty())
00404         {
00405                 // some platforms have case-sensitive filesystems, so be
00406                 // utterly consistent with our firstname/lastname case.
00407                 LLString firstlower(first);
00408                 LLString::toLower(firstlower);
00409                 LLString lastlower(last);
00410                 LLString::toLower(lastlower);
00411                 mLindenUserDir = getOSUserAppDir();
00412                 mLindenUserDir += mDirDelimiter;
00413                 mLindenUserDir += firstlower.c_str();
00414                 mLindenUserDir += "_";
00415                 mLindenUserDir += lastlower.c_str();
00416         }
00417         else
00418         {
00419                 llerrs << "Invalid name for LLDir::setLindenUserDir" << llendl;
00420         }
00421 
00422         dumpCurrentDirectories();       
00423 }
00424 
00425 void LLDir::setChatLogsDir(const std::string &path)
00426 {
00427         if (!path.empty() )
00428         {
00429                 mChatLogsDir = path;
00430         }
00431         else
00432         {
00433                 llwarns << "Invalid name for LLDir::setChatLogsDir" << llendl;
00434         }
00435 }
00436 
00437 void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last)
00438 {
00439         // if both first and last aren't set, assume we're grabbing the cached dir
00440         if (!first.empty() && !last.empty())
00441         {
00442                 // some platforms have case-sensitive filesystems, so be
00443                 // utterly consistent with our firstname/lastname case.
00444                 LLString firstlower(first);
00445                 LLString::toLower(firstlower);
00446                 LLString lastlower(last);
00447                 LLString::toLower(lastlower);
00448                 mPerAccountChatLogsDir = getChatLogsDir();
00449                 mPerAccountChatLogsDir += mDirDelimiter;
00450                 mPerAccountChatLogsDir += firstlower.c_str();
00451                 mPerAccountChatLogsDir += "_";
00452                 mPerAccountChatLogsDir += lastlower.c_str();
00453         }
00454         else
00455         {
00456                 llwarns << "Invalid name for LLDir::setPerAccountChatLogsDir" << llendl;
00457         }
00458 }
00459 
00460 void LLDir::setSkinFolder(const std::string &skin_folder)
00461 {
00462         mSkinDir = getAppRODataDir();
00463         mSkinDir += mDirDelimiter;
00464         mSkinDir += "skins";
00465         mSkinDir += mDirDelimiter;
00466         mSkinDir += skin_folder;
00467 }
00468 
00469 bool LLDir::setCacheDir(const std::string &path)
00470 {
00471         if (path.empty() )
00472         {
00473                 // reset to default
00474                 mCacheDir = "";
00475                 return true;
00476         }
00477         else
00478         {
00479                 LLFile::mkdir(path.c_str());
00480                 std::string tempname = path + mDirDelimiter + "temp";
00481                 LLFILE* file = LLFile::fopen(tempname.c_str(),"wt");
00482                 if (file)
00483                 {
00484                         fclose(file);
00485                         LLFile::remove(tempname.c_str());
00486                         mCacheDir = path;
00487                         return true;
00488                 }
00489                 return false;
00490         }
00491 }
00492 
00493 void LLDir::dumpCurrentDirectories()
00494 {
00495         LL_DEBUGS2("AppInit","Directories") << "Current Directories:" << LL_ENDL;
00496 
00497         LL_DEBUGS2("AppInit","Directories") << "  CurPath:               " << getCurPath() << LL_ENDL;
00498         LL_DEBUGS2("AppInit","Directories") << "  AppName:               " << getAppName() << LL_ENDL;
00499         LL_DEBUGS2("AppInit","Directories") << "  ExecutableFilename:    " << getExecutableFilename() << LL_ENDL;
00500         LL_DEBUGS2("AppInit","Directories") << "  ExecutableDir:         " << getExecutableDir() << LL_ENDL;
00501         LL_DEBUGS2("AppInit","Directories") << "  ExecutablePathAndName: " << getExecutablePathAndName() << LL_ENDL;
00502         LL_DEBUGS2("AppInit","Directories") << "  WorkingDir:            " << getWorkingDir() << LL_ENDL;
00503         LL_DEBUGS2("AppInit","Directories") << "  AppRODataDir:          " << getAppRODataDir() << LL_ENDL;
00504         LL_DEBUGS2("AppInit","Directories") << "  OSUserDir:             " << getOSUserDir() << LL_ENDL;
00505         LL_DEBUGS2("AppInit","Directories") << "  OSUserAppDir:          " << getOSUserAppDir() << LL_ENDL;
00506         LL_DEBUGS2("AppInit","Directories") << "  LindenUserDir:         " << getLindenUserDir() << LL_ENDL;
00507         LL_DEBUGS2("AppInit","Directories") << "  TempDir:               " << getTempDir() << LL_ENDL;
00508         LL_DEBUGS2("AppInit","Directories") << "  CAFile:                                " << getCAFile() << LL_ENDL;
00509         LL_DEBUGS2("AppInit","Directories") << "  SkinDir:               " << getSkinDir() << LL_ENDL;
00510 }
00511 
00512 
00513 void dir_exists_or_crash(const std::string &dir_name)
00514 {
00515 #if LL_WINDOWS
00516         // *FIX: lame - it doesn't do the same thing on windows. not so
00517         // important since we don't deploy simulator to windows boxes.
00518         LLFile::mkdir(dir_name.c_str(), 0700);
00519 #else
00520         struct stat dir_stat;
00521         if(0 != LLFile::stat(dir_name.c_str(), &dir_stat))
00522         {
00523                 S32 stat_rv = errno;
00524                 if(ENOENT == stat_rv)
00525                 {
00526                    if(0 != LLFile::mkdir(dir_name.c_str(), 0700))               // octal
00527                    {
00528                            llerrs << "Unable to create directory: " << dir_name << llendl;
00529                    }
00530                 }
00531                 else
00532                 {
00533                         llerrs << "Unable to stat: " << dir_name << " errno = " << stat_rv
00534                                    << llendl;
00535                 }
00536         }
00537         else
00538         {
00539                 // data_dir exists, make sure it's a directory.
00540                 if(!S_ISDIR(dir_stat.st_mode))
00541                 {
00542                         llerrs << "Data directory collision: " << dir_name << llendl;
00543                 }
00544         }
00545 #endif
00546 }

Generated on Fri May 16 08:33:01 2008 for SecondLife by  doxygen 1.5.5