lldir_solaris.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "lldir_solaris.h"
00035 #include "llerror.h"
00036 #include "llrand.h"
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #include <fcntl.h>
00040 #include <sys/param.h>
00041 #include <unistd.h>
00042 #include <glob.h>
00043 #include <pwd.h>
00044 #include <sys/utsname.h>
00045 #define _STRUCTURED_PROC 1
00046 #include <sys/procfs.h>
00047 
00048 static std::string getCurrentUserHome(char* fallback)
00049 {
00050         const uid_t uid = getuid();
00051         struct passwd *pw;
00052         char *result_cstr = fallback;
00053         
00054         pw = getpwuid(uid);
00055         if ((pw != NULL) && (pw->pw_dir != NULL))
00056         {
00057                 result_cstr = (char*) pw->pw_dir;
00058         }
00059         else
00060         {
00061                 llinfos << "Couldn't detect home directory from passwd - trying $HOME" << llendl;
00062                 const char *const home_env = getenv("HOME");    /* Flawfinder: ignore */ 
00063                 if (home_env)
00064                 {
00065                         result_cstr = (char*) home_env;
00066                 }
00067                 else
00068                 {
00069                         llwarns << "Couldn't detect home directory!  Falling back to " << fallback << llendl;
00070                 }
00071         }
00072         
00073         return std::string(result_cstr);
00074 }
00075 
00076 
00077 LLDir_Solaris::LLDir_Solaris()
00078 {
00079         mDirDelimiter = "/";
00080         mCurrentDirIndex = -1;
00081         mCurrentDirCount = -1;
00082         mDirp = NULL;
00083 
00084         char tmp_str[LL_MAX_PATH];      /* Flawfinder: ignore */ 
00085         getcwd(tmp_str, LL_MAX_PATH);
00086 
00087         mExecutableFilename = "";
00088         mExecutablePathAndName = "";
00089         mExecutableDir = strdup(tmp_str);
00090         mWorkingDir = strdup(tmp_str);
00091         mAppRODataDir = strdup(tmp_str);
00092         mOSUserDir = getCurrentUserHome(tmp_str);
00093         mOSUserAppDir = "";
00094         mLindenUserDir = tmp_str;
00095 
00096         char path [LL_MAX_PATH];        /* Flawfinder: ignore */ 
00097 
00098         sprintf(path, "/proc/%d/psinfo", (int)getpid());
00099         int proc_fd = -1;
00100         if((proc_fd = open(path, O_RDONLY)) == -1){
00101                 llwarns << "unable to open " << path << llendl;
00102                 return;
00103         }
00104         psinfo_t proc_psinfo;
00105         if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
00106                 llwarns << "Unable to read " << path << llendl;
00107                 close(proc_fd);
00108                 return;
00109         }
00110 
00111         close(proc_fd);
00112 
00113         mExecutableFilename = strdup(proc_psinfo.pr_fname);
00114         llinfos << "mExecutableFilename = [" << mExecutableFilename << "]" << llendl;
00115 
00116         sprintf(path, "/proc/%d/path/a.out", (int)getpid());
00117 
00118         char execpath[LL_MAX_PATH];
00119         if(readlink(path, execpath, LL_MAX_PATH) == -1){
00120                 llwarns << "Unable to read link from " << path << llendl;
00121                 return;
00122         }
00123 
00124         mExecutablePathAndName = strdup(execpath);
00125         llinfos << "mExecutablePathAndName = [" << mExecutablePathAndName << "]" << llendl;
00126 
00127                         // plunk a null at last '/' to get exec dir
00128         char *s = execpath + strlen(execpath) -1;
00129         while(*s != '/' && s != execpath){
00130                 --s;
00131         }
00132         
00133         if(s != execpath){
00134                 *s = (char)NULL;
00135         
00136                 mExecutableDir = strdup(execpath);
00137                 llinfos << "mExecutableDir = [" << mExecutableDir << "]" << llendl;
00138         }
00139         
00140         // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
00141         mTempDir = "/tmp";
00142 }
00143 
00144 LLDir_Solaris::~LLDir_Solaris()
00145 {
00146 }
00147 
00148 // Implementation
00149 
00150 
00151 void LLDir_Solaris::initAppDirs(const std::string &app_name)
00152 {
00153         mAppName = app_name;
00154 
00155         LLString upper_app_name(app_name);
00156         LLString::toUpper(upper_app_name);
00157 
00158         char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str());    /* Flawfinder: ignore */ 
00159         if (app_home_env)
00160         {
00161                 // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
00162                 mOSUserAppDir = app_home_env;
00163         }
00164         else
00165         {
00166                 // traditionally on unixoids, MyApp gets ~/.myapp dir for data
00167                 mOSUserAppDir = mOSUserDir;
00168                 mOSUserAppDir += "/";
00169                 mOSUserAppDir += ".";
00170                 LLString lower_app_name(app_name);
00171                 LLString::toLower(lower_app_name);
00172                 mOSUserAppDir += lower_app_name;
00173         }
00174 
00175         // create any directories we expect to write to.
00176 
00177         int res = LLFile::mkdir(mOSUserAppDir.c_str());
00178         if (res == -1)
00179         {
00180                 if (errno != EEXIST)
00181                 {
00182                         llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
00183                         llwarns << "Default to base dir" << mOSUserDir << llendl;
00184                         mOSUserAppDir = mOSUserDir;
00185                 }
00186         }
00187 
00188         res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,"").c_str());
00189         if (res == -1)
00190         {
00191                 if (errno != EEXIST)
00192                 {
00193                         llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
00194                 }
00195         }
00196         
00197         res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,"").c_str());
00198         if (res == -1)
00199         {
00200                 if (errno != EEXIST)
00201                 {
00202                         llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
00203                 }
00204         }
00205         
00206         res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,"").c_str());
00207         if (res == -1)
00208         {
00209                 if (errno != EEXIST)
00210                 {
00211                         llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
00212                 }
00213         }
00214         
00215         res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"").c_str());
00216         if (res == -1)
00217         {
00218                 if (errno != EEXIST)
00219                 {
00220                         llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
00221                 }
00222         }
00223 
00224         mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
00225 }
00226 
00227 U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string &mask)
00228 {
00229         U32 file_count = 0;
00230         glob_t g;
00231 
00232         std::string tmp_str;
00233         tmp_str = dirname;
00234         tmp_str += mask;
00235         
00236         if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
00237         {
00238                 file_count = g.gl_pathc;
00239 
00240                 globfree(&g);
00241         }
00242 
00243         return (file_count);
00244 }
00245 
00246 // get the next file in the directory
00247 // automatically wrap if we've hit the end
00248 BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
00249 {
00250         glob_t g;
00251         BOOL result = FALSE;
00252         fname = "";
00253         
00254         if(!(dirname == mCurrentDir))
00255         {
00256                 // different dir specified, close old search
00257                 mCurrentDirIndex = -1;
00258                 mCurrentDirCount = -1;
00259                 mCurrentDir = dirname;
00260         }
00261         
00262         std::string tmp_str;
00263         tmp_str = dirname;
00264         tmp_str += mask;
00265 
00266         if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
00267         {
00268                 if(g.gl_pathc > 0)
00269                 {
00270                         if((int)g.gl_pathc != mCurrentDirCount)
00271                         {
00272                                 // Number of matches has changed since the last search, meaning a file has been added or deleted.
00273                                 // Reset the index.
00274                                 mCurrentDirIndex = -1;
00275                                 mCurrentDirCount = g.gl_pathc;
00276                         }
00277         
00278                         mCurrentDirIndex++;
00279         
00280                         if((mCurrentDirIndex >= (int)g.gl_pathc) && wrap)
00281                         {
00282                                 mCurrentDirIndex = 0;
00283                         }
00284                         
00285                         if(mCurrentDirIndex < (int)g.gl_pathc)
00286                         {
00287 //                              llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
00288 
00289                                 // The API wants just the filename, not the full path.
00290                                 //fname = g.gl_pathv[mCurrentDirIndex];
00291 
00292                                 char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
00293                                 
00294                                 if(s == NULL)
00295                                         s = g.gl_pathv[mCurrentDirIndex];
00296                                 else if(s[0] == '/')
00297                                         s++;
00298                                         
00299                                 fname = s;
00300                                 
00301                                 result = TRUE;
00302                         }
00303                 }
00304                 
00305                 globfree(&g);
00306         }
00307         
00308         return(result);
00309 }
00310 
00311 
00312 // get a random file in the directory
00313 // automatically wrap if we've hit the end
00314 void LLDir_Solaris::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
00315 {
00316         S32 num_files;
00317         S32 which_file;
00318         DIR *dirp;
00319         dirent *entryp = NULL;
00320 
00321         fname = "";
00322 
00323         num_files = countFilesInDir(dirname,mask);
00324         if (!num_files)
00325         {
00326                 return;
00327         }
00328 
00329         which_file = ll_rand(num_files);
00330 
00331 //      llinfos << "Random select file #" << which_file << llendl;
00332 
00333     // which_file now indicates the (zero-based) index to which file to play
00334         
00335         if (!((dirp = opendir(dirname.c_str()))))
00336         {
00337                 while (which_file--)
00338                 {
00339                         if (!((entryp = readdir(dirp))))
00340                         {
00341                                 return;
00342                         }
00343                 }                  
00344 
00345                 if ((!which_file) && entryp)
00346                 {
00347                         fname = entryp->d_name;
00348                 }
00349                 
00350                 closedir(dirp);
00351         }
00352 }
00353 
00354 std::string LLDir_Solaris::getCurPath()
00355 {
00356         char tmp_str[LL_MAX_PATH];      /* Flawfinder: ignore */ 
00357         getcwd(tmp_str, LL_MAX_PATH);
00358         return tmp_str;
00359 }
00360 
00361 
00362 BOOL LLDir_Solaris::fileExists(const std::string &filename)
00363 {
00364         struct stat stat_data;
00365         // Check the age of the file
00366         // Now, we see if the files we've gathered are recent...
00367         int res = stat(filename.c_str(), &stat_data);
00368         if (!res)
00369         {
00370                 return TRUE;
00371         }
00372         else
00373         {
00374                 return FALSE;
00375         }
00376 }
00377 

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