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:
hwaara%gmail.com 2006-03-26 15:43:17 +00:00
Родитель 75a71d5d88
Коммит 8b81319248
12 изменённых файлов: 197 добавлений и 270 удалений

Просмотреть файл

@ -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)