Commit 62df6067 authored by Kathleen Brade's avatar Kathleen Brade Committed by Mike Perry
Browse files

Bug #9173: Change the default Firefox profile directory to be TBB-relative.

This should eliminate our need to rely on a wrapper script that sets $HOME and
launches Firefox with -profile.

See https://trac.torproject.org/projects/tor/ticket/9173.
parent 6c7ce74a
Loading
Loading
Loading
Loading
+34 −143
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include "nsArrayEnumerator.h"
#include "nsEnumeratorUtils.h"
#include "nsReadableUtils.h"
#include "nsXPCOMPrivate.h"  // for XPCOM_FILE_PATH_SEPARATOR
#include "mozilla/Services.h"
#include "mozilla/Omnijar.h"
#include "mozilla/Preferences.h"
@@ -192,9 +193,6 @@ nsXREDirProvider::GetUserProfilesRootDir(nsIFile** aResult,
                                     aProfileName, aAppName, aVendorName);

  if (NS_SUCCEEDED(rv)) {
#if !defined(XP_UNIX) || defined(XP_MACOSX)
    rv = file->AppendNative(NS_LITERAL_CSTRING("Profiles"));
#endif
    // We must create the profile directory here if it does not exist.
    nsresult tmp = EnsureDirectoryExists(file);
    if (NS_FAILED(tmp)) {
@@ -217,9 +215,6 @@ nsXREDirProvider::GetUserProfilesLocalDir(nsIFile** aResult,
                                     aProfileName, aAppName, aVendorName);

  if (NS_SUCCEEDED(rv)) {
#if !defined(XP_UNIX) || defined(XP_MACOSX)
    rv = file->AppendNative(NS_LITERAL_CSTRING("Profiles"));
#endif
    // We must create the profile directory here if it does not exist.
    nsresult tmp = EnsureDirectoryExists(file);
    if (NS_FAILED(tmp)) {
@@ -1137,106 +1132,45 @@ nsresult
nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal)
{
  // Copied from nsAppFileLocationProvider (more or less)
  nsresult rv;
  NS_ENSURE_ARG_POINTER(aFile);
  nsCOMPtr<nsIFile> localDir;

  nsresult rv = GetAppDir()->Clone(getter_AddRefs(localDir));
  NS_ENSURE_SUCCESS(rv, rv);

  int levelsToRemove = 1; // In FF21+, appDir points to browser subdirectory.
#if defined(XP_MACOSX)
  FSRef fsRef;
  OSType folderType;
  if (aLocal) {
    folderType = kCachedDataFolderType;
  } else {
#ifdef MOZ_THUNDERBIRD
    folderType = kDomainLibraryFolderType;
#else
    folderType = kApplicationSupportFolderType;
  levelsToRemove += 2;
#endif
  }
  OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
  NS_ENSURE_FALSE(err, NS_ERROR_FAILURE);

  rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(localDir));
  while (localDir && (levelsToRemove > 0)) {
    // When crawling up the hierarchy, components named "." do not count.
    nsAutoCString removedName;
    rv = localDir->GetNativeLeafName(removedName);
    NS_ENSURE_SUCCESS(rv, rv);
    bool didRemove = !removedName.Equals(".");

  nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(localDir);
  NS_ENSURE_TRUE(dirFileMac, NS_ERROR_UNEXPECTED);

  rv = dirFileMac->InitWithFSRef(&fsRef);
    // Remove a directory component.
    nsCOMPtr<nsIFile> parentDir;
    rv = localDir->GetParent(getter_AddRefs(parentDir));
    NS_ENSURE_SUCCESS(rv, rv);
    localDir = parentDir;

  localDir = do_QueryInterface(dirFileMac, &rv);
#elif defined(XP_WIN)
  nsString path;
  if (aLocal) {
    rv = GetShellFolderPath(CSIDL_LOCAL_APPDATA, path);
    if (NS_FAILED(rv))
      rv = GetRegWindowsAppDataFolder(aLocal, path);
  }
  if (!aLocal || NS_FAILED(rv)) {
    rv = GetShellFolderPath(CSIDL_APPDATA, path);
    if (NS_FAILED(rv)) {
      if (!aLocal)
        rv = GetRegWindowsAppDataFolder(aLocal, path);
    }
    if (didRemove)
      --levelsToRemove;
  }
  NS_ENSURE_SUCCESS(rv, rv);

  rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir));
#elif defined(XP_OS2)
#if 0 /* For OS/2 we want to always use MOZILLA_HOME */
  // we want an environment variable of the form
  // FIREFOX_HOME, etc
  if (!gAppData)
    return NS_ERROR_FAILURE;
  nsDependentCString envVar(nsDependentCString(gAppData->name));
  envVar.Append("_HOME");
  char *pHome = getenv(envVar.get());
#endif
  char *pHome = getenv("MOZILLA_HOME");
  if (pHome && *pHome) {
    rv = NS_NewNativeLocalFile(nsDependentCString(pHome), true,
                               getter_AddRefs(localDir));
  } else {
    PPIB ppib;
    PTIB ptib;
    char appDir[CCHMAXPATH];

    DosGetInfoBlocks(&ptib, &ppib);
    DosQueryModuleName(ppib->pib_hmte, CCHMAXPATH, appDir);
    *strrchr(appDir, '\\') = '\0';
    rv = NS_NewNativeLocalFile(nsDependentCString(appDir), true, getter_AddRefs(localDir));
  }
#elif defined(MOZ_WIDGET_GONK)
  rv = NS_NewNativeLocalFile(NS_LITERAL_CSTRING("/data/b2g"), true,
                             getter_AddRefs(localDir));
#elif defined(XP_UNIX)
  const char* homeDir = getenv("HOME");
  if (!homeDir || !*homeDir)
  if (!localDir)
    return NS_ERROR_FAILURE;

#ifdef ANDROID /* We want (ProfD == ProfLD) on Android. */
  aLocal = false;
#endif
  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
                                     XPCOM_FILE_PATH_SEPARATOR "Data"
                                     XPCOM_FILE_PATH_SEPARATOR "Browser"));
  NS_ENSURE_SUCCESS(rv, rv);

  if (aLocal) {
    // If $XDG_CACHE_HOME is defined use it, otherwise use $HOME/.cache.
    const char* cacheHome = getenv("XDG_CACHE_HOME");
    if (cacheHome && *cacheHome) {
      rv = NS_NewNativeLocalFile(nsDependentCString(cacheHome), true,
                                 getter_AddRefs(localDir));
    } else {
      rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
                                 getter_AddRefs(localDir));
      if (NS_SUCCEEDED(rv))
        rv = localDir->AppendNative(NS_LITERAL_CSTRING(".cache"));
    }
  } else {
    rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
                               getter_AddRefs(localDir));
    rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches"));
    NS_ENSURE_SUCCESS(rv, rv);
  }
