зеркало из https://github.com/mozilla/pjs.git
bug 323780. Make Camino portable. By setting CAMINO_PROFILE_DIR to a custom path, you can 1) Run more than 1 Camino simultaneously 2) Have a profile that can be moved to other computers. r=mento, sr=pinkerton
This commit is contained in:
Родитель
75a71d5d88
Коммит
8b81319248
|
@ -185,9 +185,7 @@
|
|||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>mozNewProfileDirName</key>
|
||||
<key>mozProfileDirName</key>
|
||||
<string>Camino</string>
|
||||
<key>mozOldProfileDirName</key>
|
||||
<string>Chimera</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -185,9 +185,7 @@
|
|||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>mozNewProfileDirName</key>
|
||||
<key>mozProfileDirName</key>
|
||||
<string>Camino</string>
|
||||
<key>mozOldProfileDirName</key>
|
||||
<string>Chimera</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Conrad Carlen <ccarlen@netscape.com>
|
||||
* Hakan Waara <hwaara@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -43,114 +44,148 @@
|
|||
#include <Carbon/Carbon.h>
|
||||
|
||||
// Defines
|
||||
#define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application.regs")
|
||||
|
||||
#define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application.regs")
|
||||
|
||||
//*****************************************************************************
|
||||
// AppDirServiceProvider::Constructor/Destructor
|
||||
//*****************************************************************************
|
||||
|
||||
AppDirServiceProvider::AppDirServiceProvider(const nsACString& productDirName)
|
||||
AppDirServiceProvider::AppDirServiceProvider(const char *inName, PRBool isCustomProfile)
|
||||
{
|
||||
mProductDirName.Assign(productDirName);
|
||||
mIsCustomProfile = isCustomProfile;
|
||||
mName.Assign(inName);
|
||||
}
|
||||
|
||||
AppDirServiceProvider::~AppDirServiceProvider()
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// AppDirServiceProvider::nsISupports
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_ISUPPORTS1(AppDirServiceProvider, nsIDirectoryServiceProvider)
|
||||
|
||||
//*****************************************************************************
|
||||
// AppDirServiceProvider::nsIDirectoryServiceProvider
|
||||
//*****************************************************************************
|
||||
|
||||
// nsIDirectoryServiceProvider implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
AppDirServiceProvider::GetFile(const char *prop, PRBool *persistent, nsIFile **_retval)
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> localFile;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
nsCAutoString strBuf;
|
||||
|
||||
*_retval = nsnull;
|
||||
*persistent = PR_TRUE;
|
||||
|
||||
if (strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
|
||||
if (strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0 ||
|
||||
strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
|
||||
{
|
||||
rv = GetProductDirectory(getter_AddRefs(localFile));
|
||||
rv = GetProfileDirectory(getter_AddRefs(localFile));
|
||||
}
|
||||
else if (strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
|
||||
{
|
||||
rv = GetProductDirectory(getter_AddRefs(localFile));
|
||||
rv = GetProfileDirectory(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = localFile->AppendNative(APP_REGISTRY_NAME);
|
||||
}
|
||||
else if (strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
|
||||
{
|
||||
rv = GetProductDirectory(getter_AddRefs(localFile));
|
||||
}
|
||||
else if (strcmp(prop, NS_APP_CACHE_PARENT_DIR) == 0)
|
||||
{
|
||||
rv = GetCacheDirectory(getter_AddRefs(localFile));
|
||||
rv = GetParentCacheDirectory(getter_AddRefs(localFile));
|
||||
}
|
||||
|
||||
|
||||
if (localFile && NS_SUCCEEDED(rv))
|
||||
return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// AppDirServiceProvider::AppDirServiceProvider
|
||||
//*****************************************************************************
|
||||
|
||||
NS_METHOD
|
||||
AppDirServiceProvider::GetProductDirectory(nsILocalFile **outLocalFile)
|
||||
{
|
||||
return EnsureFolder(kApplicationSupportFolderType, outLocalFile);
|
||||
}
|
||||
// Protected methods
|
||||
|
||||
nsresult
|
||||
AppDirServiceProvider::GetCacheDirectory(nsILocalFile** outCacheFolder)
|
||||
{
|
||||
return EnsureFolder(kCachedDataFolderType, outCacheFolder);
|
||||
}
|
||||
|
||||
nsresult
|
||||
AppDirServiceProvider::EnsureFolder(OSType inFolderType, nsILocalFile** outFolder)
|
||||
AppDirServiceProvider::GetProfileDirectory(nsILocalFile** outFolder)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(outFolder);
|
||||
*outFolder = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsresult rv;
|
||||
FSRef foundRef;
|
||||
// Init and cache the profile directory; we'll get queried for it a lot of times.
|
||||
if (!mProfileDir)
|
||||
{
|
||||
if (mIsCustomProfile)
|
||||
{
|
||||
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(mName), PR_FALSE, getter_AddRefs(mProfileDir));
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_WARNING ("Couldn't use the specified custom path!");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this is not a custom profile path, we have a product name, and we'll use
|
||||
// Application Support/<mName> as our profile dir.
|
||||
rv = GetSystemDirectory(kApplicationSupportFolderType, getter_AddRefs(mProfileDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// if it's not a custom profile, mName is our product name.
|
||||
mProfileDir->AppendNative(mName);
|
||||
}
|
||||
|
||||
rv = EnsureExists(mProfileDir);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} // end lazy init
|
||||
|
||||
nsCOMPtr<nsIFile> profileDir;
|
||||
rv = mProfileDir->Clone(getter_AddRefs(profileDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(profileDir, outFolder);
|
||||
}
|
||||
|
||||
nsresult
|
||||
AppDirServiceProvider::GetSystemDirectory(OSType inFolderType, nsILocalFile** outFolder)
|
||||
{
|
||||
FSRef foundRef;
|
||||
*outFolder = nsnull;
|
||||
|
||||
OSErr err = ::FSFindFolder(kUserDomain, inFolderType, kCreateFolder, &foundRef);
|
||||
if (err != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsILocalFileMac> localDir(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
|
||||
if (!localDir)
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> macFolder = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
||||
if (!macFolder)
|
||||
return NS_ERROR_FAILURE;
|
||||
rv = localDir->InitWithFSRef(&foundRef);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = localDir->AppendNative(mProductDirName);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsresult rv = macFolder->InitWithFSRef(&foundRef);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*outFolder = macFolder);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Gets the parent directory to the Cache folder.
|
||||
nsresult
|
||||
AppDirServiceProvider::GetParentCacheDirectory(nsILocalFile** outFolder)
|
||||
{
|
||||
*outFolder = nsnull;
|
||||
|
||||
if (mIsCustomProfile)
|
||||
return GetProfileDirectory(outFolder);
|
||||
|
||||
// we don't have a custom profile path, so use Caches/<product name>
|
||||
nsresult rv = GetSystemDirectory(kCachedDataFolderType, outFolder);
|
||||
if (NS_FAILED(rv) || !(*outFolder))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
(*outFolder)->AppendNative(mName);
|
||||
rv = EnsureExists(*outFolder);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
AppDirServiceProvider::EnsureExists(nsILocalFile* inFolder)
|
||||
{
|
||||
PRBool exists;
|
||||
rv = localDir->Exists(&exists);
|
||||
nsresult rv = inFolder->Exists(&exists);
|
||||
if (NS_SUCCEEDED(rv) && !exists)
|
||||
rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*outFolder = localDir;
|
||||
NS_ADDREF(*outFolder);
|
||||
|
||||
return rv;
|
||||
}
|
||||
rv = inFolder->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,19 +54,29 @@ class nsIFile;
|
|||
class AppDirServiceProvider : public nsIDirectoryServiceProvider
|
||||
{
|
||||
public:
|
||||
AppDirServiceProvider(const nsACString& productDirName);
|
||||
// If |isCustomProfile| is true, we use the passed in string as a path to the custom
|
||||
// profile. If it is false, the string is the product name, which will be used for the
|
||||
// Application Support/<name> folder, as well as the Caches/<name> system folder.
|
||||
AppDirServiceProvider(const char *inProductName, PRBool isCustomProfile);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
||||
|
||||
protected:
|
||||
virtual ~AppDirServiceProvider();
|
||||
virtual ~AppDirServiceProvider();
|
||||
|
||||
NS_METHOD GetProductDirectory(nsILocalFile **aLocalFile);
|
||||
nsresult GetCacheDirectory(nsILocalFile** outCacheFolder);
|
||||
nsresult EnsureFolder(OSType inFolderType, nsILocalFile** outFolder);
|
||||
|
||||
nsCString mProductDirName;
|
||||
nsresult GetProfileDirectory(nsILocalFile **outFolder);
|
||||
nsresult GetParentCacheDirectory(nsILocalFile** outFolder);
|
||||
|
||||
nsresult GetSystemDirectory(OSType inFolderType, nsILocalFile** outFolder);
|
||||
static nsresult AppDirServiceProvider::EnsureExists(nsILocalFile* inFolder);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsILocalFile> mProfileDir;
|
||||
PRBool mIsCustomProfile;
|
||||
|
||||
// this is either the product name (e.g., "Camino") or a path, depending on mIsCustomPath
|
||||
nsCString mName;
|
||||
};
|
||||
|
||||
#endif // __AppDirServiceProvider_h__
|
||||
|
|
|
@ -225,12 +225,6 @@ const int kReuseWindowOnAE = 2;
|
|||
{
|
||||
[self ensureGeckoInitted];
|
||||
|
||||
// previous versions would keep the cache in the profile folder. If we find it there, remove it so
|
||||
// that backup apps can more easily back up our profile. This will mean if anyone goes back to
|
||||
// 0.8.x, they'll lose their favicons and cache, but that's ok.
|
||||
NSString* cacheDir = [[[PreferenceManager sharedInstance] newProfilePath] stringByAppendingPathComponent:@"Cache"];
|
||||
[[NSFileManager defaultManager] removeFileAtPath:cacheDir handler:nil];
|
||||
|
||||
NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
// turn on menu display notifications
|
||||
[NSMenu setupMenuWillDisplayNotifications];
|
||||
|
|
|
@ -1193,7 +1193,7 @@ static BookmarkManager* gBookmarkManager = nil;
|
|||
//
|
||||
- (BOOL)readBookmarks
|
||||
{
|
||||
NSString *profileDir = [[PreferenceManager sharedInstance] newProfilePath];
|
||||
NSString *profileDir = [[PreferenceManager sharedInstance] profilePath];
|
||||
|
||||
//
|
||||
// figure out where Bookmarks.plist is and store it as mPathToBookmarkFile
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#import "NSString+Utils.h"
|
||||
#import "NSFileManager+Utils.h"
|
||||
#import "PreferenceManager.h"
|
||||
|
||||
#import "SiteIconCache.h"
|
||||
|
||||
|
@ -152,12 +153,13 @@ static NSString* const kCacheEntryExpirationDateKey = @"exp_date";
|
|||
if (!imageSaved)
|
||||
NSLog(@"Failed to archive image for %@ to file", inURL);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString*)cacheDirectory
|
||||
{
|
||||
return [@"~/Library/Caches/Camino/IconCache" stringByStandardizingPath];
|
||||
return [[[PreferenceManager sharedInstance] cacheParentDirPath] stringByAppendingPathComponent:@"IconCache"];
|
||||
}
|
||||
|
||||
- (NSString*)imageDataFileWithUUID:(NSString*)inUUID
|
||||
|
|
|
@ -780,13 +780,13 @@ static id gSharedProgressController = nil;
|
|||
}
|
||||
|
||||
// now save
|
||||
NSString *profileDir = [[PreferenceManager sharedInstance] newProfilePath];
|
||||
NSString *profileDir = [[PreferenceManager sharedInstance] profilePath];
|
||||
[downloadArray writeToFile: [profileDir stringByAppendingPathComponent:@"downloads.plist"] atomically: YES];
|
||||
}
|
||||
|
||||
-(void)loadProgressViewControllers
|
||||
{
|
||||
NSString* downloadsPath = [[[PreferenceManager sharedInstance] newProfilePath] stringByAppendingPathComponent:@"downloads.plist"];
|
||||
NSString* downloadsPath = [[[PreferenceManager sharedInstance] profilePath] stringByAppendingPathComponent:@"downloads.plist"];
|
||||
NSArray* downloads = [NSArray arrayWithContentsOfFile:downloadsPath];
|
||||
|
||||
if (downloads)
|
||||
|
|
|
@ -1757,12 +1757,11 @@ nsSimpleGlobalHistory::OpenDB()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool exists = PR_TRUE;
|
||||
|
||||
historyFile->Exists(&exists);
|
||||
|
||||
if (!exists || NS_FAILED(rv = OpenExistingFile(gMdbFactory, filePath.get())))
|
||||
if (exists && NS_FAILED(rv = OpenExistingFile(gMdbFactory, filePath.get())))
|
||||
{
|
||||
// we couldn't open the file, so it's either corrupt or doesn't exist.
|
||||
// we couldn't open the file, so it might be corrupt.
|
||||
// attempt to delete the file, but ignore the error
|
||||
NS_ASSERTION(0, "Failed to open history.dat file");
|
||||
#if DEBUG
|
||||
|
@ -1776,8 +1775,12 @@ nsSimpleGlobalHistory::OpenDB()
|
|||
#else
|
||||
historyFile->Remove(PR_FALSE);
|
||||
#endif
|
||||
// generate a new history file.
|
||||
exists = PR_FALSE;
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
rv = OpenNewFile(gMdbFactory, filePath.get());
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#import "MVPreferencesController.h"
|
||||
#import "ToolbarAdditions.h"
|
||||
#import "PreferenceManager.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
@ -124,8 +125,8 @@ static NSString* const CacheInfoPaneSeenKey = @"MVPreferencePaneSeen"; // N
|
|||
[self loadPreferencePanesAtPath:paneBundlesPath];
|
||||
|
||||
// this matches code in -initMozillaPrefs
|
||||
NSString* profileDirName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"mozNewProfileDirName"];
|
||||
NSString* prefPanesSubpath = [profileDirName stringByAppendingPathComponent:@"PreferencePanes"];
|
||||
NSString* profilePath = [[PreferenceManager sharedInstance] profilePath];
|
||||
NSString* prefPanesSubpath = [profilePath stringByAppendingPathComponent:@"PreferencePanes"];
|
||||
|
||||
NSString* userLibPath = [MVPreferencesController applicationSupportPathForDomain:kUserDomain];
|
||||
if (userLibPath)
|
||||
|
|
|
@ -55,6 +55,7 @@ extern NSString* const kPrefChangedNotificationName;
|
|||
NSMutableDictionary* mPrefChangeObservers; // dict of NSMutableArray of PrefChangeObserverOwner, keyed by pref name.
|
||||
|
||||
long mLastRunPrefsVersion;
|
||||
NSString* mProfilePath;
|
||||
|
||||
// proxies notification stuff
|
||||
CFRunLoopSourceRef mRunLoopSource;
|
||||
|
@ -80,7 +81,7 @@ extern NSString* const kPrefChangedNotificationName;
|
|||
- (void)setPref:(const char*)prefName toBoolean:(BOOL)value;
|
||||
|
||||
// the path to the user profile's root folder, used by camino 0.8+
|
||||
- (NSString*) newProfilePath;
|
||||
- (NSString*) profilePath;
|
||||
|
||||
// turn notifications on and off when the given pref changes.
|
||||
// if not nil, inObject is used at the 'object' of the resulting notification.
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#import "NSString+Utils.h"
|
||||
|
||||
#import "PreferenceManager.h"
|
||||
#import "AppDirServiceProvider.h"
|
||||
#import "UserDefaults.h"
|
||||
#import "CHBrowserService.h"
|
||||
#import "CHISupportsOwner.h"
|
||||
|
@ -56,7 +57,6 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsEmbedAPI.h"
|
||||
#include "AppDirServiceProvider.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsIRegistry.h"
|
||||
#include "nsIStyleSheetService.h"
|
||||
|
@ -68,6 +68,8 @@ nsStaticModuleInfo const *const kPStaticModules = nsnull;
|
|||
PRUint32 const kStaticModuleCount = 0;
|
||||
#endif
|
||||
|
||||
#define CUSTOM_PROFILE_DIR "CAMINO_PROFILE_DIR"
|
||||
|
||||
NSString* const kPrefChangedNotificationName = @"PrefChangedNotification";
|
||||
// userInfo entries:
|
||||
NSString* const kPrefChangedPrefNameUserInfoKey = @"pref_name";
|
||||
|
@ -102,9 +104,6 @@ static const PRInt32 kCurrentPrefsVersion = 1;
|
|||
- (void)termEmbedding: (NSNotification*)aNotification;
|
||||
- (void)xpcomTerminate: (NSNotification*)aNotification;
|
||||
|
||||
- (NSString*)oldProfilePath;
|
||||
- (void)migrateChimeraProfile:(NSString*)newProfilePath;
|
||||
|
||||
- (void)showLaunchFailureAndQuitWithErrorTitle:(NSString*)inTitleFormat errorMessage:(NSString*)inMessageFormat;
|
||||
|
||||
- (void)configureProxies;
|
||||
|
@ -286,6 +285,7 @@ static BOOL gMadePrefManager;
|
|||
if (self == gSharedInstance)
|
||||
gSharedInstance = nil;
|
||||
|
||||
[mProfilePath release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -376,21 +376,40 @@ static BOOL gMadePrefManager;
|
|||
// This shouldn't be needed since we are initing XPCOM with this
|
||||
// directory but causes a (harmless) warning if not defined.
|
||||
setenv("MOZILLA_FIVE_HOME", binDirPath, 1);
|
||||
|
||||
// get the 'mozNewProfileDirName' key from our Info.plist file
|
||||
NSString *dirString = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"mozNewProfileDirName"];
|
||||
const char* profileDirName;
|
||||
if (dirString)
|
||||
profileDirName = [dirString UTF8String];
|
||||
else {
|
||||
NSLog(@"mozNewProfileDirName key missing from Info.plist file. Using default profile directory");
|
||||
profileDirName = "Camino";
|
||||
|
||||
const char* profileDirectory;
|
||||
const char* customProfilePath = getenv(CUSTOM_PROFILE_DIR);
|
||||
BOOL isCustomProfile = NO;
|
||||
|
||||
// Based on whether $CAMINO_PROFILE_DIR is set, figure out what the
|
||||
// profile path should be.
|
||||
if (!customProfilePath)
|
||||
{
|
||||
// If it isn't, we then check the 'mozProfileDirName' key in our Info.plist file
|
||||
// and use the regular Application Support/<mozProfileDirName>, and Caches/<mozProfileDirName>
|
||||
// folders.
|
||||
NSString *dirString = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"mozProfileDirName"];
|
||||
if (dirString)
|
||||
profileDirectory = [dirString UTF8String];
|
||||
else
|
||||
{
|
||||
NSLog(@"mozNewProfileDirName key missing from Info.plist file. Using default profile directory");
|
||||
profileDirectory = "Camino";
|
||||
}
|
||||
isCustomProfile = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we have a custom profile path, let's just use that.
|
||||
profileDirectory = customProfilePath;
|
||||
isCustomProfile = YES;
|
||||
}
|
||||
|
||||
// Supply our own directory service provider so we can control where
|
||||
// the registry and profiles are located.
|
||||
AppDirServiceProvider *provider = new AppDirServiceProvider(nsDependentCString(profileDirName));
|
||||
if (!provider)
|
||||
AppDirServiceProvider *provider = new AppDirServiceProvider(profileDirectory, isCustomProfile);
|
||||
|
||||
if (!provider)
|
||||
{
|
||||
[self showLaunchFailureAndQuitWithErrorTitle:NSLocalizedString(@"StartupFailureAlert", @"")
|
||||
errorMessage:NSLocalizedString(@"StartupFailureMsg", @"")];
|
||||
|
@ -409,7 +428,7 @@ static BOOL gMadePrefManager;
|
|||
return NO;
|
||||
}
|
||||
|
||||
NSString* profilePath = [self newProfilePath];
|
||||
NSString* profilePath = [self profilePath];
|
||||
if (!profilePath) {
|
||||
NSLog(@"Failed to determine profile path!");
|
||||
[self showLaunchFailureAndQuitWithErrorTitle:NSLocalizedString(@"StartupFailureAlert", @"")
|
||||
|
@ -418,13 +437,6 @@ static BOOL gMadePrefManager;
|
|||
return NO;
|
||||
}
|
||||
|
||||
// Check for the existence of prefs.js in our new (as of 0.8) profile dir.
|
||||
// If it doesn't exist, attempt to migrate over the contents of the old
|
||||
// one at ~/Library/Application Support/Chimera/Profiles/default/xxxxxxxx.slt/
|
||||
NSFileManager *fileMgr = [NSFileManager defaultManager];
|
||||
if (![fileMgr fileExistsAtPath:[profilePath stringByAppendingPathComponent:@"prefs.js"]])
|
||||
[self migrateChimeraProfile:profilePath];
|
||||
|
||||
rv = NS_NewProfileDirServiceProvider(PR_TRUE, &mProfileProvider);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
|
@ -803,7 +815,7 @@ typedef enum EProxyConfig {
|
|||
// returns YES if there was a userContent.css in the chrome dir.
|
||||
- (BOOL)cleanupUserContentCSS
|
||||
{
|
||||
NSString* profilePath = [self newProfilePath];
|
||||
NSString* profilePath = [self profilePath];
|
||||
NSString* chromeDirPath = [profilePath stringByAppendingPathComponent:@"chrome"];
|
||||
NSString* userContentCSSPath = [chromeDirPath stringByAppendingPathComponent:@"userContent.css"];
|
||||
|
||||
|
@ -1023,174 +1035,47 @@ typedef enum EProxyConfig {
|
|||
}
|
||||
|
||||
//
|
||||
// -oldProfilePath
|
||||
// -profilePath
|
||||
//
|
||||
// Find the path to the pre-0.8 profile folder using the old registry. It will be
|
||||
// along the lines of ~/Library/Application Support/Chimera/profiles/default/xxxxx.slt/
|
||||
// Returns |nil| if there are any problems finding the path.
|
||||
//
|
||||
- (NSString *) oldProfilePath
|
||||
{
|
||||
#define kRegistryProfileSubtreeString (NS_LITERAL_STRING("Profiles"))
|
||||
#define kRegistryCurrentProfileString (NS_LITERAL_STRING("CurrentProfile"))
|
||||
#define kRegistryDirectoryString (NS_LITERAL_STRING("directory"))
|
||||
|
||||
NSString *resultPath = nil;
|
||||
|
||||
// The old registry file is at ~/Library/Application Support/Chimera/Application.regs
|
||||
FSRef foundRef;
|
||||
OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType,
|
||||
kCreateFolder, &foundRef);
|
||||
if (err != noErr)
|
||||
return nil;
|
||||
|
||||
UInt8 pathBuf[PATH_MAX];
|
||||
err = FSRefMakePath(&foundRef, pathBuf, sizeof(pathBuf));
|
||||
if (err != noErr)
|
||||
return nil;
|
||||
|
||||
NSString *oldDirName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"mozOldProfileDirName"];
|
||||
if (!oldDirName) {
|
||||
NSLog(@"mozNewProfileDirName key missing from Info.plist file - using default");
|
||||
oldDirName = @"Chimera";
|
||||
}
|
||||
NSString *registryPath = [[[NSString stringWithUTF8String:(char*)pathBuf]
|
||||
stringByAppendingPathComponent:oldDirName]
|
||||
stringByAppendingPathComponent:@"Application.regs"];
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsILocalFile> registryFile;
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString([registryPath fileSystemRepresentation]),
|
||||
PR_TRUE, getter_AddRefs(registryFile));
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
nsCOMPtr<nsIRegistry> registry = do_CreateInstance(NS_REGISTRY_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
rv = registry->Open(registryFile);
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
|
||||
nsRegistryKey profilesTreeKey;
|
||||
rv = registry->GetKey(nsIRegistry::Common,
|
||||
kRegistryProfileSubtreeString.get(),
|
||||
&profilesTreeKey);
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
|
||||
// Get the current profile
|
||||
nsXPIDLString currProfileName;
|
||||
rv = registry->GetString(profilesTreeKey,
|
||||
kRegistryCurrentProfileString.get(),
|
||||
getter_Copies(currProfileName));
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
|
||||
nsRegistryKey currProfileKey;
|
||||
rv = registry->GetKey(profilesTreeKey,
|
||||
currProfileName.get(),
|
||||
&currProfileKey);
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
|
||||
nsXPIDLString profDirDesc;
|
||||
rv = registry->GetString(currProfileKey,
|
||||
kRegistryDirectoryString.get(),
|
||||
getter_Copies(profDirDesc));
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
|
||||
nsCOMPtr<nsILocalFile> profDirFile;
|
||||
rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(profDirFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// profDirDesc is ASCII so no loss
|
||||
rv = profDirFile->SetPersistentDescriptor(NS_LossyConvertUTF16toASCII(profDirDesc));
|
||||
PRBool exists;
|
||||
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(profDirFile->Exists(&exists)) && exists) {
|
||||
nsCAutoString nativePath;
|
||||
profDirFile->GetNativePath(nativePath);
|
||||
resultPath = [NSString stringWithUTF8String:nativePath.get()];
|
||||
|
||||
// If the descriptor, which is an alias, is broken, this would be the place to
|
||||
// do some exhaustive alias searching, prompt the user, etc.
|
||||
}
|
||||
}
|
||||
return resultPath;
|
||||
}
|
||||
|
||||
//
|
||||
// -newProfilePath
|
||||
//
|
||||
// Returns the path for our post 0.8 profiles stored in Application Support/Camino.
|
||||
// Returns the path for our post 0.8 profiles.
|
||||
// We no longer have distinct profiles. The profile dir is the same as
|
||||
// NS_APP_USER_PROFILES_ROOT_DIR - imposed by our own AppDirServiceProvider. Will
|
||||
// return |nil| if there is a problem.
|
||||
//
|
||||
- (NSString*) newProfilePath
|
||||
- (NSString*) profilePath
|
||||
{
|
||||
nsCOMPtr<nsIFile> appSupportDir;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILES_ROOT_DIR,
|
||||
getter_AddRefs(appSupportDir));
|
||||
if (!mProfilePath)
|
||||
{
|
||||
nsCOMPtr<nsIFile> profileDir;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILES_ROOT_DIR,
|
||||
getter_AddRefs(profileDir));
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
nsCAutoString nativePath;
|
||||
rv = profileDir->GetNativePath(nativePath);
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
mProfilePath = [NSString stringWithUTF8String:nativePath.get()];
|
||||
[mProfilePath retain];
|
||||
}
|
||||
|
||||
return mProfilePath;
|
||||
}
|
||||
|
||||
- (NSString*) cacheParentDirPath
|
||||
{
|
||||
nsCOMPtr<nsIFile> cacheParentDir;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_CACHE_PARENT_DIR,
|
||||
getter_AddRefs(cacheParentDir));
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
nsCAutoString nativePath;
|
||||
rv = appSupportDir->GetNativePath(nativePath);
|
||||
rv = cacheParentDir->GetNativePath(nativePath);
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
return [NSString stringWithUTF8String:nativePath.get()];
|
||||
}
|
||||
|
||||
//
|
||||
// -migrateChimeraProfile:
|
||||
//
|
||||
// Takes the old profile and copies out the pertinent info into the new profile
|
||||
// given by the path in |newProfilePath|. Copies everything except the cache dir.
|
||||
//
|
||||
- (void)migrateChimeraProfile:(NSString*)newProfilePath;
|
||||
{
|
||||
NSFileManager *fileMgr = [NSFileManager defaultManager];
|
||||
NSString *oldProfilePath = [self oldProfilePath];
|
||||
if (!oldProfilePath)
|
||||
return;
|
||||
|
||||
BOOL exists, isDir;
|
||||
exists = [fileMgr fileExistsAtPath:oldProfilePath isDirectory:&isDir];
|
||||
if (!exists || !isDir)
|
||||
return;
|
||||
|
||||
// The parent of the terminal node in the dest path given to copyPath has to exist already.
|
||||
exists = [fileMgr fileExistsAtPath:newProfilePath isDirectory:&isDir];
|
||||
if (exists && !isDir) {
|
||||
NSLog(@"Can't migrate profile to %@: there's a file in the way", newProfilePath);
|
||||
return;
|
||||
}
|
||||
else if (!exists) {
|
||||
NSLog(@"%@ should exist if [self newProfilePath] has been called", newProfilePath);
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray *profileContents = [fileMgr directoryContentsAtPath:oldProfilePath];
|
||||
NSEnumerator *enumerator = [profileContents objectEnumerator];
|
||||
id anItem;
|
||||
|
||||
// loop over the contents of the profile copying everything except for invisible
|
||||
// files and the cache
|
||||
while ((anItem = [enumerator nextObject])) {
|
||||
NSString *sourcePath = [oldProfilePath stringByAppendingPathComponent:anItem];
|
||||
NSString *destPath = [newProfilePath stringByAppendingPathComponent:anItem];
|
||||
// Ensure that the file exists
|
||||
if ([fileMgr fileExistsAtPath:sourcePath isDirectory:&isDir]) {
|
||||
// That it's not invisible (.parentlock, .DS_Store)
|
||||
if ([anItem hasPrefix:@"."] == NO) {
|
||||
// That it's not the Cache or Cache.Trash dir
|
||||
if (!isDir || ![anItem hasPrefix:@"Cache"])
|
||||
[fileMgr copyPath:sourcePath toPath:destPath handler:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)addObserver:(id)inObject forPref:(const char*)inPrefName
|
||||
{
|
||||
if (!mPrefChangeObservers)
|
||||
|
|
Загрузка…
Ссылка в новой задаче