lldir_solaris.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file fmodwrapper.cpp
  3.  * @brief dummy source file for building a shared library to wrap libfmod.a
  4.  *
  5.  * $LicenseInfo:firstyear=2005&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2005-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "lldir_solaris.h"
  34. #include "llerror.h"
  35. #include "llrand.h"
  36. #include <sys/types.h>
  37. #include <sys/stat.h>
  38. #include <unistd.h>
  39. #include <glob.h>
  40. #include <pwd.h>
  41. #include <sys/utsname.h>
  42. #define _STRUCTURED_PROC 1
  43. #include <sys/procfs.h>
  44. #include <fcntl.h>
  45. static std::string getCurrentUserHome(char* fallback)
  46. {
  47. const uid_t uid = getuid();
  48. struct passwd *pw;
  49. char *result_cstr = fallback;
  50. pw = getpwuid(uid);
  51. if ((pw != NULL) && (pw->pw_dir != NULL))
  52. {
  53. result_cstr = (char*) pw->pw_dir;
  54. }
  55. else
  56. {
  57. llinfos << "Couldn't detect home directory from passwd - trying $HOME" << llendl;
  58. const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */ 
  59. if (home_env)
  60. {
  61. result_cstr = (char*) home_env;
  62. }
  63. else
  64. {
  65. llwarns << "Couldn't detect home directory!  Falling back to " << fallback << llendl;
  66. }
  67. }
  68. return std::string(result_cstr);
  69. }
  70. LLDir_Solaris::LLDir_Solaris()
  71. {
  72. mDirDelimiter = "/";
  73. mCurrentDirIndex = -1;
  74. mCurrentDirCount = -1;
  75. mDirp = NULL;
  76. char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ 
  77. if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
  78. {
  79. strcpy(tmp_str, "/tmp");
  80. llwarns << "Could not get current directory; changing to "
  81. << tmp_str << llendl;
  82. if (chdir(tmp_str) == -1)
  83. {
  84. llerrs << "Could not change directory to " << tmp_str << llendl;
  85. }
  86. }
  87. mExecutableFilename = "";
  88. mExecutablePathAndName = "";
  89. mExecutableDir = strdup(tmp_str);
  90. mWorkingDir = strdup(tmp_str);
  91. mAppRODataDir = strdup(tmp_str);
  92. mOSUserDir = getCurrentUserHome(tmp_str);
  93. mOSUserAppDir = "";
  94. mLindenUserDir = "";
  95. char path [LL_MAX_PATH]; /* Flawfinder: ignore */ 
  96. sprintf(path, "/proc/%d/psinfo", (int)getpid());
  97. int proc_fd = -1;
  98. if((proc_fd = open(path, O_RDONLY)) == -1){
  99. llwarns << "unable to open " << path << llendl;
  100. return;
  101. }
  102. psinfo_t proc_psinfo;
  103. if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
  104. llwarns << "Unable to read " << path << llendl;
  105. close(proc_fd);
  106. return;
  107. }
  108. close(proc_fd);
  109. mExecutableFilename = strdup(proc_psinfo.pr_fname);
  110. llinfos << "mExecutableFilename = [" << mExecutableFilename << "]" << llendl;
  111. sprintf(path, "/proc/%d/path/a.out", (int)getpid());
  112. char execpath[LL_MAX_PATH];
  113. if(readlink(path, execpath, LL_MAX_PATH) == -1){
  114. llwarns << "Unable to read link from " << path << llendl;
  115. return;
  116. }
  117. char *p = execpath; // nuke trash in link, if any exists
  118. int i = 0;
  119. while(*p != NULL && ++i < LL_MAX_PATH && isprint((int)(*p++)));
  120. *p = NULL;
  121. mExecutablePathAndName = strdup(execpath);
  122. llinfos << "mExecutablePathAndName = [" << mExecutablePathAndName << "]" << llendl;
  123. //NOTE: Why force people to cd into the package directory?
  124. //      Look for SECONDLIFE env variable and use it, if set.
  125. char *dcf = getenv("SECONDLIFE");
  126. if(dcf != NULL){
  127. (void)strcpy(path, dcf);
  128. (void)strcat(path, "/bin"); //NOTE:  make sure we point at the bin
  129. mExecutableDir = strdup(path);
  130. }else{
  131. // plunk a null at last '/' to get exec dir
  132. char *s = execpath + strlen(execpath) -1;
  133. while(*s != '/' && s != execpath){
  134. --s;
  135. }
  136. if(s != execpath){
  137. *s = (char)NULL;
  138. mExecutableDir = strdup(execpath);
  139. llinfos << "mExecutableDir = [" << mExecutableDir << "]" << llendl;
  140. }
  141. }
  142. mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
  143. // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
  144. mTempDir = "/tmp";
  145. }
  146. LLDir_Solaris::~LLDir_Solaris()
  147. {
  148. }
  149. // Implementation
  150. void LLDir_Solaris::initAppDirs(const std::string &app_name,
  151. const std::string& app_read_only_data_dir)
  152. {
  153. // Allow override so test apps can read newview directory
  154. if (!app_read_only_data_dir.empty())
  155. {
  156. mAppRODataDir = app_read_only_data_dir;
  157. }
  158. mAppName = app_name;
  159. std::string upper_app_name(app_name);
  160. LLStringUtil::toUpper(upper_app_name);
  161. char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */ 
  162. if (app_home_env)
  163. {
  164. // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
  165. mOSUserAppDir = app_home_env;
  166. }
  167. else
  168. {
  169. // traditionally on unixoids, MyApp gets ~/.myapp dir for data
  170. mOSUserAppDir = mOSUserDir;
  171. mOSUserAppDir += "/";
  172. mOSUserAppDir += ".";
  173. std::string lower_app_name(app_name);
  174. LLStringUtil::toLower(lower_app_name);
  175. mOSUserAppDir += lower_app_name;
  176. }
  177. // create any directories we expect to write to.
  178. int res = LLFile::mkdir(mOSUserAppDir);
  179. if (res == -1)
  180. {
  181. if (errno != EEXIST)
  182. {
  183. llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
  184. llwarns << "Default to base dir" << mOSUserDir << llendl;
  185. mOSUserAppDir = mOSUserDir;
  186. }
  187. }
  188. res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,""));
  189. if (res == -1)
  190. {
  191. if (errno != EEXIST)
  192. {
  193. llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
  194. }
  195. }
  196. res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,""));
  197. if (res == -1)
  198. {
  199. if (errno != EEXIST)
  200. {
  201. llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
  202. }
  203. }
  204. res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,""));
  205. if (res == -1)
  206. {
  207. if (errno != EEXIST)
  208. {
  209. llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
  210. }
  211. }
  212. mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
  213. }
  214. U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string &mask)
  215. {
  216. U32 file_count = 0;
  217. glob_t g;
  218. std::string tmp_str;
  219. tmp_str = dirname;
  220. tmp_str += mask;
  221. if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
  222. {
  223. file_count = g.gl_pathc;
  224. globfree(&g);
  225. }
  226. return (file_count);
  227. }
  228. // get the next file in the directory
  229. // automatically wrap if we've hit the end
  230. BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
  231. {
  232. glob_t g;
  233. BOOL result = FALSE;
  234. fname = "";
  235. if(!(dirname == mCurrentDir))
  236. {
  237. // different dir specified, close old search
  238. mCurrentDirIndex = -1;
  239. mCurrentDirCount = -1;
  240. mCurrentDir = dirname;
  241. }
  242. std::string tmp_str;
  243. tmp_str = dirname;
  244. tmp_str += mask;
  245. if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
  246. {
  247. if(g.gl_pathc > 0)
  248. {
  249. if((int)g.gl_pathc != mCurrentDirCount)
  250. {
  251. // Number of matches has changed since the last search, meaning a file has been added or deleted.
  252. // Reset the index.
  253. mCurrentDirIndex = -1;
  254. mCurrentDirCount = g.gl_pathc;
  255. }
  256. mCurrentDirIndex++;
  257. if((mCurrentDirIndex >= (int)g.gl_pathc) && wrap)
  258. {
  259. mCurrentDirIndex = 0;
  260. }
  261. if(mCurrentDirIndex < (int)g.gl_pathc)
  262. {
  263. // llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
  264. // The API wants just the filename, not the full path.
  265. //fname = g.gl_pathv[mCurrentDirIndex];
  266. char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
  267. if(s == NULL)
  268. s = g.gl_pathv[mCurrentDirIndex];
  269. else if(s[0] == '/')
  270. s++;
  271. fname = s;
  272. result = TRUE;
  273. }
  274. }
  275. globfree(&g);
  276. }
  277. return(result);
  278. }
  279. // get a random file in the directory
  280. // automatically wrap if we've hit the end
  281. void LLDir_Solaris::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
  282. {
  283. S32 num_files;
  284. S32 which_file;
  285. DIR *dirp;
  286. dirent *entryp = NULL;
  287. fname = "";
  288. num_files = countFilesInDir(dirname,mask);
  289. if (!num_files)
  290. {
  291. return;
  292. }
  293. which_file = ll_rand(num_files);
  294. // llinfos << "Random select file #" << which_file << llendl;
  295.     // which_file now indicates the (zero-based) index to which file to play
  296. if (!((dirp = opendir(dirname.c_str()))))
  297. {
  298. while (which_file--)
  299. {
  300. if (!((entryp = readdir(dirp))))
  301. {
  302. return;
  303. }
  304. }    
  305. if ((!which_file) && entryp)
  306. {
  307. fname = entryp->d_name;
  308. }
  309. closedir(dirp);
  310. }
  311. }
  312. std::string LLDir_Solaris::getCurPath()
  313. {
  314. char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ 
  315. if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
  316. {
  317. llwarns << "Could not get current directory" << llendl;
  318. tmp_str[0] = '';
  319. }
  320. return tmp_str;
  321. }
  322. BOOL LLDir_Solaris::fileExists(const std::string &filename) const
  323. {
  324. struct stat stat_data;
  325. // Check the age of the file
  326. // Now, we see if the files we've gathered are recent...
  327. int res = stat(filename.c_str(), &stat_data);
  328. if (!res)
  329. {
  330. return TRUE;
  331. }
  332. else
  333. {
  334. return FALSE;
  335. }
  336. }