michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsAppFileLocationProvider.h" michael@0: #include "nsAppDirectoryServiceDefs.h" michael@0: #include "nsDirectoryServiceDefs.h" michael@0: #include "nsIAtom.h" michael@0: #include "nsIFile.h" michael@0: #include "nsString.h" michael@0: #include "nsXPIDLString.h" michael@0: #include "nsISimpleEnumerator.h" michael@0: #include "prenv.h" michael@0: #include "nsCRT.h" michael@0: #include "nsXPCOMPrivate.h" // for XPCOM_FILE_PATH_SEPARATOR michael@0: michael@0: #if defined(MOZ_WIDGET_COCOA) michael@0: #include michael@0: #include "nsILocalFileMac.h" michael@0: #elif defined(XP_WIN) michael@0: #include michael@0: #include michael@0: #elif defined(XP_UNIX) michael@0: #include michael@0: #include michael@0: #include michael@0: #endif michael@0: michael@0: michael@0: // WARNING: These hard coded names need to go away. They need to michael@0: // come from localizable resources michael@0: michael@0: #if defined(MOZ_WIDGET_COCOA) michael@0: #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application Registry") michael@0: #define ESSENTIAL_FILES NS_LITERAL_CSTRING("Essential Files") michael@0: #elif defined(XP_WIN) michael@0: #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat") michael@0: #else michael@0: #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("appreg") michael@0: #endif michael@0: michael@0: // define default product directory michael@0: #define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR) michael@0: michael@0: // Locally defined keys used by nsAppDirectoryEnumerator michael@0: #define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH michael@0: #define NS_USER_PLUGINS_DIR "UserPlugins" michael@0: michael@0: #ifdef MOZ_WIDGET_COCOA michael@0: #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins" michael@0: #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins" michael@0: #define NS_MACOSX_JAVA2_PLUGIN_DIR "OSXJavaPlugins" michael@0: #elif XP_UNIX michael@0: #define NS_SYSTEM_PLUGINS_DIR "SysPlugins" michael@0: #endif michael@0: michael@0: #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults") michael@0: #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref") michael@0: #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile") michael@0: #define RES_DIR_NAME NS_LITERAL_CSTRING("res") michael@0: #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome") michael@0: #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins") michael@0: #define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins") michael@0: michael@0: //***************************************************************************** michael@0: // nsAppFileLocationProvider::Constructor/Destructor michael@0: //***************************************************************************** michael@0: michael@0: nsAppFileLocationProvider::nsAppFileLocationProvider() michael@0: { michael@0: } michael@0: michael@0: //***************************************************************************** michael@0: // nsAppFileLocationProvider::nsISupports michael@0: //***************************************************************************** michael@0: michael@0: NS_IMPL_ISUPPORTS(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2) michael@0: michael@0: //***************************************************************************** michael@0: // nsAppFileLocationProvider::nsIDirectoryServiceProvider michael@0: //***************************************************************************** michael@0: michael@0: NS_IMETHODIMP michael@0: nsAppFileLocationProvider::GetFile(const char *prop, bool *persistent, nsIFile **_retval) michael@0: { michael@0: if (NS_WARN_IF(!prop)) michael@0: return NS_ERROR_INVALID_ARG; michael@0: michael@0: nsCOMPtr localFile; michael@0: nsresult rv = NS_ERROR_FAILURE; michael@0: michael@0: *_retval = nullptr; michael@0: *persistent = true; michael@0: michael@0: #ifdef MOZ_WIDGET_COCOA michael@0: FSRef fileRef; michael@0: nsCOMPtr macFile; michael@0: #endif michael@0: michael@0: if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0) michael@0: { michael@0: rv = GetProductDirectory(getter_AddRefs(localFile)); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0) michael@0: { michael@0: rv = GetProductDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendNative(APP_REGISTRY_NAME); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0) michael@0: { michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0) michael@0: { michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME); michael@0: } michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 || michael@0: nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0) michael@0: { michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME); michael@0: } michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0) michael@0: { michael@0: rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile)); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0) michael@0: { michael@0: rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), true); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0) michael@0: { michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(RES_DIR_NAME); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0) michael@0: { michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0) michael@0: { michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); michael@0: } michael@0: #ifdef MOZ_WIDGET_COCOA michael@0: else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0) michael@0: { michael@0: if (::FSFindFolder(kUserDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) { michael@0: rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: localFile = macFile; michael@0: } michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0) michael@0: { michael@0: if (::FSFindFolder(kLocalDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) { michael@0: rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: localFile = macFile; michael@0: } michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_MACOSX_JAVA2_PLUGIN_DIR) == 0) michael@0: { michael@0: static const char *const java2PluginDirPath = michael@0: "/System/Library/Java/Support/Deploy.bundle/Contents/Resources/"; michael@0: rv = NS_NewNativeLocalFile(nsDependentCString(java2PluginDirPath), true, getter_AddRefs(localFile)); michael@0: } michael@0: #else michael@0: else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0) michael@0: { michael@0: NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). " michael@0: "Use nsAppFileLocationProvider::GetFiles(...)."); michael@0: const char *pathVar = PR_GetEnv("MOZ_PLUGIN_PATH"); michael@0: if (pathVar && *pathVar) michael@0: rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), true, michael@0: getter_AddRefs(localFile)); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0) michael@0: { michael@0: #ifdef ENABLE_SYSTEM_EXTENSION_DIRS michael@0: rv = GetProductDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); michael@0: #else michael@0: rv = NS_ERROR_FAILURE; michael@0: #endif michael@0: } michael@0: #ifdef XP_UNIX michael@0: else if (nsCRT::strcmp(prop, NS_SYSTEM_PLUGINS_DIR) == 0) { michael@0: #ifdef ENABLE_SYSTEM_EXTENSION_DIRS michael@0: static const char *const sysLPlgDir = michael@0: #if defined(HAVE_USR_LIB64_DIR) && defined(__LP64__) michael@0: "/usr/lib64/mozilla/plugins"; michael@0: #elif defined(__OpenBSD__) || defined (__FreeBSD__) michael@0: "/usr/local/lib/mozilla/plugins"; michael@0: #else michael@0: "/usr/lib/mozilla/plugins"; michael@0: #endif michael@0: rv = NS_NewNativeLocalFile(nsDependentCString(sysLPlgDir), michael@0: false, getter_AddRefs(localFile)); michael@0: #else michael@0: rv = NS_ERROR_FAILURE; michael@0: #endif michael@0: } michael@0: #endif michael@0: #endif michael@0: else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0) michael@0: { michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0) michael@0: { michael@0: rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, _retval); michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = (*_retval)->AppendNative(SEARCH_DIR_NAME); michael@0: } michael@0: else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0) michael@0: { michael@0: // This is cloned so that embeddors will have a hook to override michael@0: // with their own cleanup dir. See bugzilla bug #105087 michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localFile)); michael@0: } michael@0: michael@0: if (localFile && NS_SUCCEEDED(rv)) michael@0: return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: michael@0: NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile **aLocalFile) michael@0: { michael@0: if (NS_WARN_IF(!aLocalFile)) michael@0: return NS_ERROR_INVALID_ARG; michael@0: nsresult rv; michael@0: michael@0: if (!mMozBinDirectory) michael@0: { michael@0: // Get the mozilla bin directory michael@0: // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR michael@0: // This will be set if a directory was passed to NS_InitXPCOM michael@0: // 2. If that doesn't work, set it to be the current process directory michael@0: nsCOMPtr michael@0: directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory)); michael@0: if (NS_FAILED(rv)) { michael@0: rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory)); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: } michael@0: } michael@0: michael@0: nsCOMPtr aFile; michael@0: rv = mMozBinDirectory->Clone(getter_AddRefs(aFile)); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: NS_IF_ADDREF(*aLocalFile = aFile); michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: //---------------------------------------------------------------------------------------- michael@0: // GetProductDirectory - Gets the directory which contains the application data folder michael@0: // michael@0: // UNIX and WIN : /TorBrowser/Data/Browser michael@0: // Mac : /../../TorBrowser/Data/Browser michael@0: //---------------------------------------------------------------------------------------- michael@0: NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, bool aLocal) michael@0: { michael@0: if (NS_WARN_IF(!aLocalFile)) michael@0: return NS_ERROR_INVALID_ARG; michael@0: michael@0: nsresult rv; michael@0: bool exists; michael@0: nsCOMPtr localDir; michael@0: michael@0: rv = CloneMozBinDirectory(getter_AddRefs(localDir)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory. michael@0: #if defined(XP_MACOSX) michael@0: levelsToRemove += 2; michael@0: #endif michael@0: while (localDir && (levelsToRemove > 0)) { michael@0: // When crawling up the hierarchy, components named "." do not count. michael@0: nsAutoCString removedName; michael@0: rv = localDir->GetNativeLeafName(removedName); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: bool didRemove = !removedName.Equals("."); michael@0: michael@0: // Remove a directory component. michael@0: nsCOMPtr parentDir; michael@0: rv = localDir->GetParent(getter_AddRefs(parentDir)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: localDir = parentDir; michael@0: michael@0: if (didRemove) michael@0: --levelsToRemove; michael@0: } michael@0: michael@0: if (!localDir) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser" michael@0: XPCOM_FILE_PATH_SEPARATOR "Data" michael@0: XPCOM_FILE_PATH_SEPARATOR "Browser")); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (aLocal) { michael@0: rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches")); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: rv = localDir->Exists(&exists); michael@0: michael@0: if (NS_SUCCEEDED(rv) && !exists) michael@0: rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700); michael@0: michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: *aLocalFile = localDir; michael@0: NS_ADDREF(*aLocalFile); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: michael@0: //---------------------------------------------------------------------------------------- michael@0: // GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir michael@0: //---------------------------------------------------------------------------------------- michael@0: NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile **aLocalFile, bool aLocal) michael@0: { michael@0: if (NS_WARN_IF(!aLocalFile)) michael@0: return NS_ERROR_INVALID_ARG; michael@0: michael@0: nsresult rv; michael@0: nsCOMPtr localDir; michael@0: michael@0: rv = GetProductDirectory(getter_AddRefs(localDir), aLocal); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: *aLocalFile = localDir; michael@0: NS_ADDREF(*aLocalFile); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: //***************************************************************************** michael@0: // nsAppFileLocationProvider::nsIDirectoryServiceProvider2 michael@0: //***************************************************************************** michael@0: michael@0: class nsAppDirectoryEnumerator : public nsISimpleEnumerator michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: /** michael@0: * aKeyList is a null-terminated list of properties which are provided by aProvider michael@0: * They do not need to be publicly defined keys. michael@0: */ michael@0: nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider, michael@0: const char* aKeyList[]) : michael@0: mProvider(aProvider), michael@0: mCurrentKey(aKeyList) michael@0: { michael@0: } michael@0: michael@0: NS_IMETHOD HasMoreElements(bool *result) michael@0: { michael@0: while (!mNext && *mCurrentKey) michael@0: { michael@0: bool dontCare; michael@0: nsCOMPtr testFile; michael@0: (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile)); michael@0: // Don't return a file which does not exist. michael@0: bool exists; michael@0: if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists) michael@0: mNext = testFile; michael@0: } michael@0: *result = mNext != nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD GetNext(nsISupports **result) michael@0: { michael@0: if (NS_WARN_IF(!result)) michael@0: return NS_ERROR_INVALID_ARG; michael@0: *result = nullptr; michael@0: michael@0: bool hasMore; michael@0: HasMoreElements(&hasMore); michael@0: if (!hasMore) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: *result = mNext; michael@0: NS_IF_ADDREF(*result); michael@0: mNext = nullptr; michael@0: michael@0: return *result ? NS_OK : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: // Virtual destructor since subclass nsPathsDirectoryEnumerator michael@0: // does not re-implement Release() michael@0: michael@0: virtual ~nsAppDirectoryEnumerator() michael@0: { michael@0: } michael@0: michael@0: protected: michael@0: nsIDirectoryServiceProvider *mProvider; michael@0: const char** mCurrentKey; michael@0: nsCOMPtr mNext; michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(nsAppDirectoryEnumerator, nsISimpleEnumerator) michael@0: michael@0: /* nsPathsDirectoryEnumerator and PATH_SEPARATOR michael@0: * are not used on MacOS/X. */ michael@0: michael@0: #if defined(XP_WIN) /* Win32 */ michael@0: #define PATH_SEPARATOR ';' michael@0: #else michael@0: #define PATH_SEPARATOR ':' michael@0: #endif michael@0: michael@0: class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator michael@0: { michael@0: public: michael@0: /** michael@0: * aKeyList is a null-terminated list. michael@0: * The first element is a path list. michael@0: * The remainder are properties provided by aProvider. michael@0: * They do not need to be publicly defined keys. michael@0: */ michael@0: nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider, michael@0: const char* aKeyList[]) : michael@0: nsAppDirectoryEnumerator(aProvider, aKeyList+1), michael@0: mEndPath(aKeyList[0]) michael@0: { michael@0: } michael@0: michael@0: NS_IMETHOD HasMoreElements(bool *result) michael@0: { michael@0: if (mEndPath) michael@0: while (!mNext && *mEndPath) michael@0: { michael@0: const char *pathVar = mEndPath; michael@0: michael@0: // skip PATH_SEPARATORs at the begining of the mEndPath michael@0: while (*pathVar == PATH_SEPARATOR) pathVar++; michael@0: michael@0: do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR); michael@0: michael@0: nsCOMPtr localFile; michael@0: NS_NewNativeLocalFile(Substring(pathVar, mEndPath), michael@0: true, michael@0: getter_AddRefs(localFile)); michael@0: if (*mEndPath == PATH_SEPARATOR) michael@0: ++mEndPath; michael@0: // Don't return a "file" (directory) which does not exist. michael@0: bool exists; michael@0: if (localFile && michael@0: NS_SUCCEEDED(localFile->Exists(&exists)) && michael@0: exists) michael@0: mNext = localFile; michael@0: } michael@0: if (mNext) michael@0: *result = true; michael@0: else michael@0: nsAppDirectoryEnumerator::HasMoreElements(result); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: protected: michael@0: const char *mEndPath; michael@0: }; michael@0: michael@0: NS_IMETHODIMP michael@0: nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval) michael@0: { michael@0: if (NS_WARN_IF(!_retval)) michael@0: return NS_ERROR_INVALID_ARG; michael@0: *_retval = nullptr; michael@0: nsresult rv = NS_ERROR_FAILURE; michael@0: michael@0: if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST)) michael@0: { michael@0: #ifdef MOZ_WIDGET_COCOA michael@0: // As of Java for Mac OS X 10.5 Update 10, Apple has (in effect) deprecated Java Plugin2 on michael@0: // on OS X 10.5, and removed the soft link to it from /Library/Internet Plug-Ins/. Java michael@0: // Plugin2 is still present and usable, but there are no longer any links to it in the michael@0: // "normal" locations. So we won't be able to find it unless we look in the "non-normal" michael@0: // location where it actually is. Safari can use the WebKit-specific JavaPluginCocoa.bundle, michael@0: // which (of course) is still fully supported on OS X 10.5. But we have no alternative to michael@0: // using Java Plugin2. For more information see bug 668639. michael@0: static const char* keys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, michael@0: NS_MACOSX_LOCAL_PLUGIN_DIR, michael@0: IsOSXLeopard() ? NS_MACOSX_JAVA2_PLUGIN_DIR : nullptr, nullptr }; michael@0: *_retval = new nsAppDirectoryEnumerator(this, keys); michael@0: #else michael@0: #ifdef XP_UNIX michael@0: static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_SYSTEM_PLUGINS_DIR, nullptr }; michael@0: #else michael@0: static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, nullptr }; michael@0: #endif michael@0: if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) { michael@0: static const char nullstr = 0; michael@0: keys[0] = &nullstr; michael@0: } michael@0: *_retval = new nsPathsDirectoryEnumerator(this, keys); michael@0: #endif michael@0: NS_IF_ADDREF(*_retval); michael@0: rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: if (!nsCRT::strcmp(prop, NS_APP_SEARCH_DIR_LIST)) michael@0: { michael@0: static const char* keys[] = { nullptr, NS_APP_SEARCH_DIR, NS_APP_USER_SEARCH_DIR, nullptr }; michael@0: if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_SEARCH_ENGINE_PATH"))) { michael@0: static const char nullstr = 0; michael@0: keys[0] = &nullstr; michael@0: } michael@0: *_retval = new nsPathsDirectoryEnumerator(this, keys); michael@0: NS_IF_ADDREF(*_retval); michael@0: rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: #if defined(MOZ_WIDGET_COCOA) michael@0: bool michael@0: nsAppFileLocationProvider::IsOSXLeopard() michael@0: { michael@0: static SInt32 version = 0; michael@0: michael@0: if (!version) { michael@0: OSErr err = ::Gestalt(gestaltSystemVersion, &version); michael@0: if (err != noErr) { michael@0: version = 0; michael@0: } else { michael@0: version &= 0xFFFF; // The system version is in the low order word michael@0: } michael@0: } michael@0: michael@0: return ((version >= 0x1050) && (version < 0x1060)); michael@0: } michael@0: #endif