LCOV - code coverage report
Current view: top level - xpcom/io - nsAppFileLocationProvider.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 104 189 55.0 %
Date: 2017-07-14 16:53:18 Functions: 18 21 85.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13