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");
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];
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];
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
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
00141 mTempDir = "/tmp";
00142 }
00143
00144 LLDir_Solaris::~LLDir_Solaris()
00145 {
00146 }
00147
00148
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());
00159 if (app_home_env)
00160 {
00161
00162 mOSUserAppDir = app_home_env;
00163 }
00164 else
00165 {
00166
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
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
00247
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
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
00273
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
00288
00289
00290
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
00313
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
00332
00333
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];
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
00366
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