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_MOZILLA_PROFILE:
00328                 prefix = getOSUserAppDir();
00329                 prefix += mDirDelimiter;
00330                 prefix += "browser_profile";
00331                 break;
00332                 
00333         default:
00334                 llassert(0);
00335         }
00336 
00337         std::string filename = in_filename;
00338         if (!subdir.empty())
00339         {
00340                 filename = subdir + mDirDelimiter + in_filename;
00341         }
00342         else
00343         {
00344                 filename = in_filename;
00345         }
00346         
00347         std::string expanded_filename;
00348         if (!filename.empty())
00349         {
00350                 if (!prefix.empty())
00351                 {
00352                         expanded_filename += prefix;
00353                         expanded_filename += mDirDelimiter;
00354                         expanded_filename += filename;
00355                 }
00356                 else
00357                 {
00358                         expanded_filename = filename;
00359                 }
00360         }
00361         else if (!prefix.empty())
00362         {
00363                 // Directory only, no file name.
00364                 expanded_filename = prefix;
00365         }
00366         else
00367         {
00368                 expanded_filename.assign("");
00369         }
00370 
00371         //llinfos << "*** EXPANDED FILENAME: <" << mExpandedFilename << ">" << llendl;
00372 
00373         return expanded_filename;
00374 }
00375 
00376 std::string LLDir::getTempFilename() const
00377 {
00378         LLUUID random_uuid;
00379         char uuid_str[64];      /* Flawfinder: ignore */ 
00380 
00381         random_uuid.generate();
00382         random_uuid.toString(uuid_str);
00383 
00384         std::string temp_filename = getTempDir();
00385         temp_filename += mDirDelimiter;
00386         temp_filename += uuid_str;
00387         temp_filename += ".tmp";
00388 
00389         return temp_filename;
00390 }
00391 
00392 void LLDir::setLindenUserDir(const std::string &first, const std::string &last)
00393 {
00394         // if both first and last aren't set, assume we're grabbing the cached dir
00395         if (!first.empty() && !last.empty())
00396         {
00397                 // some platforms have case-sensitive filesystems, so be
00398                 // utterly consistent with our firstname/lastname case.
00399                 LLString firstlower(first);
00400                 LLString::toLower(firstlower);
00401                 LLString lastlower(last);
00402                 LLString::toLower(lastlower);
00403                 mLindenUserDir = getOSUserAppDir();
00404                 mLindenUserDir += mDirDelimiter;
00405                 mLindenUserDir += firstlower.c_str();
00406                 mLindenUserDir += "_";
00407                 mLindenUserDir += lastlower.c_str();
00408         }
00409         else
00410         {
00411                 llerrs << "Invalid name for LLDir::setLindenUserDir" << llendl;
00412         }
00413 
00414         dumpCurrentDirectories();       
00415 }
00416 
00417 void LLDir::setChatLogsDir(const std::string &path)
00418 {
00419         if (!path.empty() )
00420         {
00421                 mChatLogsDir = path;
00422         }
00423         else
00424         {
00425                 llwarns << "Invalid name for LLDir::setChatLogsDir" << llendl;
00426         }
00427 }
00428 
00429 void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last)
00430 {
00431         // if both first and last aren't set, assume we're grabbing the cached dir
00432         if (!first.empty() && !last.empty())
00433         {
00434                 // some platforms have case-sensitive filesystems, so be
00435                 // utterly consistent with our firstname/lastname case.
00436                 LLString firstlower(first);
00437                 LLString::toLower(firstlower);
00438                 LLString lastlower(last);
00439                 LLString::toLower(lastlower);
00440                 mPerAccountChatLogsDir = getChatLogsDir();
00441                 mPerAccountChatLogsDir += mDirDelimiter;
00442                 mPerAccountChatLogsDir += firstlower.c_str();
00443                 mPerAccountChatLogsDir += "_";
00444                 mPerAccountChatLogsDir += lastlower.c_str();
00445         }
00446         else
00447         {
00448                 llwarns << "Invalid name for LLDir::setPerAccountChatLogsDir" << llendl;
00449         }
00450 }
00451 
00452 void LLDir::setSkinFolder(const std::string &skin_folder)
00453 {
00454         mSkinDir = getAppRODataDir();
00455         mSkinDir += mDirDelimiter;
00456         mSkinDir += "skins";
00457         mSkinDir += mDirDelimiter;
00458         mSkinDir += skin_folder;
00459 }
00460 
00461 bool LLDir::setCacheDir(const std::string &path)
00462 {
00463         if (path.empty() )
00464         {
00465                 // reset to default
00466                 mCacheDir = "";
00467                 return true;
00468         }
00469         else
00470         {
00471                 LLFile::mkdir(path.c_str());
00472                 std::string tempname = path + mDirDelimiter + "temp";
00473                 LLFILE* file = LLFile::fopen(tempname.c_str(),"wt");
00474                 if (file)
00475                 {
00476                         fclose(file);
00477                         LLFile::remove(tempname.c_str());
00478                         mCacheDir = path;
00479                         return true;
00480                 }
00481                 return false;
00482         }
00483 }
00484 
00485 void LLDir::dumpCurrentDirectories()
00486 {
00487         llinfos << "Current Directories:" << llendl;
00488 
00489         llinfos << "  CurPath:               " << getCurPath() << llendl;
00490         llinfos << "  AppName:               " << getAppName() << llendl;
00491         llinfos << "  ExecutableFilename:    " << getExecutableFilename() << llendl;
00492         llinfos << "  ExecutableDir:         " << getExecutableDir() << llendl;
00493         llinfos << "  ExecutablePathAndName: " << getExecutablePathAndName() << llendl;
00494         llinfos << "  WorkingDir:            " << getWorkingDir() << llendl;
00495         llinfos << "  AppRODataDir:          " << getAppRODataDir() << llendl;
00496         llinfos << "  OSUserDir:             " << getOSUserDir() << llendl;
00497         llinfos << "  OSUserAppDir:          " << getOSUserAppDir() << llendl;
00498         llinfos << "  LindenUserDir:         " << getLindenUserDir() << llendl;
00499         llinfos << "  TempDir:               " << getTempDir() << llendl;
00500         llinfos << "  CAFile:                            " << getCAFile() << llendl;
00501         llinfos << "  SkinDir:               " << getSkinDir() << llendl;
00502 }
00503 
00504 
00505 void dir_exists_or_crash(const std::string &dir_name)
00506 {
00507 #if LL_WINDOWS
00508         // *FIX: lame - it doesn't do the same thing on windows. not so
00509         // important since we don't deploy simulator to windows boxes.
00510         LLFile::mkdir(dir_name.c_str(), 0700);
00511 #else
00512         struct stat dir_stat;
00513         if(0 != LLFile::stat(dir_name.c_str(), &dir_stat))
00514         {
00515                 S32 stat_rv = errno;
00516                 if(ENOENT == stat_rv)
00517                 {
00518                    if(0 != LLFile::mkdir(dir_name.c_str(), 0700))               // octal
00519                    {
00520                            llerrs << "Unable to create directory: " << dir_name << llendl;
00521                    }
00522                 }
00523                 else
00524                 {
00525                         llerrs << "Unable to stat: " << dir_name << " errno = " << stat_rv
00526                                    << llendl;
00527                 }
00528         }
00529         else
00530         {
00531                 // data_dir exists, make sure it's a directory.
00532                 if(!S_ISDIR(dir_stat.st_mode))
00533                 {
00534                         llerrs << "Data directory collision: " << dir_name << llendl;
00535                 }
00536         }
00537 #endif
00538 }

Generated on Thu Jul 1 06:08:24 2010 for Second Life Viewer by  doxygen 1.4.7