#else
#error "Don't know how to get product dir on your platform"
#endif

  NS_IF_ADDREF(*aFile = localDir);
  return rv;
@@ -1449,48 +1383,25 @@ nsXREDirProvider::AppendProfilePath(nsIFile* aFile,
  }

  nsAutoCString profile;
  nsAutoCString appName;
  nsAutoCString vendor;
  if (aProfileName && !aProfileName->IsEmpty()) {
    profile = *aProfileName;
  } else if (aAppName) {
    appName = *aAppName;
    if (aVendorName) {
      vendor = *aVendorName;
    }
  } else if (gAppData->profile) {
    profile = gAppData->profile;
  } else {
    appName = gAppData->name;
    vendor = gAppData->vendor;
  }

  nsresult rv;
  nsresult rv = NS_ERROR_FAILURE;

#if defined (XP_MACOSX)
  if (!profile.IsEmpty()) {
    rv = AppendProfileString(aFile, profile.get());
  }
  else {
    // Note that MacOS ignores the vendor when creating the profile hierarchy -
    // all application preferences directories live alongside one another in
    // ~/Library/Application Support/
    rv = aFile->AppendNative(appName);
  }
    NS_ENSURE_SUCCESS(rv, rv);
  }

#elif defined(XP_WIN) || defined(XP_OS2)
  if (!profile.IsEmpty()) {
    rv = AppendProfileString(aFile, profile.get());
  }
  else {
    if (!vendor.IsEmpty()) {
      rv = aFile->AppendNative(vendor);
    NS_ENSURE_SUCCESS(rv, rv);
  }
    rv = aFile->AppendNative(appName);
  }
  NS_ENSURE_SUCCESS(rv, rv);

#elif defined(ANDROID)
  // The directory used for storing profiles
