/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is The Browser Profile Migrator. * * The Initial Developer of the Original Code is Ben Goodger. * Portions created by the Initial Developer are Copyright (C) 2004 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Ben Goodger * * 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 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsBrowserProfileMigratorUtils.h" #include "nsDirectoryServiceDefs.h" #include "nsIObserverService.h" #include "nsIPrefService.h" #include "nsIServiceManager.h" #include "nsISupportsArray.h" #include "nsISupportsPrimitives.h" #include "nsNetCID.h" #include "nsNetUtil.h" #include "nsPhoenixProfileMigrator.h" /////////////////////////////////////////////////////////////////////////////// // nsPhoenixProfileMigrator #define FILE_NAME_BOOKMARKS NS_LITERAL_STRING("bookmarks.html") #define FILE_NAME_COOKIES NS_LITERAL_STRING("cookies.txt") #define FILE_NAME_SITEPERM_OLD NS_LITERAL_STRING("cookperm.txt") #define FILE_NAME_SITEPERM_NEW NS_LITERAL_STRING("hostperm.1") #define FILE_NAME_CERT8DB NS_LITERAL_STRING("cert8.db") #define FILE_NAME_KEY3DB NS_LITERAL_STRING("key3.db") #define FILE_NAME_SECMODDB NS_LITERAL_STRING("secmod.db") #define FILE_NAME_HISTORY NS_LITERAL_STRING("history.dat") #define FILE_NAME_FORMHISTORY NS_LITERAL_STRING("formhistory.dat") #define FILE_NAME_LOCALSTORE NS_LITERAL_STRING("localstore.rdf") #define FILE_NAME_MIMETYPES NS_LITERAL_STRING("mimeTypes.rdf") #define FILE_NAME_DOWNLOADS NS_LITERAL_STRING("downloads.rdf") #define FILE_NAME_PREFS NS_LITERAL_STRING("prefs.js") #define FILE_NAME_USER_PREFS NS_LITERAL_STRING("user.js") #define FILE_NAME_USERCHROME NS_LITERAL_STRING("userChrome.css") #define FILE_NAME_USERCONTENT NS_LITERAL_STRING("userContent.css") #define DIR_NAME_CHROME NS_LITERAL_STRING("chrome") NS_IMPL_ISUPPORTS1(nsPhoenixProfileMigrator, nsIBrowserProfileMigrator) nsPhoenixProfileMigrator::nsPhoenixProfileMigrator() { mObserverService = do_GetService("@mozilla.org/observer-service;1"); } nsPhoenixProfileMigrator::~nsPhoenixProfileMigrator() { } /////////////////////////////////////////////////////////////////////////////// // nsIBrowserProfileMigrator NS_IMETHODIMP nsPhoenixProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile) { nsresult rv = NS_OK; // At this time the only reason for this migrator is to get data across from the // Phoenix profile directory on initial run, so we don't need to support after-the-fact // importing. NS_ASSERTION(aStartup, "Can't migrate from Phoenix/Firebird/Firefox profiles once Firefox is running!"); if (!aStartup) return NS_ERROR_FAILURE; if (!mTargetProfile) { GetProfilePath(aStartup, mTargetProfile); if (!mTargetProfile) return NS_ERROR_FAILURE; } if (!mSourceProfile) GetSourceProfile(aProfile); NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull); COPY_DATA(CopyPreferences, PR_TRUE, nsIBrowserProfileMigrator::SETTINGS); COPY_DATA(CopyCookies, PR_TRUE, nsIBrowserProfileMigrator::COOKIES); COPY_DATA(CopyHistory, PR_TRUE, nsIBrowserProfileMigrator::HISTORY); COPY_DATA(CopyPasswords, PR_TRUE, nsIBrowserProfileMigrator::PASSWORDS); COPY_DATA(CopyOtherData, PR_TRUE, nsIBrowserProfileMigrator::OTHERDATA); COPY_DATA(CopyBookmarks, PR_TRUE, nsIBrowserProfileMigrator::BOOKMARKS); if (aItems & nsIBrowserProfileMigrator::SETTINGS || aItems & nsIBrowserProfileMigrator::COOKIES || aItems & nsIBrowserProfileMigrator::PASSWORDS || !aItems) { // Permissions (Images, Cookies, Popups) rv |= CopyFile(FILE_NAME_SITEPERM_NEW, FILE_NAME_SITEPERM_NEW); rv |= CopyFile(FILE_NAME_SITEPERM_OLD, FILE_NAME_SITEPERM_OLD); } NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull); return rv; } NS_IMETHODIMP nsPhoenixProfileMigrator::GetMigrateData(const PRUnichar* aProfile, PRBool aReplace, PRUint16* aResult) { *aResult = 0; if (!mSourceProfile) { GetSourceProfile(aProfile); if (!mSourceProfile) return NS_ERROR_FILE_NOT_FOUND; } MigrationData data[] = { { ToNewUnicode(FILE_NAME_PREFS), nsIBrowserProfileMigrator::SETTINGS, PR_TRUE }, { ToNewUnicode(FILE_NAME_USER_PREFS), nsIBrowserProfileMigrator::SETTINGS, PR_TRUE }, { ToNewUnicode(FILE_NAME_COOKIES), nsIBrowserProfileMigrator::COOKIES, PR_TRUE }, { ToNewUnicode(FILE_NAME_HISTORY), nsIBrowserProfileMigrator::HISTORY, PR_TRUE }, { ToNewUnicode(FILE_NAME_BOOKMARKS), nsIBrowserProfileMigrator::BOOKMARKS, PR_TRUE }, { ToNewUnicode(FILE_NAME_DOWNLOADS), nsIBrowserProfileMigrator::OTHERDATA, PR_TRUE }, { ToNewUnicode(FILE_NAME_MIMETYPES), nsIBrowserProfileMigrator::OTHERDATA, PR_TRUE }, { ToNewUnicode(FILE_NAME_USERCHROME), nsIBrowserProfileMigrator::OTHERDATA, PR_TRUE }, { ToNewUnicode(FILE_NAME_USERCONTENT), nsIBrowserProfileMigrator::OTHERDATA, PR_TRUE }, { ToNewUnicode(FILE_NAME_FORMHISTORY), nsIBrowserProfileMigrator::OTHERDATA, PR_TRUE } }; // Frees file name strings allocated above. GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData), aReplace, mSourceProfile, aResult); // Now locate passwords nsCString signonsFileName; GetSignonFileName(aReplace, getter_Copies(signonsFileName)); if (!signonsFileName.IsEmpty()) { NS_ConvertASCIItoUTF16 fileName(signonsFileName); nsCOMPtr sourcePasswordsFile; mSourceProfile->Clone(getter_AddRefs(sourcePasswordsFile)); sourcePasswordsFile->Append(fileName); PRBool exists; sourcePasswordsFile->Exists(&exists); if (exists) *aResult |= nsIBrowserProfileMigrator::PASSWORDS; } return NS_OK; } NS_IMETHODIMP nsPhoenixProfileMigrator::GetSourceExists(PRBool* aResult) { nsCOMPtr profiles; GetSourceProfiles(getter_AddRefs(profiles)); if (profiles) { PRUint32 count; profiles->Count(&count); *aResult = count > 0; } else *aResult = PR_FALSE; return NS_OK; } NS_IMETHODIMP nsPhoenixProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult) { nsCOMPtr profiles; GetSourceProfiles(getter_AddRefs(profiles)); if (profiles) { PRUint32 count; profiles->Count(&count); *aResult = count > 1; } else *aResult = PR_FALSE; return NS_OK; } NS_IMETHODIMP nsPhoenixProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult) { if (!mProfileNames && !mProfileLocations) { mProfileNames = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID); mProfileLocations = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID); NS_ENSURE_TRUE(mProfileNames && mProfileLocations, NS_ERROR_UNEXPECTED); // Fills mProfileNames and mProfileLocations FillProfileDataFromPhoenixRegistry(); } NS_IF_ADDREF(*aResult = mProfileNames); return NS_OK; } NS_IMETHODIMP nsPhoenixProfileMigrator::GetSourceHomePageURL(nsACString& aResult) { aResult.Truncate(); return NS_OK; } /////////////////////////////////////////////////////////////////////////////// // nsPhoenixProfileMigrator nsresult nsPhoenixProfileMigrator::GetSourceProfile(const PRUnichar* aProfile) { PRUint32 count; mProfileNames->Count(&count); for (PRUint32 i = 0; i < count; ++i) { nsCOMPtr str; mProfileNames->QueryElementAt(i, NS_GET_IID(nsISupportsString), getter_AddRefs(str)); nsString profileName; str->GetData(profileName); if (profileName.Equals(aProfile)) { mProfileLocations->QueryElementAt(i, NS_GET_IID(nsILocalFile), getter_AddRefs(mSourceProfile)); break; } } return NS_OK; } nsresult nsPhoenixProfileMigrator::FillProfileDataFromPhoenixRegistry() { // Find the Phoenix Registry nsCOMPtr fileLocator(do_GetService("@mozilla.org/file/directory_service;1")); nsCOMPtr phoenixRegistry; #ifdef XP_WIN fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry)); phoenixRegistry->Append(NS_LITERAL_STRING("Phoenix")); phoenixRegistry->Append(NS_LITERAL_STRING("registry.dat")); #elif defined(XP_MACOSX) fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry)); phoenixRegistry->Append(NS_LITERAL_STRING("Phoenix")); phoenixRegistry->Append(NS_LITERAL_STRING("Application Registry")); #elif defined(XP_UNIX) fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry)); phoenixRegistry->Append(NS_LITERAL_STRING(".phoenix")); phoenixRegistry->Append(NS_LITERAL_STRING("appreg")); #elif defined(XP_BEOS) fileLocator->Get(NS_BEOS_SETTINGS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry)); phoenixRegistry->Append(NS_LITERAL_STRING("Phoenix")); phoenixRegistry->Append(NS_LITERAL_STRING("appreg")); #elif defined(XP_OS2) fileLocator->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry)); phoenixRegistry->Append(NS_LITERAL_STRING("Phoenix")); phoenixRegistry->Append(NS_LITERAL_STRING("registry.dat")); #endif return GetProfileDataFromRegistry(phoenixRegistry, mProfileNames, mProfileLocations); } nsresult nsPhoenixProfileMigrator::CopyPreferences(PRBool aReplace) { nsresult rv = NS_OK; if (!aReplace) return rv; // Prefs files rv |= CopyFile(FILE_NAME_PREFS, FILE_NAME_PREFS); rv |= CopyFile(FILE_NAME_USER_PREFS, FILE_NAME_USER_PREFS); // Security Stuff rv |= CopyFile(FILE_NAME_CERT8DB, FILE_NAME_CERT8DB); rv |= CopyFile(FILE_NAME_KEY3DB, FILE_NAME_KEY3DB); rv |= CopyFile(FILE_NAME_SECMODDB, FILE_NAME_SECMODDB); // User MIME Type overrides rv |= CopyFile(FILE_NAME_MIMETYPES, FILE_NAME_MIMETYPES); rv |= CopyUserStyleSheets(); return rv; } nsresult nsPhoenixProfileMigrator::CopyUserStyleSheets() { nsresult rv = NS_OK; nsCOMPtr sourceUserContent; mSourceProfile->Clone(getter_AddRefs(sourceUserContent)); sourceUserContent->Append(DIR_NAME_CHROME); sourceUserContent->Append(FILE_NAME_USERCONTENT); PRBool exists = PR_FALSE; sourceUserContent->Exists(&exists); if (exists) { nsCOMPtr targetUserContent; mTargetProfile->Clone(getter_AddRefs(targetUserContent)); targetUserContent->Append(DIR_NAME_CHROME); nsCOMPtr targetChromeDir; targetUserContent->Clone(getter_AddRefs(targetChromeDir)); targetUserContent->Append(FILE_NAME_USERCONTENT); targetUserContent->Exists(&exists); if (exists) targetUserContent->Remove(PR_FALSE); rv |= sourceUserContent->CopyTo(targetChromeDir, FILE_NAME_USERCONTENT); } nsCOMPtr sourceUserChrome; mSourceProfile->Clone(getter_AddRefs(sourceUserChrome)); sourceUserChrome->Append(DIR_NAME_CHROME); sourceUserChrome->Append(FILE_NAME_USERCHROME); sourceUserChrome->Exists(&exists); if (exists) { nsCOMPtr targetUserChrome; mTargetProfile->Clone(getter_AddRefs(targetUserChrome)); targetUserChrome->Append(DIR_NAME_CHROME); nsCOMPtr targetChromeDir; targetUserChrome->Clone(getter_AddRefs(targetChromeDir)); targetUserChrome->Append(FILE_NAME_USERCHROME); targetUserChrome->Exists(&exists); if (exists) targetUserChrome->Remove(PR_FALSE); rv |= sourceUserChrome->CopyTo(targetChromeDir, FILE_NAME_USERCHROME); } return rv; } nsresult nsPhoenixProfileMigrator::CopyCookies(PRBool aReplace) { return aReplace ? CopyFile(FILE_NAME_COOKIES, FILE_NAME_COOKIES) : NS_OK; } nsresult nsPhoenixProfileMigrator::CopyHistory(PRBool aReplace) { return aReplace ? CopyFile(FILE_NAME_HISTORY, FILE_NAME_HISTORY) : NS_OK; } nsresult nsPhoenixProfileMigrator::CopyPasswords(PRBool aReplace) { nsresult rv; nsCString signonsFileName; if (!aReplace) return NS_OK; // Find out what the signons file was called, this is stored in a pref // in Seamonkey. nsCOMPtr psvc(do_GetService(NS_PREFSERVICE_CONTRACTID)); psvc->ResetPrefs(); nsCOMPtr seamonkeyPrefsFile; mSourceProfile->Clone(getter_AddRefs(seamonkeyPrefsFile)); seamonkeyPrefsFile->Append(FILE_NAME_PREFS); psvc->ReadUserPrefs(seamonkeyPrefsFile); nsCOMPtr branch(do_QueryInterface(psvc)); rv = branch->GetCharPref("signon.SignonFileName", getter_Copies(signonsFileName)); if (signonsFileName.IsEmpty()) return NS_ERROR_FILE_NOT_FOUND; NS_ConvertASCIItoUTF16 fileName(signonsFileName); return aReplace ? CopyFile(fileName, fileName) : NS_OK; } nsresult nsPhoenixProfileMigrator::CopyBookmarks(PRBool aReplace) { // This overwrites the defaults. This might be ok in this instance. return aReplace ? CopyFile(FILE_NAME_BOOKMARKS, FILE_NAME_BOOKMARKS) : NS_OK; } nsresult nsPhoenixProfileMigrator::CopyOtherData(PRBool aReplace) { if (!aReplace) return NS_OK; nsresult rv = NS_OK; rv |= CopyFile(FILE_NAME_DOWNLOADS, FILE_NAME_DOWNLOADS); rv |= CopyFile(FILE_NAME_LOCALSTORE, FILE_NAME_LOCALSTORE); rv |= CopyFile(FILE_NAME_FORMHISTORY, FILE_NAME_FORMHISTORY); return rv; }