Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / browser / components / migration / src / nsOperaProfileMigrator.cpp
blobc94c09edce771f85ac33d76e5c4b80e59b6792d9
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is The Browser Profile Migrator.
17 * The Initial Developer of the Original Code is Ben Goodger.
18 * Portions created by the Initial Developer are Copyright (C) 2004
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Ben Goodger <ben@bengoodger.com>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsAppDirectoryServiceDefs.h"
39 #include "nsBrowserProfileMigratorUtils.h"
40 #include "nsDirectoryServiceDefs.h"
41 #include "nsDirectoryServiceUtils.h"
42 #include "nsDocShellCID.h"
43 #include "nsINavBookmarksService.h"
44 #include "nsBrowserCompsCID.h"
45 #include "nsIBrowserProfileMigrator.h"
46 #include "nsIBrowserHistory.h"
47 #include "nsICookieManager2.h"
48 #include "nsIGlobalHistory.h"
49 #include "nsIInputStream.h"
50 #include "nsILineInputStream.h"
51 #include "nsILocalFile.h"
52 #include "nsINIParser.h"
53 #include "nsIObserverService.h"
54 #include "nsIPermissionManager.h"
55 #include "nsIPrefLocalizedString.h"
56 #include "nsIPrefService.h"
57 #include "nsIProfileMigrator.h"
58 #include "nsIProperties.h"
59 #include "nsIRDFContainer.h"
60 #include "nsIRDFService.h"
61 #include "nsIServiceManager.h"
62 #include "nsIStringBundle.h"
63 #include "nsISupportsPrimitives.h"
64 #include "nsNetUtil.h"
65 #include "nsOperaProfileMigrator.h"
66 #include "nsToolkitCompsCID.h"
67 #ifdef XP_WIN
68 #include <windows.h>
69 #endif
71 #define MIGRATION_BUNDLE "chrome://browser/locale/migration/migration.properties"
73 #ifdef XP_WIN
74 #define OPERA_PREFERENCES_FOLDER_NAME NS_LITERAL_STRING("Opera")
75 #define OPERA_PREFERENCES_FILE_NAME NS_LITERAL_STRING("opera6.ini")
76 #define OPERA_HISTORY_FILE_NAME NS_LITERAL_STRING("global.dat")
77 #define OPERA_BOOKMARKS_FILE_NAME NS_LITERAL_STRING("opera6.adr")
78 #elif defined(XP_MACOSX)
79 #define OPERA_PREFERENCES_FOLDER_NAME NS_LITERAL_STRING("Opera 6 Preferences")
80 #define OPERA_PREFERENCES_FILE_NAME NS_LITERAL_STRING("Opera 6 Preferences")
81 #define OPERA_HISTORY_FILE_NAME NS_LITERAL_STRING("Opera Global History")
82 #define OPERA_BOOKMARKS_FILE_NAME NS_LITERAL_STRING("Bookmarks")
83 #elif defined (XP_UNIX)
84 #define OPERA_PREFERENCES_FOLDER_NAME NS_LITERAL_STRING(".opera")
85 #define OPERA_PREFERENCES_FILE_NAME NS_LITERAL_STRING("opera6.ini")
86 #define OPERA_HISTORY_FILE_NAME NS_LITERAL_STRING("global.dat")
87 #define OPERA_BOOKMARKS_FILE_NAME NS_LITERAL_STRING("opera6.adr")
88 #elif defined (XP_BEOS)
89 #define OPERA_PREFERENCES_FOLDER_NAME NS_LITERAL_STRING("Opera")
90 #define OPERA_PREFERENCES_FILE_NAME NS_LITERAL_STRING("opera.ini")
91 #define OPERA_HISTORY_FILE_NAME NS_LITERAL_STRING("global.dat")
92 #define OPERA_BOOKMARKS_FILE_NAME NS_LITERAL_STRING("opera.adr")
93 #else
94 #error Need to define location of Opera Profile data.
95 #endif
97 #define OPERA_COOKIES_FILE_NAME NS_LITERAL_STRING("cookies4.dat")
98 #ifdef XP_BEOS
99 #define OPERA_COOKIES_FILE_NAME NS_LITERAL_STRING("cookies.dat")
100 #endif
102 ///////////////////////////////////////////////////////////////////////////////
103 // nsBrowserProfileMigrator
105 NS_IMPL_ISUPPORTS1(nsOperaProfileMigrator, nsIBrowserProfileMigrator)
107 nsOperaProfileMigrator::nsOperaProfileMigrator()
109 mObserverService = do_GetService("@mozilla.org/observer-service;1");
112 nsOperaProfileMigrator::~nsOperaProfileMigrator()
116 NS_IMETHODIMP
117 nsOperaProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
119 nsresult rv = NS_OK;
120 PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;
122 if (aStartup) {
123 rv = aStartup->DoStartup();
124 NS_ENSURE_SUCCESS(rv, rv);
127 if (!mOperaProfile)
128 GetOperaProfile(aProfile, getter_AddRefs(mOperaProfile));
130 NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
132 COPY_DATA(CopyPreferences, aReplace, nsIBrowserProfileMigrator::SETTINGS);
133 COPY_DATA(CopyCookies, aReplace, nsIBrowserProfileMigrator::COOKIES);
134 COPY_DATA(CopyHistory, aReplace, nsIBrowserProfileMigrator::HISTORY);
135 COPY_DATA(CopyBookmarks, aReplace, nsIBrowserProfileMigrator::BOOKMARKS);
137 NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
139 return rv;
142 NS_IMETHODIMP
143 nsOperaProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
144 PRBool aReplace,
145 PRUint16* aResult)
147 *aResult = 0;
148 if (!mOperaProfile) {
149 GetOperaProfile(aProfile, getter_AddRefs(mOperaProfile));
150 if (!mOperaProfile)
151 return NS_ERROR_FILE_NOT_FOUND;
154 MigrationData data[] = { { ToNewUnicode(OPERA_PREFERENCES_FILE_NAME),
155 nsIBrowserProfileMigrator::SETTINGS,
156 PR_FALSE },
157 { ToNewUnicode(OPERA_COOKIES_FILE_NAME),
158 nsIBrowserProfileMigrator::COOKIES,
159 PR_FALSE },
160 { ToNewUnicode(OPERA_HISTORY_FILE_NAME),
161 nsIBrowserProfileMigrator::HISTORY,
162 PR_FALSE },
163 { ToNewUnicode(OPERA_BOOKMARKS_FILE_NAME),
164 nsIBrowserProfileMigrator::BOOKMARKS,
165 PR_FALSE } };
167 // Frees file name strings allocated above.
168 GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
169 aReplace, mOperaProfile, aResult);
171 return NS_OK;
174 NS_IMETHODIMP
175 nsOperaProfileMigrator::GetSourceExists(PRBool* aResult)
177 nsCOMPtr<nsISupportsArray> profiles;
178 GetSourceProfiles(getter_AddRefs(profiles));
180 if (profiles) {
181 PRUint32 count;
182 profiles->Count(&count);
183 *aResult = count > 0;
185 else
186 *aResult = PR_FALSE;
188 return NS_OK;
191 NS_IMETHODIMP
192 nsOperaProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
194 nsCOMPtr<nsISupportsArray> profiles;
195 GetSourceProfiles(getter_AddRefs(profiles));
197 #ifdef XP_WIN
198 if (profiles) {
199 PRUint32 count;
200 profiles->Count(&count);
201 *aResult = count > 1;
203 else
204 #endif
205 *aResult = PR_FALSE;
207 return NS_OK;
210 NS_IMETHODIMP
211 nsOperaProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
213 if (!mProfiles) {
214 nsresult rv;
216 mProfiles = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
217 if (NS_FAILED(rv)) return rv;
219 nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
220 nsCOMPtr<nsILocalFile> file;
221 #ifdef XP_WIN
222 fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
224 // Opera profile lives under %APP_DATA%\Opera\<operaver>\profile
225 file->Append(OPERA_PREFERENCES_FOLDER_NAME);
227 nsCOMPtr<nsISimpleEnumerator> e;
228 rv = file->GetDirectoryEntries(getter_AddRefs(e));
229 if (NS_FAILED(rv))
230 return rv;
232 PRBool hasMore;
233 e->HasMoreElements(&hasMore);
234 while (hasMore) {
235 nsCOMPtr<nsILocalFile> curr;
236 e->GetNext(getter_AddRefs(curr));
238 PRBool isDirectory = PR_FALSE;
239 curr->IsDirectory(&isDirectory);
240 if (isDirectory) {
241 nsCOMPtr<nsISupportsString> string(do_CreateInstance("@mozilla.org/supports-string;1"));
242 nsAutoString leafName;
243 curr->GetLeafName(leafName);
244 string->SetData(leafName);
245 mProfiles->AppendElement(string);
248 e->HasMoreElements(&hasMore);
250 #elif defined (XP_MACOSX)
251 fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
253 file->Append(NS_LITERAL_STRING("Preferences"));
254 file->Append(OPERA_PREFERENCES_FOLDER_NAME);
256 PRBool exists;
257 file->Exists(&exists);
259 if (exists) {
260 nsCOMPtr<nsISupportsString> string(do_CreateInstance("@mozilla.org/supports-string;1"));
261 string->SetData(OPERA_PREFERENCES_FOLDER_NAME);
262 mProfiles->AppendElement(string);
264 #elif defined (XP_UNIX)
265 fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
267 file->Append(OPERA_PREFERENCES_FOLDER_NAME);
269 PRBool exists;
270 file->Exists(&exists);
272 if (exists) {
273 nsCOMPtr<nsISupportsString> string(do_CreateInstance("@mozilla.org/supports-string;1"));
274 string->SetData(OPERA_PREFERENCES_FOLDER_NAME);
275 mProfiles->AppendElement(string);
277 #endif
280 *aResult = mProfiles;
281 NS_IF_ADDREF(*aResult);
282 return NS_OK;
285 NS_IMETHODIMP
286 nsOperaProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
288 nsresult rv;
289 nsCAutoString val;
291 nsCOMPtr<nsIFile> operaPrefs;
292 mOperaProfile->Clone(getter_AddRefs(operaPrefs));
293 operaPrefs->Append(OPERA_PREFERENCES_FILE_NAME);
295 nsCOMPtr<nsILocalFile> lf(do_QueryInterface(operaPrefs));
296 NS_ENSURE_TRUE(lf, NS_ERROR_UNEXPECTED);
298 nsINIParser parser;
299 rv = parser.Init(lf);
300 NS_ENSURE_SUCCESS(rv, rv);
302 rv = parser.GetString("User Prefs",
303 "Home URL",
304 val);
306 if (NS_SUCCEEDED(rv))
307 aResult.Assign(val);
309 return NS_OK;
313 #define _OPM(type) nsOperaProfileMigrator::type
315 static
316 nsOperaProfileMigrator::PrefTransform gTransforms[] = {
317 { "User Prefs", "Download Directory", _OPM(STRING), "browser.download.dir", _OPM(SetFile), PR_FALSE, -1 },
318 { nsnull, "Enable Cookies", _OPM(INT), "network.cookie.cookieBehavior", _OPM(SetCookieBehavior), PR_FALSE, -1 },
319 { nsnull, "Accept Cookies Session Only", _OPM(BOOL), "network.cookie.lifetimePolicy", _OPM(SetCookieLifetime), PR_FALSE, -1 },
320 { nsnull, "Allow script to resize window", _OPM(BOOL), "dom.disable_window_move_resize", _OPM(SetBool), PR_FALSE, -1 },
321 { nsnull, "Allow script to move window", _OPM(BOOL), "dom.disable_window_move_resize", _OPM(SetBool), PR_FALSE, -1 },
322 { nsnull, "Allow script to raise window", _OPM(BOOL), "dom.disable_window_flip", _OPM(SetBool), PR_FALSE, -1 },
323 { nsnull, "Allow script to change status", _OPM(BOOL), "dom.disable_window_status_change", _OPM(SetBool), PR_FALSE, -1 },
324 { nsnull, "Ignore Unrequested Popups", _OPM(BOOL), "dom.disable_open_during_load", _OPM(SetBool), PR_FALSE, -1 },
325 { nsnull, "Load Figures", _OPM(BOOL), "permissions.default.image", _OPM(SetImageBehavior), PR_FALSE, -1 },
327 { "Visited link", nsnull, _OPM(COLOR), "browser.visited_color", _OPM(SetString), PR_FALSE, -1 },
328 { "Link", nsnull, _OPM(COLOR), "browser.anchor_color", _OPM(SetString), PR_FALSE, -1 },
329 { nsnull, "Underline", _OPM(BOOL), "browser.underline_anchors", _OPM(SetBool), PR_FALSE, -1 },
330 { nsnull, "Expiry", _OPM(INT), "browser.history_expire_days", _OPM(SetInt), PR_FALSE, -1 },
332 { "Security Prefs", "Enable SSL v2", _OPM(BOOL), "security.enable_ssl2", _OPM(SetBool), PR_FALSE, -1 },
333 { nsnull, "Enable SSL v3", _OPM(BOOL), "security.enable_ssl3", _OPM(SetBool), PR_FALSE, -1 },
334 { nsnull, "Enable TLS v1.0", _OPM(BOOL), "security.enable_tls", _OPM(SetBool), PR_FALSE, -1 },
336 { "Extensions", "Scripting", _OPM(BOOL), "javascript.enabled", _OPM(SetBool), PR_FALSE, -1 }
339 nsresult
340 nsOperaProfileMigrator::SetFile(void* aTransform, nsIPrefBranch* aBranch)
342 PrefTransform* xform = (PrefTransform*)aTransform;
343 nsCOMPtr<nsILocalFile> lf(do_CreateInstance("@mozilla.org/file/local;1"));
344 lf->InitWithPath(NS_ConvertUTF8toUTF16(xform->stringValue));
345 return aBranch->SetComplexValue(xform->targetPrefName, NS_GET_IID(nsILocalFile), lf);
348 nsresult
349 nsOperaProfileMigrator::SetCookieBehavior(void* aTransform, nsIPrefBranch* aBranch)
351 PrefTransform* xform = (PrefTransform*)aTransform;
352 PRInt32 val = (xform->intValue == 3) ? 0 : (xform->intValue == 0) ? 2 : 1;
353 return aBranch->SetIntPref(xform->targetPrefName, val);
356 nsresult
357 nsOperaProfileMigrator::SetCookieLifetime(void* aTransform, nsIPrefBranch* aBranch)
359 PrefTransform* xform = (PrefTransform*)aTransform;
360 return aBranch->SetIntPref(xform->targetPrefName, xform->boolValue ? 2 : 0);
363 nsresult
364 nsOperaProfileMigrator::SetImageBehavior(void* aTransform, nsIPrefBranch* aBranch)
366 PrefTransform* xform = (PrefTransform*)aTransform;
367 return aBranch->SetIntPref(xform->targetPrefName, xform->boolValue ? 1 : 2);
370 nsresult
371 nsOperaProfileMigrator::SetBool(void* aTransform, nsIPrefBranch* aBranch)
373 PrefTransform* xform = (PrefTransform*)aTransform;
374 return aBranch->SetBoolPref(xform->targetPrefName, xform->boolValue);
377 nsresult
378 nsOperaProfileMigrator::SetWString(void* aTransform, nsIPrefBranch* aBranch)
380 PrefTransform* xform = (PrefTransform*)aTransform;
381 nsCOMPtr<nsIPrefLocalizedString> pls(do_CreateInstance("@mozilla.org/pref-localizedstring;1"));
382 NS_ConvertUTF8toUTF16 data(xform->stringValue);
383 pls->SetData(data.get());
384 return aBranch->SetComplexValue(xform->targetPrefName, NS_GET_IID(nsIPrefLocalizedString), pls);
387 nsresult
388 nsOperaProfileMigrator::SetInt(void* aTransform, nsIPrefBranch* aBranch)
390 PrefTransform* xform = (PrefTransform*)aTransform;
391 return aBranch->SetIntPref(xform->targetPrefName, xform->intValue);
394 nsresult
395 nsOperaProfileMigrator::SetString(void* aTransform, nsIPrefBranch* aBranch)
397 PrefTransform* xform = (PrefTransform*)aTransform;
398 return aBranch->SetCharPref(xform->targetPrefName, xform->stringValue);
401 nsresult
402 nsOperaProfileMigrator::CopyPreferences(PRBool aReplace)
404 nsresult rv;
406 nsCOMPtr<nsIFile> operaPrefs;
407 mOperaProfile->Clone(getter_AddRefs(operaPrefs));
408 operaPrefs->Append(OPERA_PREFERENCES_FILE_NAME);
410 nsCOMPtr<nsILocalFile> lf(do_QueryInterface(operaPrefs));
411 NS_ENSURE_TRUE(lf, NS_ERROR_UNEXPECTED);
413 nsINIParser parser;
414 rv = parser.Init(lf);
415 NS_ENSURE_SUCCESS(rv, rv);
417 nsCOMPtr<nsIPrefBranch> branch(do_GetService(NS_PREFSERVICE_CONTRACTID));
419 // Traverse the standard transforms
420 PrefTransform* transform;
421 PrefTransform* end = gTransforms + sizeof(gTransforms)/sizeof(PrefTransform);
423 char* lastSectionName = nsnull;
424 for (transform = gTransforms; transform < end; ++transform) {
425 if (transform->sectionName)
426 lastSectionName = transform->sectionName;
428 if (transform->type == _OPM(COLOR)) {
429 char* colorString = nsnull;
430 nsresult rv = ParseColor(parser, lastSectionName, &colorString);
431 if (NS_SUCCEEDED(rv)) {
432 transform->stringValue = colorString;
434 transform->prefHasValue = PR_TRUE;
435 transform->prefSetterFunc(transform, branch);
437 if (colorString)
438 free(colorString);
440 else {
441 nsCAutoString val;
442 rv = parser.GetString(lastSectionName,
443 transform->keyName,
444 val);
445 if (NS_SUCCEEDED(rv)) {
446 nsresult strerr;
447 switch (transform->type) {
448 case _OPM(STRING):
449 transform->stringValue = ToNewCString(val);
450 break;
451 case _OPM(INT): {
452 transform->intValue = val.ToInteger(&strerr);
454 break;
455 case _OPM(BOOL): {
456 transform->boolValue = val.ToInteger(&strerr) != 0;
458 break;
459 default:
460 break;
462 transform->prefHasValue = PR_TRUE;
463 transform->prefSetterFunc(transform, branch);
464 if (transform->type == _OPM(STRING) && transform->stringValue) {
465 NS_Free(transform->stringValue);
466 transform->stringValue = nsnull;
472 // Copy Proxy Settings
473 CopyProxySettings(parser, branch);
475 // Copy User Content Sheet
476 if (aReplace)
477 CopyUserContentSheet(parser);
479 return NS_OK;
482 nsresult
483 nsOperaProfileMigrator::CopyProxySettings(nsINIParser &aParser,
484 nsIPrefBranch* aBranch)
486 nsresult rv;
488 PRInt32 networkProxyType = 0;
490 const char* protocols[4] = { "HTTP", "HTTPS", "FTP", "GOPHER" };
491 const char* protocols_l[4] = { "http", "https", "ftp", "gopher" };
492 char toggleBuf[15], serverBuf[20], serverPrefBuf[20],
493 serverPortPrefBuf[25];
494 PRInt32 enabled;
495 for (PRUint32 i = 0; i < 4; ++i) {
496 sprintf(toggleBuf, "Use %s", protocols[i]);
497 GetInteger(aParser, "Proxy", toggleBuf, &enabled);
498 if (enabled) {
499 // Enable the "manual configuration" setting if we have at least
500 // one protocol using a Proxy.
501 networkProxyType = 1;
504 sprintf(serverBuf, "%s Server", protocols[i]);
505 nsCAutoString proxyServer;
506 rv = aParser.GetString("Proxy", serverBuf, proxyServer);
507 if (NS_FAILED(rv))
508 continue;
510 sprintf(serverPrefBuf, "network.proxy.%s", protocols_l[i]);
511 sprintf(serverPortPrefBuf, "network.proxy.%s_port", protocols_l[i]);
512 // strings in Opera pref. file are in UTF-8
513 SetProxyPref(NS_ConvertUTF8toUTF16(proxyServer),
514 serverPrefBuf, serverPortPrefBuf, aBranch);
517 GetInteger(aParser, "Proxy", "Use Automatic Proxy Configuration", &enabled);
518 if (enabled)
519 networkProxyType = 2;
521 nsCAutoString configURL;
522 rv = aParser.GetString("Proxy", "Automatic Proxy Configuration URL",
523 configURL);
524 if (NS_SUCCEEDED(rv))
525 aBranch->SetCharPref("network.proxy.autoconfig_url", configURL.get());
527 GetInteger(aParser, "Proxy", "No Proxy Servers Check", &enabled);
528 if (enabled) {
529 nsCAutoString servers;
530 rv = aParser.GetString("Proxy", "No Proxy Servers", servers);
531 if (NS_SUCCEEDED(rv))
532 // strings in Opera pref. file are in UTF-8
533 ParseOverrideServers(NS_ConvertUTF8toUTF16(servers), aBranch);
536 aBranch->SetIntPref("network.proxy.type", networkProxyType);
538 return NS_OK;
541 nsresult
542 nsOperaProfileMigrator::GetInteger(nsINIParser &aParser,
543 const char* aSectionName,
544 const char* aKeyName,
545 PRInt32* aResult)
547 nsCAutoString val;
549 nsresult rv = aParser.GetString(aSectionName, aKeyName, val);
550 if (NS_FAILED(rv))
551 return rv;
553 *aResult = val.ToInteger(&rv);
555 return rv;
559 nsresult
560 nsOperaProfileMigrator::ParseColor(nsINIParser &aParser,
561 const char* aSectionName, char** aResult)
563 nsresult rv;
564 PRInt32 r, g, b;
566 rv = GetInteger(aParser, aSectionName, "Red", &r);
567 rv |= GetInteger(aParser, aSectionName, "Green", &g);
568 rv |= GetInteger(aParser, aSectionName, "Blue", &b);
569 if (NS_FAILED(rv))
570 return NS_OK; // This Preference has no value. Bail now before we get in trouble.
572 *aResult = (char*)malloc(sizeof(char) * 8);
573 if (!*aResult)
574 return NS_ERROR_OUT_OF_MEMORY;
576 sprintf(*aResult, "#%02X%02X%02X", r, g, b);
578 return NS_OK;
581 nsresult
582 nsOperaProfileMigrator::CopyUserContentSheet(nsINIParser &aParser)
584 nsresult rv;
586 nsCAutoString userContentCSS;
587 rv = aParser.GetString("User Prefs", "Local CSS File", userContentCSS);
588 if (NS_FAILED(rv) || userContentCSS.Length() == 0)
589 return NS_OK;
591 // Copy the file
592 nsCOMPtr<nsILocalFile> userContentCSSFile;
593 rv = NS_NewNativeLocalFile(userContentCSS, PR_TRUE,
594 getter_AddRefs(userContentCSSFile));
595 if (NS_FAILED(rv))
596 return NS_OK;
598 PRBool exists;
599 rv = userContentCSSFile->Exists(&exists);
600 if (NS_FAILED(rv) || !exists)
601 return NS_OK;
603 nsCOMPtr<nsIFile> profileChromeDir;
604 NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR,
605 getter_AddRefs(profileChromeDir));
606 if (!profileChromeDir)
607 return NS_OK;
609 userContentCSSFile->CopyToNative(profileChromeDir,
610 NS_LITERAL_CSTRING("userContent.css"));
612 return NS_OK;
615 nsresult
616 nsOperaProfileMigrator::CopyCookies(PRBool aReplace)
618 nsresult rv = NS_OK;
620 nsCOMPtr<nsIFile> temp;
621 mOperaProfile->Clone(getter_AddRefs(temp));
622 nsCOMPtr<nsILocalFile> historyFile(do_QueryInterface(temp));
624 historyFile->Append(OPERA_COOKIES_FILE_NAME);
626 nsCOMPtr<nsIInputStream> fileStream;
627 NS_NewLocalFileInputStream(getter_AddRefs(fileStream), historyFile);
628 if (!fileStream)
629 return NS_ERROR_OUT_OF_MEMORY;
631 nsOperaCookieMigrator* ocm = new nsOperaCookieMigrator(fileStream);
632 if (!ocm)
633 return NS_ERROR_OUT_OF_MEMORY;
635 rv = ocm->Migrate();
637 if (ocm) {
638 delete ocm;
639 ocm = nsnull;
642 return rv;
645 nsOperaCookieMigrator::nsOperaCookieMigrator(nsIInputStream* aSourceStream) :
646 mAppVersion(0), mFileVersion(0), mTagTypeLength(0), mPayloadTypeLength(0),
647 mCookieOpen(PR_FALSE), mCurrHandlingInfo(0)
649 mStream = do_CreateInstance("@mozilla.org/binaryinputstream;1");
650 if (mStream)
651 mStream->SetInputStream(aSourceStream);
653 mCurrCookie.isSecure = PR_FALSE;
654 mCurrCookie.expiryTime = 0;
657 nsOperaCookieMigrator::~nsOperaCookieMigrator()
659 if (mStream)
660 mStream->SetInputStream(nsnull);
664 nsresult
665 nsOperaCookieMigrator::Migrate()
667 if (!mStream)
668 return NS_ERROR_FAILURE;
670 nsresult rv;
672 rv = ReadHeader();
673 if (NS_FAILED(rv))
674 return NS_OK;
676 nsCOMPtr<nsICookieManager2> manager(do_GetService(NS_COOKIEMANAGER_CONTRACTID));
677 nsCOMPtr<nsIPermissionManager> permissionManager(do_GetService("@mozilla.org/permissionmanager;1"));
679 PRUint8 tag;
680 PRUint16 length, segmentLength;
682 char* buf = nsnull;
683 do {
684 if (NS_FAILED(mStream->Read8(&tag)))
685 return NS_OK; // EOF.
687 switch (tag) {
688 case BEGIN_DOMAIN_SEGMENT:
689 mStream->Read16(&length);
690 break;
691 case DOMAIN_COMPONENT:
693 mStream->Read16(&length);
695 mStream->ReadBytes(length, &buf);
696 buf = (char*)nsMemory::Realloc(buf, length+1);
697 buf[length] = '\0';
698 mDomainStack.AppendElement((void*)buf);
700 break;
701 case END_DOMAIN_SEGMENT:
703 if (mCurrHandlingInfo)
704 AddCookieOverride(permissionManager);
706 // Pop the domain stack
707 PRUint32 count = mDomainStack.Count();
708 if (count > 0) {
709 char* segment = (char*)mDomainStack.ElementAt(count - 1);
710 if (segment)
711 nsMemory::Free(segment);
712 mDomainStack.RemoveElementAt(count - 1);
715 break;
717 case BEGIN_PATH_SEGMENT:
718 mStream->Read16(&length);
719 break;
720 case PATH_COMPONENT:
722 mStream->Read16(&length);
724 mStream->ReadBytes(length, &buf);
725 buf = (char*)nsMemory::Realloc(buf, length+1);
726 buf[length] = '\0';
727 mPathStack.AppendElement((void*)buf);
729 break;
730 case END_PATH_SEGMENT:
732 // Add the last remaining cookie for this path.
733 if (mCookieOpen)
734 AddCookie(manager);
736 // We receive one "End Path Segment" even if the path stack is empty
737 // i.e. telling us that we are done processing cookies for "/"
739 // Pop the path stack
740 PRUint32 count = mPathStack.Count();
741 if (count > 0) {
742 char* segment = (char*)mPathStack.ElementAt(count - 1);
743 if (segment)
744 nsMemory::Free(segment);
745 mPathStack.RemoveElementAt(count - 1);
748 break;
750 case FILTERING_INFO:
751 mStream->Read16(&length);
752 mStream->Read8(&mCurrHandlingInfo);
753 break;
754 case PATH_HANDLING_INFO:
755 case THIRD_PARTY_HANDLING_INFO:
757 mStream->Read16(&length);
758 PRUint8 temp;
759 mStream->Read8(&temp);
761 break;
763 case BEGIN_COOKIE_SEGMENT:
765 // Be sure to save the last cookie before overwriting the buffers
766 // with data from subsequent cookies.
767 if (mCookieOpen)
768 AddCookie(manager);
770 mStream->Read16(&segmentLength);
771 mCookieOpen = PR_TRUE;
773 break;
774 case COOKIE_ID:
776 mStream->Read16(&length);
777 mStream->ReadBytes(length, &buf);
778 buf = (char*)nsMemory::Realloc(buf, length+1);
779 buf[length] = '\0';
780 mCurrCookie.id.Assign(buf);
781 if (buf) {
782 nsMemory::Free(buf);
783 buf = nsnull;
786 break;
787 case COOKIE_DATA:
789 mStream->Read16(&length);
790 mStream->ReadBytes(length, &buf);
791 buf = (char*)nsMemory::Realloc(buf, length+1);
792 buf[length] = '\0';
793 mCurrCookie.data.Assign(buf);
794 if (buf) {
795 nsMemory::Free(buf);
796 buf = nsnull;
799 break;
800 case COOKIE_EXPIRY:
801 mStream->Read16(&length);
802 mStream->Read32(reinterpret_cast<PRUint32*>(&(mCurrCookie.expiryTime)));
803 break;
804 case COOKIE_SECURE:
805 mCurrCookie.isSecure = PR_TRUE;
806 break;
808 // We don't support any of these fields but we must read them in
809 // to advance the stream cursor.
810 case COOKIE_LASTUSED:
812 mStream->Read16(&length);
813 PRTime temp;
814 mStream->Read32(reinterpret_cast<PRUint32*>(&temp));
816 break;
817 case COOKIE_COMMENT:
818 case COOKIE_COMMENT_URL:
819 case COOKIE_V1_DOMAIN:
820 case COOKIE_V1_PATH:
821 case COOKIE_V1_PORT_LIMITATIONS:
823 mStream->Read16(&length);
824 mStream->ReadBytes(length, &buf);
825 if (buf) {
826 nsMemory::Free(buf);
827 buf = nsnull;
830 break;
831 case COOKIE_VERSION:
833 mStream->Read16(&length);
834 PRUint8 temp;
835 mStream->Read8(&temp);
837 break;
838 case COOKIE_OTHERFLAG_1:
839 case COOKIE_OTHERFLAG_2:
840 case COOKIE_OTHERFLAG_3:
841 case COOKIE_OTHERFLAG_4:
842 case COOKIE_OTHERFLAG_5:
843 case COOKIE_OTHERFLAG_6:
844 break;
847 while (1);
849 // Make sure the path and domain stacks are clear.
850 char* segment = nsnull;
851 PRUint32 i;
852 PRUint32 count = mPathStack.Count();
853 for (i = 0; i < count; ++i) {
854 segment = (char*)mPathStack.ElementAt(i);
855 if (segment) {
856 nsMemory::Free(segment);
857 segment = nsnull;
860 count = mDomainStack.Count();
861 for (i = 0; i < count; ++i) {
862 segment = (char*)mDomainStack.ElementAt(i);
863 if (segment) {
864 nsMemory::Free(segment);
865 segment = nsnull;
869 return NS_OK;
872 nsresult
873 nsOperaCookieMigrator::AddCookieOverride(nsIPermissionManager* aManager)
875 nsresult rv;
877 nsCString domain;
878 SynthesizeDomain(getter_Copies(domain));
879 nsCOMPtr<nsIURI> uri(do_CreateInstance("@mozilla.org/network/standard-url;1"));
880 if (!uri)
881 return NS_ERROR_OUT_OF_MEMORY;
882 uri->SetHost(domain);
884 rv = aManager->Add(uri, "cookie",
885 (mCurrHandlingInfo == 1 || mCurrHandlingInfo == 3) ? nsIPermissionManager::ALLOW_ACTION :
886 nsIPermissionManager::DENY_ACTION);
888 mCurrHandlingInfo = 0;
890 return rv;
894 nsresult
895 nsOperaCookieMigrator::AddCookie(nsICookieManager2* aManager)
897 // This is where we use the information gathered in all the other
898 // states to add a cookie to the Firebird/Firefox Cookie Manager.
899 nsCString domain;
900 SynthesizeDomain(getter_Copies(domain));
902 nsCString path;
903 SynthesizePath(getter_Copies(path));
905 mCookieOpen = PR_FALSE;
907 nsresult rv = aManager->Add(domain,
908 path,
909 mCurrCookie.id,
910 mCurrCookie.data,
911 mCurrCookie.isSecure,
912 PR_FALSE, // isHttpOnly
913 PR_FALSE, // isSession
914 PRInt64(mCurrCookie.expiryTime));
916 mCurrCookie.isSecure = 0;
917 mCurrCookie.expiryTime = 0;
919 return rv;
922 void
923 nsOperaCookieMigrator::SynthesizePath(char** aResult)
925 PRUint32 count = mPathStack.Count();
926 nsCAutoString synthesizedPath("/");
927 for (PRUint32 i = 0; i < count; ++i) {
928 synthesizedPath.Append((char*)mPathStack.ElementAt(i));
929 if (i != count-1)
930 synthesizedPath.Append("/");
932 if (synthesizedPath.IsEmpty())
933 synthesizedPath.Assign("/");
935 *aResult = ToNewCString(synthesizedPath);
938 void
939 nsOperaCookieMigrator::SynthesizeDomain(char** aResult)
941 PRUint32 count = mDomainStack.Count();
942 if (count == 0)
943 return;
945 nsCAutoString synthesizedDomain;
946 for (PRInt32 i = (PRInt32)count - 1; i >= 0; --i) {
947 synthesizedDomain.Append((char*)mDomainStack.ElementAt((PRUint32)i));
948 if (i != 0)
949 synthesizedDomain.Append(".");
952 *aResult = ToNewCString(synthesizedDomain);
955 nsresult
956 nsOperaCookieMigrator::ReadHeader()
958 mStream->Read32(&mAppVersion);
959 mStream->Read32(&mFileVersion);
961 if (mAppVersion & 0x1000 && mFileVersion & 0x2000) {
962 mStream->Read16(&mTagTypeLength);
963 mStream->Read16(&mPayloadTypeLength);
965 return NS_OK;
967 return NS_ERROR_FAILURE;
970 nsresult
971 nsOperaProfileMigrator::CopyHistory(PRBool aReplace)
973 nsresult rv;
974 nsCOMPtr<nsINavHistoryService> history = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
975 NS_ENSURE_SUCCESS(rv, rv);
977 return history->RunInBatchMode(this, nsnull);
980 NS_IMETHODIMP
981 nsOperaProfileMigrator::RunBatched(nsISupports* aUserData)
983 nsCOMPtr<nsIBrowserHistory> hist(do_GetService(NS_GLOBALHISTORY2_CONTRACTID));
985 nsCOMPtr<nsIFile> temp;
986 mOperaProfile->Clone(getter_AddRefs(temp));
987 nsCOMPtr<nsILocalFile> historyFile(do_QueryInterface(temp));
988 historyFile->Append(OPERA_HISTORY_FILE_NAME);
990 nsCOMPtr<nsIInputStream> fileStream;
991 NS_NewLocalFileInputStream(getter_AddRefs(fileStream), historyFile);
992 if (!fileStream) return NS_ERROR_OUT_OF_MEMORY;
994 nsCOMPtr<nsILineInputStream> lineStream = do_QueryInterface(fileStream);
996 nsCAutoString buffer, url;
997 nsAutoString title;
998 PRTime lastVisitDate;
999 PRBool moreData = PR_FALSE;
1001 enum { TITLE, URL, LASTVISIT } state = TITLE;
1003 // Format is "title\nurl\nlastvisitdate"
1004 do {
1005 nsresult rv = lineStream->ReadLine(buffer, &moreData);
1006 if (NS_FAILED(rv))
1007 return rv;
1009 switch (state) {
1010 case TITLE:
1011 CopyUTF8toUTF16(buffer, title);
1012 state = URL;
1013 break;
1014 case URL:
1015 url = buffer;
1016 state = LASTVISIT;
1017 break;
1018 case LASTVISIT:
1019 // Opera time format is a second offset, PRTime is a microsecond offset
1020 nsresult err;
1021 lastVisitDate = buffer.ToInteger(&err);
1023 PRInt64 temp, million;
1024 LL_I2L(temp, lastVisitDate);
1025 LL_I2L(million, PR_USEC_PER_SEC);
1026 LL_MUL(lastVisitDate, temp, million);
1028 nsCOMPtr<nsIURI> uri;
1029 NS_NewURI(getter_AddRefs(uri), url);
1030 if (uri)
1031 hist->AddPageWithDetails(uri, title.get(), lastVisitDate);
1033 state = TITLE;
1034 break;
1037 while (moreData);
1039 return NS_OK;
1042 nsresult
1043 nsOperaProfileMigrator::CopyBookmarks(PRBool aReplace)
1045 // Find Opera Bookmarks
1046 nsCOMPtr<nsIFile> operaBookmarks;
1047 mOperaProfile->Clone(getter_AddRefs(operaBookmarks));
1048 operaBookmarks->Append(OPERA_BOOKMARKS_FILE_NAME);
1050 nsCOMPtr<nsIInputStream> fileInputStream;
1051 NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), operaBookmarks);
1052 if (!fileInputStream) return NS_ERROR_OUT_OF_MEMORY;
1054 nsCOMPtr<nsILineInputStream> lineInputStream(do_QueryInterface(fileInputStream));
1056 nsresult rv;
1057 nsCOMPtr<nsINavBookmarksService> bms(do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv));
1058 NS_ENSURE_SUCCESS(rv, rv);
1059 PRInt64 root;
1060 rv = bms->GetBookmarksMenuFolder(&root);
1061 NS_ENSURE_SUCCESS(rv, rv);
1062 PRInt64 parentFolder = root;
1064 nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID));
1065 nsCOMPtr<nsIStringBundle> bundle;
1066 bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
1067 if (!aReplace) {
1068 nsString sourceNameOpera;
1069 bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(),
1070 getter_Copies(sourceNameOpera));
1072 const PRUnichar* sourceNameStrings[] = { sourceNameOpera.get() };
1073 nsString importedOperaHotlistTitle;
1074 bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
1075 sourceNameStrings, 1,
1076 getter_Copies(importedOperaHotlistTitle));
1078 bms->CreateFolder(parentFolder, NS_ConvertUTF16toUTF8(importedOperaHotlistTitle),
1079 nsINavBookmarksService::DEFAULT_INDEX, &parentFolder);
1081 else {
1082 nsCOMPtr<nsIFile> profile;
1083 GetProfilePath(nsnull, profile);
1084 rv = InitializeBookmarks(profile);
1085 NS_ENSURE_SUCCESS(rv, rv);
1088 #if defined(XP_WIN) || (defined(XP_UNIX) && !defined(XP_MACOSX))
1089 printf("*** about to copy smart keywords\n");
1090 CopySmartKeywords(bms, bundle, parentFolder);
1091 printf("*** done copying smart keywords\n");
1092 #endif
1094 PRInt64 toolbar;
1095 rv = bms->GetToolbarFolder(&toolbar);
1096 NS_ENSURE_SUCCESS(rv, rv);
1098 rv = ParseBookmarksFolder(lineInputStream, parentFolder, toolbar, bms);
1099 NS_ENSURE_SUCCESS(rv, rv);
1101 // after importing the favorites,
1102 // we need to set this pref so that on startup
1103 // we don't blow away what we just imported
1104 nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID));
1105 NS_ENSURE_TRUE(pref, NS_ERROR_FAILURE);
1106 rv = pref->SetBoolPref("browser.places.importBookmarksHTML", PR_FALSE);
1107 NS_ENSURE_SUCCESS(rv, rv);
1108 return NS_OK;
1111 #if defined(XP_WIN) || (defined(XP_UNIX) && !defined(XP_MACOSX))
1112 nsresult
1113 nsOperaProfileMigrator::CopySmartKeywords(nsINavBookmarksService* aBMS,
1114 nsIStringBundle* aBundle,
1115 PRInt64 aParentFolder)
1117 nsresult rv;
1119 nsCOMPtr<nsIFile> smartKeywords;
1120 mOperaProfile->Clone(getter_AddRefs(smartKeywords));
1121 smartKeywords->Append(NS_LITERAL_STRING("search.ini"));
1123 nsCOMPtr<nsILocalFile> lf(do_QueryInterface(smartKeywords));
1124 if (!lf)
1125 return NS_OK;
1127 nsINIParser parser;
1128 rv = parser.Init(lf);
1129 if (NS_FAILED(rv))
1130 return NS_OK;
1132 nsString sourceNameOpera;
1133 aBundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(),
1134 getter_Copies(sourceNameOpera));
1136 const PRUnichar* sourceNameStrings[] = { sourceNameOpera.get() };
1137 nsString importedSearchUrlsTitle;
1138 aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchURLsFolder").get(),
1139 sourceNameStrings, 1,
1140 getter_Copies(importedSearchUrlsTitle));
1142 PRInt64 keywordsFolder;
1143 rv = aBMS->CreateFolder(aParentFolder, NS_ConvertUTF16toUTF8(importedSearchUrlsTitle),
1144 nsINavBookmarksService::DEFAULT_INDEX, &keywordsFolder);
1145 NS_ENSURE_SUCCESS(rv, rv);
1147 PRInt32 sectionIndex = 1;
1148 nsCAutoString name, url, keyword;
1149 do {
1150 nsCAutoString section("Search Engine ");
1151 section.AppendInt(sectionIndex++);
1153 rv = parser.GetString(section.get(), "Name", name);
1154 if (NS_FAILED(rv))
1155 break;
1157 rv = parser.GetString(section.get(), "URL", url);
1158 if (NS_FAILED(rv))
1159 continue;
1161 rv = parser.GetString(section.get(), "Key", keyword);
1162 if (NS_FAILED(rv))
1163 continue;
1165 PRInt32 post;
1166 rv = GetInteger(parser, section.get(), "Is post", &post);
1167 if (NS_SUCCEEDED(rv) && post)
1168 continue;
1170 if (url.IsEmpty() || keyword.IsEmpty() || name.IsEmpty())
1171 continue;
1173 PRUint32 length = name.Length();
1174 PRInt32 index = 0;
1175 do {
1176 index = name.FindChar('&', index);
1177 if (index >= length - 2)
1178 break;
1180 // Assume "&&" is an escaped ampersand in the search query title.
1181 if (name.CharAt(index + 1) == '&') {
1182 name.Cut(index, 1);
1183 index += 2;
1184 continue;
1187 name.Cut(index, 1);
1189 while (index < length);
1191 nsCOMPtr<nsIURI> uri;
1192 NS_NewURI(getter_AddRefs(uri), url.get());
1193 if (!uri)
1194 return NS_ERROR_OUT_OF_MEMORY;
1196 nsCAutoString hostCStr;
1197 uri->GetHost(hostCStr);
1198 NS_ConvertASCIItoUTF16 host(hostCStr);
1200 const PRUnichar* descStrings[] = { NS_ConvertUTF8toUTF16(keyword).get(), host.get() };
1201 nsString keywordDesc;
1202 aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchUrlDesc").get(),
1203 descStrings, 2, getter_Copies(keywordDesc));
1205 PRInt64 newId;
1206 rv = aBMS->InsertBookmark(keywordsFolder, uri,
1207 nsINavBookmarksService::DEFAULT_INDEX,
1208 name, &newId);
1209 NS_ENSURE_SUCCESS(rv, rv);
1210 // TODO -- set bookmark keyword to keyword and description to keywordDesc.
1212 while (1);
1214 return rv;
1216 #endif
1218 typedef enum { LineType_FOLDER,
1219 LineType_BOOKMARK,
1220 LineType_SEPARATOR,
1221 LineType_NAME,
1222 LineType_URL,
1223 LineType_KEYWORD,
1224 LineType_DESCRIPTION,
1225 LineType_ONTOOLBAR,
1226 LineType_NL,
1227 LineType_OTHER } LineType;
1229 static LineType GetLineType(nsAString& aBuffer, PRUnichar** aData)
1231 if (Substring(aBuffer, 0, 7).Equals(NS_LITERAL_STRING("#FOLDER")))
1232 return LineType_FOLDER;
1233 if (Substring(aBuffer, 0, 4).Equals(NS_LITERAL_STRING("#URL")))
1234 return LineType_BOOKMARK;
1235 if (Substring(aBuffer, 0, 1).Equals(NS_LITERAL_STRING("-")))
1236 return LineType_SEPARATOR;
1237 if (Substring(aBuffer, 1, 5).Equals(NS_LITERAL_STRING("NAME="))) {
1238 const nsAString& data = Substring(aBuffer, 6, aBuffer.Length() - 6);
1239 *aData = ToNewUnicode(data);
1240 return LineType_NAME;
1242 if (Substring(aBuffer, 1, 4).Equals(NS_LITERAL_STRING("URL="))) {
1243 const nsAString& data = Substring(aBuffer, 5, aBuffer.Length() - 5);
1244 *aData = ToNewUnicode(data);
1245 return LineType_URL;
1247 if (Substring(aBuffer, 1, 12).Equals(NS_LITERAL_STRING("DESCRIPTION="))) {
1248 const nsAString& data = Substring(aBuffer, 13, aBuffer.Length() - 13);
1249 *aData = ToNewUnicode(data);
1250 return LineType_DESCRIPTION;
1252 if (Substring(aBuffer, 1, 11).Equals(NS_LITERAL_STRING("SHORT NAME="))) {
1253 const nsAString& data = Substring(aBuffer, 12, aBuffer.Length() - 12);
1254 *aData = ToNewUnicode(data);
1255 return LineType_KEYWORD;
1257 if (Substring(aBuffer, 1, 15).Equals(NS_LITERAL_STRING("ON PERSONALBAR="))) {
1258 const nsAString& data = Substring(aBuffer, 16, aBuffer.Length() - 16);
1259 *aData = ToNewUnicode(data);
1260 return LineType_ONTOOLBAR;
1262 if (aBuffer.IsEmpty())
1263 return LineType_NL; // Newlines separate bookmarks
1264 return LineType_OTHER;
1267 typedef enum { EntryType_BOOKMARK, EntryType_FOLDER } EntryType;
1269 nsresult
1270 nsOperaProfileMigrator::ParseBookmarksFolder(nsILineInputStream* aStream,
1271 PRInt64 aParent,
1272 PRInt64 aToolbar,
1273 nsINavBookmarksService* aBMS)
1275 nsresult rv;
1276 PRBool moreData = PR_FALSE;
1277 nsAutoString buffer;
1278 EntryType entryType = EntryType_BOOKMARK;
1279 nsAutoString keyword, description;
1280 nsCAutoString url, name;
1281 PRBool onToolbar = PR_FALSE;
1282 do {
1283 nsCAutoString cBuffer;
1284 rv = aStream->ReadLine(cBuffer, &moreData);
1285 if (NS_FAILED(rv)) return rv;
1287 CopyUTF8toUTF16(cBuffer, buffer);
1288 nsString data;
1289 LineType type = GetLineType(buffer, getter_Copies(data));
1290 switch(type) {
1291 case LineType_FOLDER:
1292 entryType = EntryType_FOLDER;
1293 break;
1294 case LineType_BOOKMARK:
1295 entryType = EntryType_BOOKMARK;
1296 break;
1297 case LineType_SEPARATOR:
1298 // If we're here, we need to break out of the loop for the current folder,
1299 // essentially terminating this instance of ParseBookmarksFolder and return
1300 // to the calling function, which is either ParseBookmarksFolder for a parent
1301 // folder, or CopyBookmarks (which means we're done parsing all bookmarks).
1302 goto done;
1303 case LineType_NAME:
1304 name.Assign(NS_ConvertUTF16toUTF8(data));
1305 break;
1306 case LineType_URL:
1307 url.Assign(NS_ConvertUTF16toUTF8(data));
1308 break;
1309 case LineType_KEYWORD:
1310 keyword = data;
1311 break;
1312 case LineType_DESCRIPTION:
1313 description = data;
1314 break;
1315 case LineType_ONTOOLBAR:
1316 if (NS_LITERAL_STRING("YES").Equals(data))
1317 onToolbar = PR_TRUE;
1318 break;
1319 case LineType_NL: {
1320 // XXX We don't know for sure how Opera deals with IDN hostnames in URL.
1321 // Assuming it's in UTF-8 is rather safe because it covers two cases
1322 // (UTF-8 and ASCII) out of three cases (the last is a non-UTF-8
1323 // multibyte encoding).
1324 // XXX Todo: |description| is not saved.
1325 if (entryType == EntryType_BOOKMARK) {
1326 if (!name.IsEmpty() && !url.IsEmpty()) {
1327 nsCOMPtr<nsIURI> uri;
1328 rv = NS_NewURI(getter_AddRefs(uri), url);
1329 if (NS_FAILED(rv))
1330 continue;
1331 PRInt64 id;
1332 rv = aBMS->InsertBookmark(onToolbar ? aToolbar : aParent,
1333 uri, nsINavBookmarksService::DEFAULT_INDEX,
1334 name, &id);
1335 if (NS_FAILED(rv))
1336 continue;
1337 name.Truncate();
1338 url.Truncate();
1339 keyword.Truncate();
1340 description.Truncate();
1341 onToolbar = PR_FALSE;
1344 else if (entryType == EntryType_FOLDER) {
1345 if (!name.IsEmpty()) {
1346 PRInt64 newFolder;
1347 rv = aBMS->CreateFolder(onToolbar ? aToolbar : aParent,
1348 name, nsINavBookmarksService::DEFAULT_INDEX, &newFolder);
1349 if (NS_FAILED(rv))
1350 continue;
1351 rv = ParseBookmarksFolder(aStream, newFolder, aToolbar, aBMS);
1352 name.Truncate();
1355 break;
1357 case LineType_OTHER:
1358 break;
1361 while (moreData);
1363 done:
1364 return rv;
1367 void
1368 nsOperaProfileMigrator::GetOperaProfile(const PRUnichar* aProfile, nsILocalFile** aFile)
1370 nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
1371 nsCOMPtr<nsILocalFile> file;
1372 #ifdef XP_WIN
1373 fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
1375 // Opera profile lives under %APP_DATA%\Opera\<operaver>\profile
1376 file->Append(OPERA_PREFERENCES_FOLDER_NAME);
1377 file->Append(nsDependentString(aProfile));
1378 file->Append(NS_LITERAL_STRING("profile"));
1379 #elif defined (XP_MACOSX)
1380 fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
1382 file->Append(NS_LITERAL_STRING("Preferences"));
1383 file->Append(OPERA_PREFERENCES_FOLDER_NAME);
1384 #elif defined (XP_UNIX)
1385 fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
1387 file->Append(OPERA_PREFERENCES_FOLDER_NAME);
1388 #endif
1390 *aFile = file;
1391 NS_ADDREF(*aFile);