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