@@ -1502,12 +1413,6 @@ nsXREDirProvider::AppendProfilePath(nsIFile* aFile,
  rv = aFile->AppendNative(nsDependentCString("mozilla"));
  NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_UNIX)
  nsAutoCString folder;
  // Make it hidden (by starting with "."), except when local (the
  // profile is already under ~/.cache or XDG_CACHE_HOME).
  if (!aLocal)
    folder.Assign('.');

  if (!profile.IsEmpty()) {
    // Skip any leading path characters
    const char* profileStart = profile.get();
@@ -1516,31 +1421,17 @@ nsXREDirProvider::AppendProfilePath(nsIFile* aFile,

    // On the off chance that someone wanted their folder to be hidden don't
    // let it become ".."
    if (*profileStart == '.' && !aLocal)
    if (*profileStart == '.')
      profileStart++;

    // Make it hidden (by starting with ".").
    nsAutoCString folder(".");
    folder.Append(profileStart);
    ToLowerCase(folder);

    rv = AppendProfileString(aFile, folder.BeginReading());
  }
  else {
    if (!vendor.IsEmpty()) {
      folder.Append(vendor);
      ToLowerCase(folder);

      rv = aFile->AppendNative(folder);
    NS_ENSURE_SUCCESS(rv, rv);

      folder.Truncate();
    }

    folder.Append(appName);
    ToLowerCase(folder);

    rv = aFile->AppendNative(folder);
  }
  NS_ENSURE_SUCCESS(rv, rv);

#else
#error "Don't know how to get profile path on your platform"
+5 −5
Original line number Diff line number Diff line
@@ -56,16 +56,16 @@ public:

  nsresult GetProfileDefaultsDir(nsIFile* *aResult);

  static nsresult GetUserAppDataDirectory(nsIFile* *aFile) {
  nsresult GetUserAppDataDirectory(nsIFile* *aFile) {
    return GetUserDataDirectory(aFile, false, nullptr, nullptr, nullptr);
  }
  static nsresult GetUserLocalDataDirectory(nsIFile* *aFile) {
  nsresult GetUserLocalDataDirectory(nsIFile* *aFile) {
    return GetUserDataDirectory(aFile, true, nullptr, nullptr, nullptr);
  }

  // By default GetUserDataDirectory gets profile path from gAppData,
  // but that can be overridden by using aProfileName/aAppName/aVendorName.
  static nsresult GetUserDataDirectory(nsIFile** aFile, bool aLocal,
  nsresult GetUserDataDirectory(nsIFile** aFile, bool aLocal,
                                       const nsACString* aProfileName,
                                       const nsACString* aAppName,
                                       const nsACString* aVendorName);
@@ -101,8 +101,8 @@ public:

protected:
  nsresult GetFilesInternal(const char* aProperty, nsISimpleEnumerator** aResult);
  static nsresult GetUserDataDirectoryHome(nsIFile* *aFile, bool aLocal);
  static nsresult GetSysUserExtensionsDirectory(nsIFile* *aFile);
  nsresult GetUserDataDirectoryHome(nsIFile* *aFile, bool aLocal);
  nsresult GetSysUserExtensionsDirectory(nsIFile* *aFile);
#if defined(XP_UNIX) || defined(XP_MACOSX)
  static nsresult GetSystemExtensionsDirectory(nsIFile** aFile);
#endif
+3 −1
Original line number Diff line number Diff line
@@ -48,7 +48,9 @@ DEFINES += -DHAVE_USR_LIB64_DIR
endif
endif

LOCAL_INCLUDES	+= -I..
LOCAL_INCLUDES	+=	\
		-I.. \
		-I$(srcdir)/../build

ifeq ($(MOZ_PLATFORM_MAEMO),5)
CFLAGS          += $(MOZ_DBUS_CFLAGS)
+38 −49
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "nsISimpleEnumerator.h"
#include "prenv.h"
#include "nsCRT.h"
#include "nsXPCOMPrivate.h"  // for XPCOM_FILE_PATH_SEPARATOR

#if defined(MOZ_WIDGET_COCOA)
#include <Carbon/Carbon.h>
@@ -285,9 +286,8 @@ NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile **aLocalFile)
//----------------------------------------------------------------------------------------
// GetProductDirectory - Gets the directory which contains the application data folder
//
// UNIX   : ~/.mozilla/
// WIN    : <Application Data folder on user's machine>\Mozilla
// Mac    : :Documents:Mozilla:
// UNIX and WIN   : <App Folder>/TorBrowser/Data/Browser
// Mac            : <App Folder>/../../TorBrowser/Data/Browser
//----------------------------------------------------------------------------------------
NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, bool aLocal)
{
@@ -297,38 +297,43 @@ NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, b
    bool exists;
    nsCOMPtr<nsIFile> localDir;

#if defined(MOZ_WIDGET_COCOA)
    FSRef fsRef;
    OSType folderType = aLocal ? (OSType) kCachedDataFolderType : (OSType) kDomainLibraryFolderType;
    OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
    if (err) return NS_ERROR_FAILURE;
    NS_NewLocalFile(EmptyString(), true, getter_AddRefs(localDir));
    if (!localDir) return NS_ERROR_FAILURE;
    nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir));
    rv = localDirMac->InitWithFSRef(&fsRef);
    if (NS_FAILED(rv)) return rv;
#elif defined(XP_OS2)
    nsCOMPtr<nsIProperties> directoryService = 
             do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv)) return rv;
    rv = directoryService->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsIFile), getter_AddRefs(localDir));
    if (NS_FAILED(rv)) return rv;
