PageRenderTime 73ms CodeModel.GetById 53ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llvfs/lldir_solaris.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 290 lines | 210 code | 44 blank | 36 comment | 48 complexity | d00309b5788c2f774f3f6d8b154bb5d6 MD5 | raw file
  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=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "linden_common.h"
 28
 29#include "lldir_solaris.h"
 30#include "llerror.h"
 31#include "llrand.h"
 32#include <sys/types.h>
 33#include <sys/stat.h>
 34#include <unistd.h>
 35#include <glob.h>
 36#include <pwd.h>
 37#include <sys/utsname.h>
 38#define _STRUCTURED_PROC 1
 39#include <sys/procfs.h>
 40#include <fcntl.h>
 41
 42static std::string getCurrentUserHome(char* fallback)
 43{
 44	const uid_t uid = getuid();
 45	struct passwd *pw;
 46	char *result_cstr = fallback;
 47	
 48	pw = getpwuid(uid);
 49	if ((pw != NULL) && (pw->pw_dir != NULL))
 50	{
 51		result_cstr = (char*) pw->pw_dir;
 52	}
 53	else
 54	{
 55		llinfos << "Couldn't detect home directory from passwd - trying $HOME" << llendl;
 56		const char *const home_env = getenv("HOME");	/* Flawfinder: ignore */ 
 57		if (home_env)
 58		{
 59			result_cstr = (char*) home_env;
 60		}
 61		else
 62		{
 63			llwarns << "Couldn't detect home directory!  Falling back to " << fallback << llendl;
 64		}
 65	}
 66	
 67	return std::string(result_cstr);
 68}
 69
 70
 71LLDir_Solaris::LLDir_Solaris()
 72{
 73	mDirDelimiter = "/";
 74	mCurrentDirIndex = -1;
 75	mCurrentDirCount = -1;
 76	mDirp = NULL;
 77
 78	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
 79	if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
 80	{
 81		strcpy(tmp_str, "/tmp");
 82		llwarns << "Could not get current directory; changing to "
 83				<< tmp_str << llendl;
 84		if (chdir(tmp_str) == -1)
 85		{
 86			llerrs << "Could not change directory to " << tmp_str << llendl;
 87		}
 88	}
 89
 90	mExecutableFilename = "";
 91	mExecutablePathAndName = "";
 92	mExecutableDir = strdup(tmp_str);
 93	mWorkingDir = strdup(tmp_str);
 94	mAppRODataDir = strdup(tmp_str);
 95	mOSUserDir = getCurrentUserHome(tmp_str);
 96	mOSUserAppDir = "";
 97	mLindenUserDir = "";
 98
 99	char path [LL_MAX_PATH];	/* Flawfinder: ignore */ 
100
101	sprintf(path, "/proc/%d/psinfo", (int)getpid());
102	int proc_fd = -1;
103	if((proc_fd = open(path, O_RDONLY)) == -1){
104		llwarns << "unable to open " << path << llendl;
105		return;
106	}
107	psinfo_t proc_psinfo;
108	if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
109		llwarns << "Unable to read " << path << llendl;
110		close(proc_fd);
111		return;
112	}
113
114	close(proc_fd);
115
116	mExecutableFilename = strdup(proc_psinfo.pr_fname);
117	llinfos << "mExecutableFilename = [" << mExecutableFilename << "]" << llendl;
118
119	sprintf(path, "/proc/%d/path/a.out", (int)getpid());
120
121	char execpath[LL_MAX_PATH];
122	if(readlink(path, execpath, LL_MAX_PATH) == -1){
123		llwarns << "Unable to read link from " << path << llendl;
124		return;
125	}
126
127	char *p = execpath;			// nuke trash in link, if any exists
128	int i = 0;
129	while(*p != NULL && ++i < LL_MAX_PATH && isprint((int)(*p++)));
130	*p = NULL;
131
132	mExecutablePathAndName = strdup(execpath);
133	llinfos << "mExecutablePathAndName = [" << mExecutablePathAndName << "]" << llendl;
134
135	//NOTE: Why force people to cd into the package directory?
136	//      Look for SECONDLIFE env variable and use it, if set.
137
138	char *dcf = getenv("SECONDLIFE");
139	if(dcf != NULL){
140		(void)strcpy(path, dcf);
141		(void)strcat(path, "/bin");	//NOTE:  make sure we point at the bin
142		mExecutableDir = strdup(path);
143	}else{
144			// plunk a null at last '/' to get exec dir
145		char *s = execpath + strlen(execpath) -1;
146		while(*s != '/' && s != execpath){
147			--s;
148		}
149	
150		if(s != execpath){
151			*s = (char)NULL;
152	
153			mExecutableDir = strdup(execpath);
154			llinfos << "mExecutableDir = [" << mExecutableDir << "]" << llendl;
155		}
156	}
157	
158	mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
159
160	// *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
161	mTempDir = "/tmp";
162}
163
164LLDir_Solaris::~LLDir_Solaris()
165{
166}
167
168// Implementation
169
170
171void LLDir_Solaris::initAppDirs(const std::string &app_name,
172								const std::string& app_read_only_data_dir)
173{
174	// Allow override so test apps can read newview directory
175	if (!app_read_only_data_dir.empty())
176	{
177		mAppRODataDir = app_read_only_data_dir;
178	}
179	mAppName = app_name;
180
181	std::string upper_app_name(app_name);
182	LLStringUtil::toUpper(upper_app_name);
183
184	char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str());	/* Flawfinder: ignore */ 
185	if (app_home_env)
186	{
187		// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
188		mOSUserAppDir = app_home_env;
189	}
190	else
191	{
192		// traditionally on unixoids, MyApp gets ~/.myapp dir for data
193		mOSUserAppDir = mOSUserDir;
194		mOSUserAppDir += "/";
195		mOSUserAppDir += ".";
196		std::string lower_app_name(app_name);
197		LLStringUtil::toLower(lower_app_name);
198		mOSUserAppDir += lower_app_name;
199	}
200
201	// create any directories we expect to write to.
202
203	int res = LLFile::mkdir(mOSUserAppDir);
204	if (res == -1)
205	{
206		if (errno != EEXIST)
207		{
208			llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
209			llwarns << "Default to base dir" << mOSUserDir << llendl;
210			mOSUserAppDir = mOSUserDir;
211		}
212	}
213
214	res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,""));
215	if (res == -1)
216	{
217		if (errno != EEXIST)
218		{
219			llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
220		}
221	}
222	
223	res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,""));
224	if (res == -1)
225	{
226		if (errno != EEXIST)
227		{
228			llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
229		}
230	}
231	
232	res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,""));
233	if (res == -1)
234	{
235		if (errno != EEXIST)
236		{
237			llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
238		}
239	}
240	
241	mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
242}
243
244U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string &mask)
245{
246	U32 file_count = 0;
247	glob_t g;
248
249	std::string tmp_str;
250	tmp_str = dirname;
251	tmp_str += mask;
252	
253	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
254	{
255		file_count = g.gl_pathc;
256
257		globfree(&g);
258	}
259
260	return (file_count);
261}
262
263std::string LLDir_Solaris::getCurPath()
264{
265	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
266	if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
267	{
268		llwarns << "Could not get current directory" << llendl;
269		tmp_str[0] = '\0';
270	}
271	return tmp_str;
272}
273
274
275BOOL LLDir_Solaris::fileExists(const std::string &filename) const
276{
277	struct stat stat_data;
278	// Check the age of the file
279	// Now, we see if the files we've gathered are recent...
280	int res = stat(filename.c_str(), &stat_data);
281	if (!res)
282	{
283		return TRUE;
284	}
285	else
286	{
287		return FALSE;
288	}
289}
290