1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code, released
16 : * March 31, 1998.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 2000
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Conrad Carlen <conrad@ingress.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsAppFileLocationProvider.h"
41 : #include "nsAppDirectoryServiceDefs.h"
42 : #include "nsDirectoryServiceDefs.h"
43 : #include "nsIAtom.h"
44 : #include "nsILocalFile.h"
45 : #include "nsString.h"
46 : #include "nsXPIDLString.h"
47 : #include "nsISimpleEnumerator.h"
48 : #include "prenv.h"
49 : #include "nsCRT.h"
50 :
51 : #if defined(MOZ_WIDGET_COCOA)
52 : #include <Carbon/Carbon.h>
53 : #include "nsILocalFileMac.h"
54 : #elif defined(XP_OS2)
55 : #define INCL_DOSPROCESS
56 : #define INCL_DOSMODULEMGR
57 : #include <os2.h>
58 : #elif defined(XP_WIN)
59 : #include <windows.h>
60 : #include <shlobj.h>
61 : #elif defined(XP_UNIX)
62 : #include <unistd.h>
63 : #include <stdlib.h>
64 : #include <sys/param.h>
65 : #endif
66 :
67 :
68 : // WARNING: These hard coded names need to go away. They need to
69 : // come from localizable resources
70 :
71 : #if defined(MOZ_WIDGET_COCOA)
72 : #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application Registry")
73 : #define ESSENTIAL_FILES NS_LITERAL_CSTRING("Essential Files")
74 : #elif defined(XP_WIN) || defined(XP_OS2)
75 : #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat")
76 : #else
77 : #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("appreg")
78 : #endif
79 :
80 : // define default product directory
81 : #define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR)
82 :
83 : // Locally defined keys used by nsAppDirectoryEnumerator
84 : #define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH
85 : #define NS_USER_PLUGINS_DIR "UserPlugins"
86 :
87 : #ifdef MOZ_WIDGET_COCOA
88 : #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins"
89 : #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins"
90 : #define NS_MACOSX_JAVA2_PLUGIN_DIR "OSXJavaPlugins"
91 : #elif XP_UNIX
92 : #define NS_SYSTEM_PLUGINS_DIR "SysPlugins"
93 : #endif
94 :
95 : #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults")
96 : #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref")
97 : #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile")
98 : #define RES_DIR_NAME NS_LITERAL_CSTRING("res")
99 : #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome")
100 : #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins")
101 : #define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins")
102 :
103 : //*****************************************************************************
104 : // nsAppFileLocationProvider::Constructor/Destructor
105 : //*****************************************************************************
106 :
107 1419 : nsAppFileLocationProvider::nsAppFileLocationProvider()
108 : {
109 1419 : }
110 :
111 : //*****************************************************************************
112 : // nsAppFileLocationProvider::nsISupports
113 : //*****************************************************************************
114 :
115 47181 : NS_IMPL_THREADSAFE_ISUPPORTS2(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
116 :
117 : //*****************************************************************************
118 : // nsAppFileLocationProvider::nsIDirectoryServiceProvider
119 : //*****************************************************************************
120 :
121 : NS_IMETHODIMP
122 13199 : nsAppFileLocationProvider::GetFile(const char *prop, bool *persistent, nsIFile **_retval)
123 : {
124 26398 : nsCOMPtr<nsILocalFile> localFile;
125 13199 : nsresult rv = NS_ERROR_FAILURE;
126 :
127 13199 : NS_ENSURE_ARG(prop);
128 13199 : *_retval = nsnull;
129 13199 : *persistent = true;
130 :
131 : #ifdef MOZ_WIDGET_COCOA
132 : FSRef fileRef;
133 : nsCOMPtr<nsILocalFileMac> macFile;
134 : #endif
135 :
136 13199 : if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
137 : {
138 0 : rv = GetProductDirectory(getter_AddRefs(localFile));
139 : }
140 13199 : else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
141 : {
142 0 : rv = GetProductDirectory(getter_AddRefs(localFile));
143 0 : if (NS_SUCCEEDED(rv))
144 0 : rv = localFile->AppendNative(APP_REGISTRY_NAME);
145 : }
146 13199 : else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
147 : {
148 1 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
149 1 : if (NS_SUCCEEDED(rv))
150 1 : rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
151 : }
152 13198 : else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
153 : {
154 33 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
155 33 : if (NS_SUCCEEDED(rv)) {
156 33 : rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
157 33 : if (NS_SUCCEEDED(rv))
158 33 : rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME);
159 : }
160 : }
161 26330 : else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
162 13165 : nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0)
163 : {
164 0 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
165 0 : if (NS_SUCCEEDED(rv)) {
166 0 : rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
167 0 : if (NS_SUCCEEDED(rv))
168 0 : rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
169 : }
170 : }
171 13165 : else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
172 : {
173 0 : rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
174 : }
175 13165 : else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0)
176 : {
177 0 : rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), true);
178 : }
179 13165 : else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0)
180 : {
181 0 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
182 0 : if (NS_SUCCEEDED(rv))
183 0 : rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
184 : }
185 13165 : else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0)
186 : {
187 1404 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
188 1404 : if (NS_SUCCEEDED(rv))
189 1404 : rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
190 : }
191 11761 : else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
192 : {
193 177 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
194 177 : if (NS_SUCCEEDED(rv))
195 177 : rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
196 : }
197 : #ifdef MOZ_WIDGET_COCOA
198 : else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0)
199 : {
200 : if (::FSFindFolder(kUserDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
201 : rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
202 : if (NS_SUCCEEDED(rv))
203 : localFile = macFile;
204 : }
205 : }
206 : else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0)
207 : {
208 : if (::FSFindFolder(kLocalDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
209 : rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
210 : if (NS_SUCCEEDED(rv))
211 : localFile = macFile;
212 : }
213 : }
214 : else if (nsCRT::strcmp(prop, NS_MACOSX_JAVA2_PLUGIN_DIR) == 0)
215 : {
216 : static const char *const java2PluginDirPath =
217 : "/System/Library/Java/Support/Deploy.bundle/Contents/Resources/";
218 : rv = NS_NewNativeLocalFile(nsDependentCString(java2PluginDirPath), true, getter_AddRefs(localFile));
219 : }
220 : #else
221 11584 : else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0)
222 : {
223 : NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). "
224 0 : "Use nsAppFileLocationProvider::GetFiles(...).");
225 0 : const char *pathVar = PR_GetEnv("MOZ_PLUGIN_PATH");
226 0 : if (pathVar && *pathVar)
227 0 : rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), true,
228 0 : getter_AddRefs(localFile));
229 : }
230 11584 : else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0)
231 : {
232 : #ifdef ENABLE_SYSTEM_EXTENSION_DIRS
233 173 : rv = GetProductDirectory(getter_AddRefs(localFile));
234 173 : if (NS_SUCCEEDED(rv))
235 173 : rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
236 : #else
237 : rv = NS_ERROR_FAILURE;
238 : #endif
239 : }
240 : #ifdef XP_UNIX
241 11411 : else if (nsCRT::strcmp(prop, NS_SYSTEM_PLUGINS_DIR) == 0) {
242 : #ifdef ENABLE_SYSTEM_EXTENSION_DIRS
243 : static const char *const sysLPlgDir =
244 : #if defined(HAVE_USR_LIB64_DIR) && defined(__LP64__)
245 : "/usr/lib64/mozilla/plugins";
246 : #else
247 : "/usr/lib/mozilla/plugins";
248 : #endif
249 173 : rv = NS_NewNativeLocalFile(nsDependentCString(sysLPlgDir),
250 346 : false, getter_AddRefs(localFile));
251 : #else
252 : rv = NS_ERROR_FAILURE;
253 : #endif
254 : }
255 : #endif
256 : #endif
257 11238 : else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0)
258 : {
259 2 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
260 2 : if (NS_SUCCEEDED(rv))
261 2 : rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
262 : }
263 11236 : else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0)
264 : {
265 2 : rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, _retval);
266 2 : if (NS_SUCCEEDED(rv))
267 2 : rv = (*_retval)->AppendNative(SEARCH_DIR_NAME);
268 : }
269 11234 : else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0)
270 : {
271 : // This is cloned so that embeddors will have a hook to override
272 : // with their own cleanup dir. See bugzilla bug #105087
273 0 : rv = CloneMozBinDirectory(getter_AddRefs(localFile));
274 : }
275 :
276 13199 : if (localFile && NS_SUCCEEDED(rv))
277 1963 : return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
278 :
279 11236 : return rv;
280 : }
281 :
282 :
283 1617 : NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsILocalFile **aLocalFile)
284 : {
285 1617 : NS_ENSURE_ARG_POINTER(aLocalFile);
286 : nsresult rv;
287 :
288 1617 : if (!mMozBinDirectory)
289 : {
290 : // Get the mozilla bin directory
291 : // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR
292 : // This will be set if a directory was passed to NS_InitXPCOM
293 : // 2. If that doesn't work, set it to be the current process directory
294 : nsCOMPtr<nsIProperties>
295 2838 : directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
296 1419 : if (NS_FAILED(rv))
297 0 : return rv;
298 :
299 1419 : rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
300 1419 : if (NS_FAILED(rv)) {
301 0 : rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
302 0 : if (NS_FAILED(rv))
303 0 : return rv;
304 : }
305 : }
306 :
307 3234 : nsCOMPtr<nsIFile> aFile;
308 1617 : rv = mMozBinDirectory->Clone(getter_AddRefs(aFile));
309 1617 : if (NS_FAILED(rv))
310 0 : return rv;
311 :
312 3234 : nsCOMPtr<nsILocalFile> lfile = do_QueryInterface (aFile);
313 1617 : if (!lfile)
314 0 : return NS_ERROR_FAILURE;
315 :
316 1617 : NS_IF_ADDREF(*aLocalFile = lfile);
317 1617 : return NS_OK;
318 : }
319 :
320 :
321 : //----------------------------------------------------------------------------------------
322 : // GetProductDirectory - Gets the directory which contains the application data folder
323 : //
324 : // UNIX : ~/.mozilla/
325 : // WIN : <Application Data folder on user's machine>\Mozilla
326 : // Mac : :Documents:Mozilla:
327 : //----------------------------------------------------------------------------------------
328 173 : NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsILocalFile **aLocalFile, bool aLocal)
329 : {
330 173 : NS_ENSURE_ARG_POINTER(aLocalFile);
331 :
332 : nsresult rv;
333 : bool exists;
334 346 : nsCOMPtr<nsILocalFile> localDir;
335 :
336 : #if defined(MOZ_WIDGET_COCOA)
337 : FSRef fsRef;
338 : OSType folderType = aLocal ? (OSType) kCachedDataFolderType : (OSType) kDomainLibraryFolderType;
339 : OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
340 : if (err) return NS_ERROR_FAILURE;
341 : NS_NewLocalFile(EmptyString(), true, getter_AddRefs(localDir));
342 : if (!localDir) return NS_ERROR_FAILURE;
343 : nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir));
344 : rv = localDirMac->InitWithFSRef(&fsRef);
345 : if (NS_FAILED(rv)) return rv;
346 : #elif defined(XP_OS2)
347 : nsCOMPtr<nsIProperties> directoryService =
348 : do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
349 : if (NS_FAILED(rv)) return rv;
350 : rv = directoryService->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
351 : if (NS_FAILED(rv)) return rv;
352 : #elif defined(XP_WIN)
353 : nsCOMPtr<nsIProperties> directoryService =
354 : do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
355 : if (NS_FAILED(rv)) return rv;
356 : const char* prop = aLocal ? NS_WIN_LOCAL_APPDATA_DIR : NS_WIN_APPDATA_DIR;
357 : rv = directoryService->Get(prop, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
358 : if (NS_FAILED(rv)) return rv;
359 : #elif defined(XP_UNIX)
360 173 : rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true, getter_AddRefs(localDir));
361 173 : if (NS_FAILED(rv)) return rv;
362 : #else
363 : #error dont_know_how_to_get_product_dir_on_your_platform
364 : #endif
365 :
366 173 : rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
367 173 : if (NS_FAILED(rv)) return rv;
368 173 : rv = localDir->Exists(&exists);
369 :
370 173 : if (NS_SUCCEEDED(rv) && !exists)
371 0 : rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
372 :
373 173 : if (NS_FAILED(rv)) return rv;
374 :
375 173 : *aLocalFile = localDir;
376 173 : NS_ADDREF(*aLocalFile);
377 :
378 173 : return rv;
379 : }
380 :
381 :
382 : //----------------------------------------------------------------------------------------
383 : // GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
384 : //
385 : // UNIX : ~/.mozilla/
386 : // WIN : <Application Data folder on user's machine>\Mozilla\Profiles
387 : // Mac : :Documents:Mozilla:Profiles:
388 : //----------------------------------------------------------------------------------------
389 0 : NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsILocalFile **aLocalFile, bool aLocal)
390 : {
391 0 : NS_ENSURE_ARG_POINTER(aLocalFile);
392 :
393 : nsresult rv;
394 0 : nsCOMPtr<nsILocalFile> localDir;
395 :
396 0 : rv = GetProductDirectory(getter_AddRefs(localDir), aLocal);
397 0 : if (NS_FAILED(rv)) return rv;
398 :
399 : #if defined(MOZ_WIDGET_COCOA) || defined(XP_OS2) || defined(XP_WIN)
400 : // These 3 platforms share this part of the path - do them as one
401 : rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
402 : if (NS_FAILED(rv)) return rv;
403 :
404 : bool exists;
405 : rv = localDir->Exists(&exists);
406 : if (NS_SUCCEEDED(rv) && !exists)
407 : rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
408 : if (NS_FAILED(rv)) return rv;
409 : #endif
410 :
411 0 : *aLocalFile = localDir;
412 0 : NS_ADDREF(*aLocalFile);
413 :
414 0 : return rv;
415 : }
416 :
417 : //*****************************************************************************
418 : // nsAppFileLocationProvider::nsIDirectoryServiceProvider2
419 : //*****************************************************************************
420 :
421 : class nsAppDirectoryEnumerator : public nsISimpleEnumerator
422 : {
423 : public:
424 : NS_DECL_ISUPPORTS
425 :
426 : /**
427 : * aKeyList is a null-terminated list of properties which are provided by aProvider
428 : * They do not need to be publicly defined keys.
429 : */
430 174 : nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
431 : const char* aKeyList[]) :
432 : mProvider(aProvider),
433 174 : mCurrentKey(aKeyList)
434 : {
435 174 : }
436 :
437 521 : NS_IMETHOD HasMoreElements(bool *result)
438 : {
439 1563 : while (!mNext && *mCurrentKey)
440 : {
441 : bool dontCare;
442 1042 : nsCOMPtr<nsIFile> testFile;
443 521 : (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile));
444 : // Don't return a file which does not exist.
445 : bool exists;
446 521 : if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists)
447 347 : mNext = testFile;
448 : }
449 521 : *result = mNext != nsnull;
450 521 : return NS_OK;
451 : }
452 :
453 347 : NS_IMETHOD GetNext(nsISupports **result)
454 : {
455 347 : NS_ENSURE_ARG_POINTER(result);
456 347 : *result = nsnull;
457 :
458 : bool hasMore;
459 347 : HasMoreElements(&hasMore);
460 347 : if (!hasMore)
461 0 : return NS_ERROR_FAILURE;
462 :
463 347 : *result = mNext;
464 347 : NS_IF_ADDREF(*result);
465 347 : mNext = nsnull;
466 :
467 347 : return *result ? NS_OK : NS_ERROR_FAILURE;
468 : }
469 :
470 : // Virtual destructor since subclass nsPathsDirectoryEnumerator
471 : // does not re-implement Release()
472 :
473 174 : virtual ~nsAppDirectoryEnumerator()
474 174 : {
475 348 : }
476 :
477 : protected:
478 : nsIDirectoryServiceProvider *mProvider;
479 : const char** mCurrentKey;
480 : nsCOMPtr<nsIFile> mNext;
481 : };
482 :
483 2271 : NS_IMPL_ISUPPORTS1(nsAppDirectoryEnumerator, nsISimpleEnumerator)
484 :
485 : /* nsPathsDirectoryEnumerator and PATH_SEPARATOR
486 : * are not used on MacOS/X. */
487 :
488 : #if defined(XP_WIN) || defined(XP_OS2) /* Win32 and OS/2 */
489 : #define PATH_SEPARATOR ';'
490 : #else
491 : #define PATH_SEPARATOR ':'
492 : #endif
493 :
494 : class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator
495 696 : {
496 : public:
497 : /**
498 : * aKeyList is a null-terminated list.
499 : * The first element is a path list.
500 : * The remainder are properties provided by aProvider.
501 : * They do not need to be publicly defined keys.
502 : */
503 174 : nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
504 : const char* aKeyList[]) :
505 : nsAppDirectoryEnumerator(aProvider, aKeyList+1),
506 174 : mEndPath(aKeyList[0])
507 : {
508 174 : }
509 :
510 868 : NS_IMETHOD HasMoreElements(bool *result)
511 : {
512 868 : if (mEndPath)
513 1736 : while (!mNext && *mEndPath)
514 : {
515 0 : const char *pathVar = mEndPath;
516 :
517 : // skip PATH_SEPARATORs at the begining of the mEndPath
518 0 : while (*pathVar == PATH_SEPARATOR) pathVar++;
519 :
520 0 : do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR);
521 :
522 0 : nsCOMPtr<nsILocalFile> localFile;
523 0 : NS_NewNativeLocalFile(Substring(pathVar, mEndPath),
524 : true,
525 0 : getter_AddRefs(localFile));
526 0 : if (*mEndPath == PATH_SEPARATOR)
527 0 : ++mEndPath;
528 : // Don't return a "file" (directory) which does not exist.
529 : bool exists;
530 0 : if (localFile &&
531 0 : NS_SUCCEEDED(localFile->Exists(&exists)) &&
532 : exists)
533 0 : mNext = localFile;
534 : }
535 868 : if (mNext)
536 347 : *result = true;
537 : else
538 521 : nsAppDirectoryEnumerator::HasMoreElements(result);
539 :
540 868 : return NS_OK;
541 : }
542 :
543 : protected:
544 : const char *mEndPath;
545 : };
546 :
547 : NS_IMETHODIMP
548 1630 : nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
549 : {
550 1630 : NS_ENSURE_ARG_POINTER(_retval);
551 1630 : *_retval = nsnull;
552 1630 : nsresult rv = NS_ERROR_FAILURE;
553 :
554 1630 : if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST))
555 : {
556 : #ifdef MOZ_WIDGET_COCOA
557 : // As of Java for Mac OS X 10.5 Update 10, Apple has (in effect) deprecated Java Plugin2 on
558 : // on OS X 10.5, and removed the soft link to it from /Library/Internet Plug-Ins/. Java
559 : // Plugin2 is still present and usable, but there are no longer any links to it in the
560 : // "normal" locations. So we won't be able to find it unless we look in the "non-normal"
561 : // location where it actually is. Safari can use the WebKit-specific JavaPluginCocoa.bundle,
562 : // which (of course) is still fully supported on OS X 10.5. But we have no alternative to
563 : // using Java Plugin2. For more information see bug 668639.
564 : static const char* keys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR,
565 : NS_MACOSX_LOCAL_PLUGIN_DIR,
566 : IsOSXLeopard() ? NS_MACOSX_JAVA2_PLUGIN_DIR : nsnull, nsnull };
567 : *_retval = new nsAppDirectoryEnumerator(this, keys);
568 : #else
569 : #ifdef XP_UNIX
570 : static const char* keys[] = { nsnull, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_SYSTEM_PLUGINS_DIR, nsnull };
571 : #else
572 : static const char* keys[] = { nsnull, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, nsnull };
573 : #endif
574 173 : if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) {
575 : static const char nullstr = 0;
576 173 : keys[0] = &nullstr;
577 : }
578 173 : *_retval = new nsPathsDirectoryEnumerator(this, keys);
579 : #endif
580 173 : NS_IF_ADDREF(*_retval);
581 173 : rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
582 : }
583 1630 : if (!nsCRT::strcmp(prop, NS_APP_SEARCH_DIR_LIST))
584 : {
585 : static const char* keys[] = { nsnull, NS_APP_SEARCH_DIR, NS_APP_USER_SEARCH_DIR, nsnull };
586 1 : if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_SEARCH_ENGINE_PATH"))) {
587 : static const char nullstr = 0;
588 1 : keys[0] = &nullstr;
589 : }
590 1 : *_retval = new nsPathsDirectoryEnumerator(this, keys);
591 1 : NS_IF_ADDREF(*_retval);
592 1 : rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
593 : }
594 1630 : return rv;
595 : }
596 :
597 : #if defined(MOZ_WIDGET_COCOA)
598 : bool
599 : nsAppFileLocationProvider::IsOSXLeopard()
600 : {
601 : static SInt32 version = 0;
602 :
603 : if (!version) {
604 : OSErr err = ::Gestalt(gestaltSystemVersion, &version);
605 : if (err != noErr) {
606 : version = 0;
607 : } else {
608 : version &= 0xFFFF; // The system version is in the low order word
609 : }
610 : }
611 :
612 : return ((version >= 0x1050) && (version < 0x1060));
613 : }
614 : #endif
|