#elif defined(XP_WIN)
    nsCOMPtr<nsIProperties> directoryService = 
             do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv)) return rv;
    const char* prop = aLocal ? NS_WIN_LOCAL_APPDATA_DIR : NS_WIN_APPDATA_DIR;
    rv = directoryService->Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(localDir));
    if (NS_FAILED(rv)) return rv;
#elif defined(XP_UNIX)
    rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true, getter_AddRefs(localDir));
    if (NS_FAILED(rv)) return rv;
#else
#error dont_know_how_to_get_product_dir_on_your_platform
    rv = CloneMozBinDirectory(getter_AddRefs(localDir));
    NS_ENSURE_SUCCESS(rv, rv);

    int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory.
#if defined(XP_MACOSX)
    levelsToRemove += 2;
#endif
    while (localDir && (levelsToRemove > 0)) {
        // When crawling up the hierarchy, components named "." do not count.
        nsAutoCString removedName;
        rv = localDir->GetNativeLeafName(removedName);
        NS_ENSURE_SUCCESS(rv, rv);
        bool didRemove = !removedName.Equals(".");

        // Remove a directory component.
        nsCOMPtr<nsIFile> parentDir;
        rv = localDir->GetParent(getter_AddRefs(parentDir));
        NS_ENSURE_SUCCESS(rv, rv);
        localDir = parentDir;

        if (didRemove)
          --levelsToRemove;
    }

    if (!localDir)
        return NS_ERROR_FAILURE;

    rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
                                       XPCOM_FILE_PATH_SEPARATOR "Data"
                                       XPCOM_FILE_PATH_SEPARATOR "Browser"));
    NS_ENSURE_SUCCESS(rv, rv);

    if (aLocal) {
        rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches"));
        NS_ENSURE_SUCCESS(rv, rv);
    }

    rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
    if (NS_FAILED(rv)) return rv;
    rv = localDir->Exists(&exists);

    if (NS_SUCCEEDED(rv) && !exists)
@@ -345,10 +350,6 @@ NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, b

//----------------------------------------------------------------------------------------
// GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
//
// UNIX   : ~/.mozilla/
// WIN    : <Application Data folder on user's machine>\Mozilla\Profiles
// Mac    : :Documents:Mozilla:Profiles:
//----------------------------------------------------------------------------------------
NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile **aLocalFile, bool aLocal)
{
@@ -360,18 +361,6 @@ NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile **aLocalF
    rv = GetProductDirectory(getter_AddRefs(localDir), aLocal);
    if (NS_FAILED(rv)) return rv;

#if defined(MOZ_WIDGET_COCOA) || defined(XP_OS2) || defined(XP_WIN)
    // These 3 platforms share this part of the path - do them as one
    rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
    if (NS_FAILED(rv)) return rv;

    bool exists;
    rv = localDir->Exists(&exists);
    if (NS_SUCCEEDED(rv) && !exists)
        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
    if (NS_FAILED(rv)) return rv;
#endif

    *aLocalFile = localDir;
    NS_ADDREF(*aLocalFile);