summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-26 17:58:24 +0000
committerkuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-26 17:58:24 +0000
commit4a63ae1381005ba988ca6f49a6c9256ab634db12 (patch)
treea6724dec3bc9c24646e2e296d9cda8f4977b5358 /chrome
parentb6e97b66c5777bbd1c5fef47a77247f6a3fb319e (diff)
downloadchromium_src-4a63ae1381005ba988ca6f49a6c9256ab634db12.zip
chromium_src-4a63ae1381005ba988ca6f49a6c9256ab634db12.tar.gz
chromium_src-4a63ae1381005ba988ca6f49a6c9256ab634db12.tar.bz2
Enable Firefox import on OS X. No UI yet.
Review URL: http://codereview.chromium.org/143001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19381 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/importer/firefox_importer_utils.cc191
-rw-r--r--chrome/browser/importer/firefox_importer_utils.h7
-rw-r--r--chrome/browser/importer/firefox_importer_utils_linux.cc39
-rw-r--r--chrome/browser/importer/firefox_importer_utils_mac.cc37
-rw-r--r--chrome/browser/importer/firefox_importer_utils_win.cc155
-rw-r--r--chrome/browser/importer/firefox_profile_lock.cc11
-rw-r--r--chrome/browser/importer/firefox_profile_lock.h13
-rw-r--r--chrome/browser/importer/firefox_profile_lock_posix.cc51
-rw-r--r--chrome/browser/importer/firefox_profile_lock_unittest.cc41
-rw-r--r--chrome/browser/importer/importer.cc4
-rw-r--r--chrome/chrome.gyp4
11 files changed, 352 insertions, 201 deletions
diff --git a/chrome/browser/importer/firefox_importer_utils.cc b/chrome/browser/importer/firefox_importer_utils.cc
index 47816c8..df0e5aa 100644
--- a/chrome/browser/importer/firefox_importer_utils.cc
+++ b/chrome/browser/importer/firefox_importer_utils.cc
@@ -6,12 +6,6 @@
#include <algorithm>
-#if defined(OS_WIN)
-#include <shlobj.h>
-
-#include "app/win_util.h"
-#include "base/registry.h"
-#endif
#include "base/logging.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
@@ -46,82 +40,8 @@ class FirefoxURLParameterFilter : public TemplateURLParser::ParameterFilter {
private:
DISALLOW_EVIL_CONSTRUCTORS(FirefoxURLParameterFilter);
};
-
-#if defined(OS_WIN)
-typedef BOOL (WINAPI* SetDllDirectoryFunc)(LPCTSTR lpPathName);
-
-// A helper class whose destructor calls SetDllDirectory(NULL) to undo the
-// effects of a previous SetDllDirectory call.
-class SetDllDirectoryCaller {
- public:
- explicit SetDllDirectoryCaller() : func_(NULL) { }
-
- ~SetDllDirectoryCaller() {
- if (func_)
- func_(NULL);
- }
-
- // Sets the SetDllDirectory function pointer to activates this object.
- void set_func(SetDllDirectoryFunc func) { func_ = func; }
-
- private:
- SetDllDirectoryFunc func_;
-};
-#endif
-
} // namespace
-#if defined(OS_WIN)
-// NOTE: Keep these in order since we need test all those paths according
-// to priority. For example. One machine has multiple users. One non-admin
-// user installs Firefox 2, which causes there is a Firefox2 entry under HKCU.
-// One admin user installs Firefox 3, which causes there is a Firefox 3 entry
-// under HKLM. So when the non-admin user log in, we should deal with Firefox 2
-// related data instead of Firefox 3.
-static const HKEY kFireFoxRegistryPaths[] = {
- HKEY_CURRENT_USER,
- HKEY_LOCAL_MACHINE
-};
-
-int GetCurrentFirefoxMajorVersionFromRegistry() {
- TCHAR ver_buffer[128];
- DWORD ver_buffer_length = sizeof(ver_buffer);
- int highest_version = 0;
- // When installing Firefox with admin account, the product keys will be
- // written under HKLM\Mozilla. Otherwise it the keys will be written under
- // HKCU\Mozilla.
- for (int i = 0; i < arraysize(kFireFoxRegistryPaths); ++i) {
- bool result = ReadFromRegistry(kFireFoxRegistryPaths[i],
- L"Software\\Mozilla\\Mozilla Firefox",
- L"CurrentVersion", ver_buffer, &ver_buffer_length);
- if (!result)
- continue;
- highest_version = std::max(highest_version, _wtoi(ver_buffer));
- }
- return highest_version;
-}
-
-std::wstring GetFirefoxInstallPathFromRegistry() {
- // Detects the path that Firefox is installed in.
- std::wstring registry_path = L"Software\\Mozilla\\Mozilla Firefox";
- TCHAR buffer[MAX_PATH];
- DWORD buffer_length = sizeof(buffer);
- bool result;
- result = ReadFromRegistry(HKEY_LOCAL_MACHINE, registry_path.c_str(),
- L"CurrentVersion", buffer, &buffer_length);
- if (!result)
- return std::wstring();
- registry_path += L"\\" + std::wstring(buffer) + L"\\Main";
- buffer_length = sizeof(buffer);
- result = ReadFromRegistry(HKEY_LOCAL_MACHINE, registry_path.c_str(),
- L"Install Directory", buffer, &buffer_length);
- if (!result)
- return std::wstring();
- return buffer;
-}
-#endif
-
-#if defined(OS_WIN) || defined(OS_LINUX)
bool GetFirefoxVersionAndPathFromProfile(const std::wstring& profile_path,
int* version,
std::wstring* app_path) {
@@ -152,32 +72,6 @@ bool GetFirefoxVersionAndPathFromProfile(const std::wstring& profile_path,
return ret;
}
-
-FilePath GetProfilesINI() {
- FilePath ini_file;
-#if defined(OS_WIN)
- // The default location of the profile folder containing user data is
- // under the "Application Data" folder in Windows XP.
- wchar_t buffer[MAX_PATH] = {0};
- if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL,
- SHGFP_TYPE_CURRENT, buffer))) {
- ini_file = FilePath(buffer).Append(L"Mozilla\\Firefox\\profiles.ini");
- }
-
-#else
- // The default location of the profile folder containing user data is
- // under user HOME directory in .mozilla/firefox folder on Linux.
- const char *home = getenv("HOME");
- if (home && home[0]) {
- ini_file = FilePath(home).Append(".mozilla/firefox/profiles.ini");
- }
-#endif
- if (file_util::PathExists(ini_file))
- return ini_file;
-
- return FilePath();
-}
-
void ParseProfileINI(std::wstring file, DictionaryValue* root) {
// Reads the whole INI file.
std::string content;
@@ -221,7 +115,6 @@ void ParseProfileINI(std::wstring file, DictionaryValue* root) {
}
}
}
-#endif
bool CanImportURL(const GURL& url) {
const char* kInvalidSchemes[] = {"wyciwyg", "place", "about", "chrome"};
@@ -442,12 +335,6 @@ bool IsDefaultHomepage(const GURL& homepage,
// class NSSDecryptor.
-// static
-const wchar_t NSSDecryptor::kNSS3Library[] = L"nss3.dll";
-const wchar_t NSSDecryptor::kSoftokn3Library[] = L"softokn3.dll";
-const wchar_t NSSDecryptor::kPLDS4Library[] = L"plds4.dll";
-const wchar_t NSSDecryptor::kNSPR4Library[] = L"nspr4.dll";
-
NSSDecryptor::NSSDecryptor()
: NSS_Init(NULL), NSS_Shutdown(NULL), PK11_GetInternalKeySlot(NULL),
PK11_CheckUserPassword(NULL), PK11_FreeSlot(NULL),
@@ -461,73 +348,9 @@ NSSDecryptor::~NSSDecryptor() {
Free();
}
-bool NSSDecryptor::Init(const std::wstring& dll_path,
- const std::wstring& db_path) {
-#if defined(OS_WIN)
- // We call SetDllDirectory to work around a Purify bug (GetModuleHandle
- // fails inside Purify under certain conditions). SetDllDirectory only
- // exists on Windows XP SP1 or later, so we look up its address at run time.
- HMODULE kernel32_dll = GetModuleHandle(L"kernel32.dll");
- if (kernel32_dll == NULL)
- return false;
- SetDllDirectoryFunc set_dll_directory =
- (SetDllDirectoryFunc)GetProcAddress(kernel32_dll, "SetDllDirectoryW");
- SetDllDirectoryCaller caller;
-
- if (set_dll_directory != NULL) {
- if (!set_dll_directory(dll_path.c_str()))
- return false;
- caller.set_func(set_dll_directory);
- nss3_dll_ = LoadLibrary(kNSS3Library);
- if (nss3_dll_ == NULL)
- return false;
- } else {
- // Fall back on LoadLibraryEx if SetDllDirectory isn't available. We
- // actually prefer this method because it doesn't change the DLL search
- // path, which is a process-wide property.
- std::wstring path = dll_path;
- file_util::AppendToPath(&path, kNSS3Library);
- nss3_dll_ = LoadLibraryEx(path.c_str(), NULL,
- LOAD_WITH_ALTERED_SEARCH_PATH);
- if (nss3_dll_ == NULL)
- return false;
-
- // Firefox 2 uses NSS 3.11. Firefox 3 uses NSS 3.12. NSS 3.12 has two
- // changes in its DLLs:
- // 1. nss3.dll is not linked with softokn3.dll at build time, but rather
- // loads softokn3.dll using LoadLibrary in NSS_Init.
- // 2. softokn3.dll has a new dependency sqlite3.dll.
- // NSS_Init's LoadLibrary call has trouble finding sqlite3.dll. To help
- // it out, we preload softokn3.dll using LoadLibraryEx with the
- // LOAD_WITH_ALTERED_SEARCH_PATH flag. This helps because LoadLibrary
- // doesn't load a DLL again if it's already loaded. This workaround is
- // harmless for NSS 3.11.
- path = dll_path;
- file_util::AppendToPath(&path, kSoftokn3Library);
- softokn3_dll_ = LoadLibraryEx(path.c_str(), NULL,
- LOAD_WITH_ALTERED_SEARCH_PATH);
- if (softokn3_dll_ == NULL) {
- Free();
- return false;
- }
- }
- HMODULE plds4_dll = GetModuleHandle(kPLDS4Library);
- HMODULE nspr4_dll = GetModuleHandle(kNSPR4Library);
-#elif defined(OS_LINUX)
- nss3_dll_ = base::LoadNativeLibrary(FilePath("libnss3.so"));
- if (nss3_dll_ == NULL)
- return false;
- base::NativeLibrary plds4_dll = base::LoadNativeLibrary(
- FilePath("libplds4.so"));
- base::NativeLibrary nspr4_dll = base::LoadNativeLibrary(
- FilePath("libnspr4.so"));
-#else
- // TODO(port): Check on MAC
- base::NativeLibrary plds4_dll, nspr4_dll;
- NOTIMPLEMENTED();
- return false;
-#endif
-
+bool NSSDecryptor::InitNSS(const std::wstring& db_path,
+ base::NativeLibrary plds4_dll,
+ base::NativeLibrary nspr4_dll) {
// NSPR DLLs are already loaded now.
if (plds4_dll == NULL || nspr4_dll == NULL) {
Free();
@@ -581,12 +404,10 @@ void NSSDecryptor::Free() {
PR_Cleanup();
is_nss_initialized_ = false;
}
-#if defined(OS_WIN) || defined(OS_LINUX)
if (softokn3_dll_ != NULL)
base::UnloadNativeLibrary(softokn3_dll_);
if (nss3_dll_ != NULL)
base::UnloadNativeLibrary(nss3_dll_);
-#endif
NSS_Init = NULL;
NSS_Shutdown = NULL;
PK11_GetInternalKeySlot = NULL;
@@ -641,12 +462,6 @@ void NSSDecryptor::Free() {
* ***** END LICENSE BLOCK ***** */
std::wstring NSSDecryptor::Decrypt(const std::string& crypt) const {
-#if !defined(OS_WIN) && !defined(OS_LINUX)
- // TODO(port): Load nss3.
- NOTIMPLEMENTED();
- return std::wstring();
-#endif
-
// Do nothing if NSS is not loaded.
if (!nss3_dll_)
return std::wstring();
diff --git a/chrome/browser/importer/firefox_importer_utils.h b/chrome/browser/importer/firefox_importer_utils.h
index cb44b1c..47deecf 100644
--- a/chrome/browser/importer/firefox_importer_utils.h
+++ b/chrome/browser/importer/firefox_importer_utils.h
@@ -27,7 +27,6 @@ int GetCurrentFirefoxMajorVersionFromRegistry();
std::wstring GetFirefoxInstallPathFromRegistry();
#endif
-#if defined(OS_WIN) || defined(OS_LINUX)
// Detects version of Firefox and installation path from given Firefox profile
bool GetFirefoxVersionAndPathFromProfile(const std::wstring& profile_path,
int* version,
@@ -51,7 +50,6 @@ FilePath GetProfilesINI();
// We set "[value]" in path "<Section>.<Key>". For example, the path
// "Genenral.StartWithLastProfile" has the value "1".
void ParseProfileINI(std::wstring file, DictionaryValue* root);
-#endif
// Returns true if we want to add the URL to the history. We filter
// out the URL with a unsupported scheme.
@@ -193,6 +191,11 @@ class NSSDecryptor {
std::vector<webkit_glue::PasswordForm>* forms);
private:
+ // Performs tasks common across all platforms to initialize NSS.
+ bool InitNSS(const std::wstring& db_path,
+ base::NativeLibrary plds4_dll,
+ base::NativeLibrary nspr4_dll);
+
// Methods in Firefox security components.
NSSInitFunc NSS_Init;
NSSShutdownFunc NSS_Shutdown;
diff --git a/chrome/browser/importer/firefox_importer_utils_linux.cc b/chrome/browser/importer/firefox_importer_utils_linux.cc
new file mode 100644
index 0000000..66f39a1
--- /dev/null
+++ b/chrome/browser/importer/firefox_importer_utils_linux.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/importer/firefox_importer_utils.h"
+
+FilePath GetProfilesINI() {
+ FilePath ini_file;
+ // The default location of the profile folder containing user data is
+ // under user HOME directory in .mozilla/firefox folder on Linux.
+ const char *home = getenv("HOME");
+ if (home && home[0]) {
+ ini_file = FilePath(home).Append(".mozilla/firefox/profiles.ini");
+ }
+ if (file_util::PathExists(ini_file))
+ return ini_file;
+
+ return FilePath();
+}
+
+// static
+const wchar_t NSSDecryptor::kNSS3Library[] = L"libnss3.so";
+const wchar_t NSSDecryptor::kSoftokn3Library[] = L"libsoftokn3.so";
+const wchar_t NSSDecryptor::kPLDS4Library[] = L"libplds4.so";
+const wchar_t NSSDecryptor::kNSPR4Library[] = L"libnspr4.so";
+
+bool NSSDecryptor::Init(const std::wstring& dll_path,
+ const std::wstring& db_path) {
+ nss3_dll_ = base::LoadNativeLibrary(
+ FilePath::FromWStringHack(kNSS3Library));
+ if (nss3_dll_ == NULL)
+ return false;
+ base::NativeLibrary plds4_lib = base::LoadNativeLibrary(
+ FilePath::FromWStringHack(kPLDS4Library));
+ base::NativeLibrary nspr4_lib = base::LoadNativeLibrary(
+ FilePath::FromWStringHack(kNSPR4Library));
+
+ return InitNSS(db_path, plds4_lib, nspr4_lib);
+}
diff --git a/chrome/browser/importer/firefox_importer_utils_mac.cc b/chrome/browser/importer/firefox_importer_utils_mac.cc
new file mode 100644
index 0000000..9fb3cf5
--- /dev/null
+++ b/chrome/browser/importer/firefox_importer_utils_mac.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/importer/firefox_importer_utils.h"
+
+#include "base/logging.h"
+
+FilePath GetProfilesINI() {
+ FilePath ini_file;
+ // ~/Library/Application Support/Firefox on OS X.
+ // This should be changed to NSSearchPathForDirectoriesInDomains().
+ // See bug http://code.google.com/p/chromium/issues/detail?id=15455
+ const char *home = getenv("HOME");
+ if (home && home[0]) {
+ ini_file = FilePath(home).Append(
+ "Library/Application Support/Firefox/profiles.ini");
+ }
+ if (file_util::PathExists(ini_file))
+ return ini_file;
+
+ return FilePath();
+}
+
+// static
+const wchar_t NSSDecryptor::kNSS3Library[] = L"libnss3.dylib";
+const wchar_t NSSDecryptor::kSoftokn3Library[] = L"libsoftokn3.dylib";
+const wchar_t NSSDecryptor::kPLDS4Library[] = L"libplds4.dylib";
+const wchar_t NSSDecryptor::kNSPR4Library[] = L"libnspr4.dylib";
+
+bool NSSDecryptor::Init(const std::wstring& dll_path,
+ const std::wstring& db_path) {
+ // TODO(port): Load the NSS libraries and call InitNSS()
+ // http://code.google.com/p/chromium/issues/detail?id=15455
+ NOTIMPLEMENTED();
+ return false;
+}
diff --git a/chrome/browser/importer/firefox_importer_utils_win.cc b/chrome/browser/importer/firefox_importer_utils_win.cc
new file mode 100644
index 0000000..3a531e3
--- /dev/null
+++ b/chrome/browser/importer/firefox_importer_utils_win.cc
@@ -0,0 +1,155 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/importer/firefox_importer_utils.h"
+
+#include "base/registry.h"
+
+namespace {
+
+typedef BOOL (WINAPI* SetDllDirectoryFunc)(LPCTSTR lpPathName);
+
+// A helper class whose destructor calls SetDllDirectory(NULL) to undo the
+// effects of a previous SetDllDirectory call.
+class SetDllDirectoryCaller {
+ public:
+ explicit SetDllDirectoryCaller() : func_(NULL) { }
+
+ ~SetDllDirectoryCaller() {
+ if (func_)
+ func_(NULL);
+ }
+
+ // Sets the SetDllDirectory function pointer to activates this object.
+ void set_func(SetDllDirectoryFunc func) { func_ = func; }
+
+ private:
+ SetDllDirectoryFunc func_;
+};
+
+} // namespace
+
+// NOTE: Keep these in order since we need test all those paths according
+// to priority. For example. One machine has multiple users. One non-admin
+// user installs Firefox 2, which causes there is a Firefox2 entry under HKCU.
+// One admin user installs Firefox 3, which causes there is a Firefox 3 entry
+// under HKLM. So when the non-admin user log in, we should deal with Firefox 2
+// related data instead of Firefox 3.
+static const HKEY kFireFoxRegistryPaths[] = {
+ HKEY_CURRENT_USER,
+ HKEY_LOCAL_MACHINE
+};
+
+int GetCurrentFirefoxMajorVersionFromRegistry() {
+ TCHAR ver_buffer[128];
+ DWORD ver_buffer_length = sizeof(ver_buffer);
+ int highest_version = 0;
+ // When installing Firefox with admin account, the product keys will be
+ // written under HKLM\Mozilla. Otherwise it the keys will be written under
+ // HKCU\Mozilla.
+ for (int i = 0; i < arraysize(kFireFoxRegistryPaths); ++i) {
+ bool result = ReadFromRegistry(kFireFoxRegistryPaths[i],
+ L"Software\\Mozilla\\Mozilla Firefox",
+ L"CurrentVersion", ver_buffer, &ver_buffer_length);
+ if (!result)
+ continue;
+ highest_version = std::max(highest_version, _wtoi(ver_buffer));
+ }
+ return highest_version;
+}
+
+std::wstring GetFirefoxInstallPathFromRegistry() {
+ // Detects the path that Firefox is installed in.
+ std::wstring registry_path = L"Software\\Mozilla\\Mozilla Firefox";
+ TCHAR buffer[MAX_PATH];
+ DWORD buffer_length = sizeof(buffer);
+ bool result;
+ result = ReadFromRegistry(HKEY_LOCAL_MACHINE, registry_path.c_str(),
+ L"CurrentVersion", buffer, &buffer_length);
+ if (!result)
+ return std::wstring();
+ registry_path += L"\\" + std::wstring(buffer) + L"\\Main";
+ buffer_length = sizeof(buffer);
+ result = ReadFromRegistry(HKEY_LOCAL_MACHINE, registry_path.c_str(),
+ L"Install Directory", buffer, &buffer_length);
+ if (!result)
+ return std::wstring();
+ return buffer;
+}
+
+FilePath GetProfilesINI() {
+ FilePath ini_file;
+ // The default location of the profile folder containing user data is
+ // under the "Application Data" folder in Windows XP.
+ wchar_t buffer[MAX_PATH] = {0};
+ if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL,
+ SHGFP_TYPE_CURRENT, buffer))) {
+ ini_file = FilePath(buffer).Append(L"Mozilla\\Firefox\\profiles.ini");
+ }
+ if (file_util::PathExists(ini_file))
+ return ini_file;
+
+ return FilePath();
+}
+
+// static
+const wchar_t NSSDecryptor::kNSS3Library[] = L"nss3.dll";
+const wchar_t NSSDecryptor::kSoftokn3Library[] = L"softokn3.dll";
+const wchar_t NSSDecryptor::kPLDS4Library[] = L"plds4.dll";
+const wchar_t NSSDecryptor::kNSPR4Library[] = L"nspr4.dll";
+
+bool NSSDecryptor::Init(const std::wstring& dll_path,
+ const std::wstring& db_path) {
+ // We call SetDllDirectory to work around a Purify bug (GetModuleHandle
+ // fails inside Purify under certain conditions). SetDllDirectory only
+ // exists on Windows XP SP1 or later, so we look up its address at run time.
+ HMODULE kernel32_dll = GetModuleHandle(L"kernel32.dll");
+ if (kernel32_dll == NULL)
+ return false;
+ SetDllDirectoryFunc set_dll_directory =
+ (SetDllDirectoryFunc)GetProcAddress(kernel32_dll, "SetDllDirectoryW");
+ SetDllDirectoryCaller caller;
+
+ if (set_dll_directory != NULL) {
+ if (!set_dll_directory(dll_path.c_str()))
+ return false;
+ caller.set_func(set_dll_directory);
+ nss3_dll_ = LoadLibrary(kNSS3Library);
+ if (nss3_dll_ == NULL)
+ return false;
+ } else {
+ // Fall back on LoadLibraryEx if SetDllDirectory isn't available. We
+ // actually prefer this method because it doesn't change the DLL search
+ // path, which is a process-wide property.
+ std::wstring path = dll_path;
+ file_util::AppendToPath(&path, kNSS3Library);
+ nss3_dll_ = LoadLibraryEx(path.c_str(), NULL,
+ LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (nss3_dll_ == NULL)
+ return false;
+
+ // Firefox 2 uses NSS 3.11. Firefox 3 uses NSS 3.12. NSS 3.12 has two
+ // changes in its DLLs:
+ // 1. nss3.dll is not linked with softokn3.dll at build time, but rather
+ // loads softokn3.dll using LoadLibrary in NSS_Init.
+ // 2. softokn3.dll has a new dependency sqlite3.dll.
+ // NSS_Init's LoadLibrary call has trouble finding sqlite3.dll. To help
+ // it out, we preload softokn3.dll using LoadLibraryEx with the
+ // LOAD_WITH_ALTERED_SEARCH_PATH flag. This helps because LoadLibrary
+ // doesn't load a DLL again if it's already loaded. This workaround is
+ // harmless for NSS 3.11.
+ path = dll_path;
+ file_util::AppendToPath(&path, kSoftokn3Library);
+ softokn3_dll_ = LoadLibraryEx(path.c_str(), NULL,
+ LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (softokn3_dll_ == NULL) {
+ Free();
+ return false;
+ }
+ }
+ HMODULE plds4_dll = GetModuleHandle(kPLDS4Library);
+ HMODULE nspr4_dll = GetModuleHandle(kNSPR4Library);
+
+ return InitNSS(db_path, plds4_dll, nspr4_dll);
+}
diff --git a/chrome/browser/importer/firefox_profile_lock.cc b/chrome/browser/importer/firefox_profile_lock.cc
index f51a9f9..4503d64 100644
--- a/chrome/browser/importer/firefox_profile_lock.cc
+++ b/chrome/browser/importer/firefox_profile_lock.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -53,11 +53,16 @@
// static
#if defined(OS_LINUX)
-// TODO(rahulk): Even though this is called OLD_LOCK_FILE_NAME in Firefox code
// http://www.google.com/codesearch/p?hl=en#e_ObwTAVPyo/profile/dirserviceprovider/src/nsProfileLock.cpp&l=433
-// this seems to work with Firefox 3.0.
const FilePath::CharType* FirefoxProfileLock::kLockFileName =
+ FILE_PATH_LITERAL(".parentlock");
+const FilePath::CharType* FirefoxProfileLock::kOldLockFileName =
FILE_PATH_LITERAL("lock");
+#elif defined(OS_MACOSX)
+const FilePath::CharType* FirefoxProfileLock::kLockFileName =
+ FILE_PATH_LITERAL(".parentlock");
+const FilePath::CharType* FirefoxProfileLock::kOldLockFileName =
+ FILE_PATH_LITERAL("parent.lock");
#else
const FilePath::CharType* FirefoxProfileLock::kLockFileName =
FILE_PATH_LITERAL("parent.lock");
diff --git a/chrome/browser/importer/firefox_profile_lock.h b/chrome/browser/importer/firefox_profile_lock.h
index 1474869..1c1c7ee 100644
--- a/chrome/browser/importer/firefox_profile_lock.h
+++ b/chrome/browser/importer/firefox_profile_lock.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -84,6 +84,7 @@ class FirefoxProfileLock {
FRIEND_TEST(FirefoxImporterTest, ProfileLockOrphaned);
static const FilePath::CharType* kLockFileName;
+ static const FilePath::CharType* kOldLockFileName;
void Init();
@@ -95,6 +96,16 @@ class FirefoxProfileLock {
HANDLE lock_handle_;
#elif defined(OS_POSIX)
int lock_fd_;
+
+ // On Posix systems Firefox apparently first tries to put a fcntl lock
+ // on a file and if that fails, it does a regular exculsive open on another
+ // file. This variable contains the location of this other file.
+ FilePath old_lock_file_;
+
+ // Method that tries to put a fcntl lock on file specified by |lock_file_|.
+ // Returns false if lock is already help by another process. true in all
+ // other cases.
+ bool LockWithFcntl();
#endif
DISALLOW_COPY_AND_ASSIGN(FirefoxProfileLock);
diff --git a/chrome/browser/importer/firefox_profile_lock_posix.cc b/chrome/browser/importer/firefox_profile_lock_posix.cc
index b32dd54..919b04a 100644
--- a/chrome/browser/importer/firefox_profile_lock_posix.cc
+++ b/chrome/browser/importer/firefox_profile_lock_posix.cc
@@ -1,9 +1,10 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/importer/firefox_profile_lock.h"
+#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -62,7 +63,14 @@ void FirefoxProfileLock::Init() {
void FirefoxProfileLock::Lock() {
if (HasAcquired())
return;
- lock_fd_ = open(lock_file_.value().c_str(), O_CREAT | O_EXCL, 0644);
+
+ bool fcntl_lock = LockWithFcntl();
+ if (!fcntl_lock) {
+ return;
+ } else if (!HasAcquired()) {
+ old_lock_file_ = lock_file_.DirName().Append(kOldLockFileName);
+ lock_fd_ = open(old_lock_file_.value().c_str(), O_CREAT | O_EXCL, 0644);
+ }
}
void FirefoxProfileLock::Unlock() {
@@ -70,9 +78,46 @@ void FirefoxProfileLock::Unlock() {
return;
close(lock_fd_);
lock_fd_ = -1;
- file_util::Delete(lock_file_, false);
+ file_util::Delete(old_lock_file_, false);
}
bool FirefoxProfileLock::HasAcquired() {
return (lock_fd_ >= 0);
}
+
+// This function tries to lock Firefox profile using fcntl(). The return
+// value of this function together with HasAcquired() tells the current status
+// of lock.
+// if return == false: Another process has lock to the profile.
+// if return == true && HasAcquired() == true: successfully acquired the lock.
+// if return == false && HasAcquired() == false: Failed to acquire lock due
+// to some error (so that we can try alternate method of profile lock).
+bool FirefoxProfileLock::LockWithFcntl() {
+ lock_fd_ = open(lock_file_.value().c_str(), O_WRONLY | O_CREAT | O_TRUNC,
+ 0666);
+ if (lock_fd_ == -1)
+ return true;
+
+ struct flock lock;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+
+ struct flock testlock = lock;
+ if (fcntl(lock_fd_, F_GETLK, &testlock) == -1) {
+ close(lock_fd_);
+ lock_fd_ = -1;
+ return true;
+ } else if (fcntl(lock_fd_, F_SETLK, &lock) == -1) {
+ close(lock_fd_);
+ lock_fd_ = -1;
+ if (errno == EAGAIN || errno == EACCES)
+ return false;
+ else
+ return true;
+ } else {
+ // We have the lock.
+ return true;
+ }
+}
diff --git a/chrome/browser/importer/firefox_profile_lock_unittest.cc b/chrome/browser/importer/firefox_profile_lock_unittest.cc
new file mode 100644
index 0000000..4345048
--- /dev/null
+++ b/chrome/browser/importer/firefox_profile_lock_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/process_util.h"
+#include "base/string_util.h"
+#include "chrome/browser/importer/firefox_profile_lock.h"
+#include "chrome/common/chrome_paths.h"
+
+class FirefoxProfileLockTest : public testing::Test {
+ public:
+ protected:
+ virtual void SetUp() {
+ ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &test_path_));
+ std::wstring dir_name(L"FirefoxProfileLockTest");
+ dir_name.append(StringPrintf(L"-%d", base::GetCurrentProcId()));
+ test_path_ = test_path_.Append(FilePath::FromWStringHack(dir_name));
+ file_util::Delete(test_path_, true);
+ file_util::CreateDirectory(test_path_);
+ }
+
+ virtual void TearDown() {
+ ASSERT_TRUE(file_util::Delete(test_path_, true));
+ ASSERT_FALSE(file_util::PathExists(test_path_));
+ }
+
+ FilePath test_path_;
+};
+
+TEST_F(FirefoxProfileLockTest, LockTest) {
+ FirefoxProfileLock lock1(test_path_.ToWStringHack());
+ ASSERT_TRUE(lock1.HasAcquired());
+ lock1.Unlock();
+ ASSERT_FALSE(lock1.HasAcquired());
+ lock1.Lock();
+ ASSERT_TRUE(lock1.HasAcquired());
+}
diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc
index a4987f2..74d2694 100644
--- a/chrome/browser/importer/importer.cc
+++ b/chrome/browser/importer/importer.cc
@@ -679,9 +679,6 @@ void ImporterHost::DetectIEProfiles() {
#endif
void ImporterHost::DetectFirefoxProfiles() {
-#if defined(OS_MACOSX)
- NOTIMPLEMENTED();
-#else
DictionaryValue root;
std::wstring ini_file = GetProfilesINI().ToWStringHack();
ParseProfileINI(ini_file, &root);
@@ -761,7 +758,6 @@ void ImporterHost::DetectFirefoxProfiles() {
SEARCH_ENGINES;
source_profiles_.push_back(firefox);
}
-#endif
}
void ImporterHost::DetectGoogleToolbarProfiles() {
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index d7ea225..ddd2c9b 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1114,6 +1114,9 @@
'browser/importer/firefox3_importer.cc',
'browser/importer/firefox3_importer.h',
'browser/importer/firefox_importer_utils.cc',
+ 'browser/importer/firefox_importer_utils_linux.cc',
+ 'browser/importer/firefox_importer_utils_mac.cc',
+ 'browser/importer/firefox_importer_utils_win.cc',
'browser/importer/firefox_importer_utils.h',
'browser/importer/firefox_profile_lock.cc',
'browser/importer/firefox_profile_lock.h',
@@ -3443,6 +3446,7 @@
'browser/importer/firefox_importer_unittest.cc',
'browser/importer/importer_unittest.cc',
'browser/importer/toolbar_importer_unittest.cc',
+ 'browser/importer/firefox_profile_lock_unittest.cc',
'browser/keychain_mock_mac.cc',
'browser/keychain_mock_mac.h',
'browser/login_prompt_unittest.cc',