nsOperaProfileMigrator.cpp
Go to the documentation of this file.
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
4  *
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/
9  *
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.
14  *
15  * The Original Code is The Browser Profile Migrator.
16  *
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.
20  *
21  * Contributor(s):
22  * Ben Goodger <ben@bengoodger.com>
23  *
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.
35  *
36  * ***** END LICENSE BLOCK ***** */
37 
38 #include "nsAppDirectoryServiceDefs.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
70 
71 #define MIGRATION_BUNDLE "chrome://browser/locale/migration/migration.properties"
72 
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
96 
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
101 
103 // nsBrowserProfileMigrator
104 
106 
108 {
109  mObserverService = do_GetService("@mozilla.org/observer-service;1");
110 }
111 
113 {
114 }
115 
116 NS_IMETHODIMP
117 nsOperaProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
118 {
119  nsresult rv = NS_OK;
120  PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;
121 
122  if (aStartup) {
123  rv = aStartup->DoStartup();
124  NS_ENSURE_SUCCESS(rv, rv);
125  }
126 
127  if (!mOperaProfile)
128  GetOperaProfile(aProfile, getter_AddRefs(mOperaProfile));
129 
131 
136 
138 
139  return rv;
140 }
141 
142 NS_IMETHODIMP
143 nsOperaProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
144  PRBool aReplace,
145  PRUint16* aResult)
146 {
147  *aResult = 0;
148  if (!mOperaProfile) {
149  GetOperaProfile(aProfile, getter_AddRefs(mOperaProfile));
150  if (!mOperaProfile)
151  return NS_ERROR_FILE_NOT_FOUND;
152  }
153 
154  MigrationData data[] = { { ToNewUnicode(OPERA_PREFERENCES_FILE_NAME),
156  PR_FALSE },
157  { ToNewUnicode(OPERA_COOKIES_FILE_NAME),
159  PR_FALSE },
160  { ToNewUnicode(OPERA_HISTORY_FILE_NAME),
162  PR_FALSE },
163  { ToNewUnicode(OPERA_BOOKMARKS_FILE_NAME),
165  PR_FALSE } };
166 
167  // Frees file name strings allocated above.
168  GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
169  aReplace, mOperaProfile, aResult);
170 
171  return NS_OK;
172 }
173 
174 NS_IMETHODIMP
175 nsOperaProfileMigrator::GetSourceExists(PRBool* aResult)
176 {
177  nsCOMPtr<nsISupportsArray> profiles;
178  GetSourceProfiles(getter_AddRefs(profiles));
179 
180  if (profiles) {
181  PRUint32 count;
182  profiles->Count(&count);
183  *aResult = count > 0;
184  }
185  else
186  *aResult = PR_FALSE;
187 
188  return NS_OK;
189 }
190 
191 NS_IMETHODIMP
192 nsOperaProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
193 {
194  nsCOMPtr<nsISupportsArray> profiles;
195  GetSourceProfiles(getter_AddRefs(profiles));
196 
197 #ifdef XP_WIN
198  if (profiles) {
199  PRUint32 count;
200  profiles->Count(&count);
201  *aResult = count > 1;
202  }
203  else
204 #endif
205  *aResult = PR_FALSE;
206 
207  return NS_OK;
208 }
209 
210 NS_IMETHODIMP
211 nsOperaProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
212 {
213  if (!mProfiles) {
214  nsresult rv;
215 
216  mProfiles = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
217  if (NS_FAILED(rv)) return rv;
218 
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));
223 
224  // Opera profile lives under %APP_DATA%\Opera<operaver>\profile
225  file->Append(OPERA_PREFERENCES_FOLDER_NAME);
226 
227  nsCOMPtr<nsISimpleEnumerator> e;
228  rv = file->GetDirectoryEntries(getter_AddRefs(e));
229  if (NS_FAILED(rv))
230  return rv;
231 
232  PRBool hasMore;
233  e->HasMoreElements(&hasMore);
234  while (hasMore) {
235  nsCOMPtr<nsILocalFile> curr;
236  e->GetNext(getter_AddRefs(curr));
237 
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);
246  }
247 
248  e->HasMoreElements(&hasMore);
249  }
250 #elif defined (XP_MACOSX)
251  fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
252 
253  file->Append(NS_LITERAL_STRING("Preferences"));
254  file->Append(OPERA_PREFERENCES_FOLDER_NAME);
255 
256  PRBool exists;
257  file->Exists(&exists);
258 
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);
263  }
264 #elif defined (XP_UNIX)
265  fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
266 
267  file->Append(OPERA_PREFERENCES_FOLDER_NAME);
268 
269  PRBool exists;
270  file->Exists(&exists);
271 
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);
276  }
277 #endif
278  }
279 
280  *aResult = mProfiles;
281  NS_IF_ADDREF(*aResult);
282  return NS_OK;
283 }
284 
285 NS_IMETHODIMP
286 nsOperaProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
287 {
288  nsresult rv;
289  nsCAutoString val;
290 
291  nsCOMPtr<nsIFile> operaPrefs;
292  mOperaProfile->Clone(getter_AddRefs(operaPrefs));
293  operaPrefs->Append(OPERA_PREFERENCES_FILE_NAME);
294 
295  nsCOMPtr<nsILocalFile> lf(do_QueryInterface(operaPrefs));
296  NS_ENSURE_TRUE(lf, NS_ERROR_UNEXPECTED);
297 
298  nsINIParser parser;
299  rv = parser.Init(lf);
300  NS_ENSURE_SUCCESS(rv, rv);
301 
302  rv = parser.GetString("User Prefs",
303  "Home URL",
304  val);
305 
306  if (NS_SUCCEEDED(rv))
307  aResult.Assign(val);
308 
309  return NS_OK;
310 }
311 
312 
313 #define _OPM(type) nsOperaProfileMigrator::type
314 
315 static
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 } },
326 
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 } },
331 
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 } },
335 
336  { "Extensions", "Scripting", _OPM(BOOL), "javascript.enabled", _OPM(SetBool), PR_FALSE, { -1 } }
337 };
338 
339 nsresult
341 {
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);
346 }
347 
348 nsresult
350 {
351  PrefTransform* xform = (PrefTransform*)aTransform;
352  PRInt32 val = (xform->intValue == 3) ? 0 : (xform->intValue == 0) ? 2 : 1;
353  return aBranch->SetIntPref(xform->targetPrefName, val);
354 }
355 
356 nsresult
358 {
359  PrefTransform* xform = (PrefTransform*)aTransform;
360  return aBranch->SetIntPref(xform->targetPrefName, xform->boolValue ? 2 : 0);
361 }
362 
363 nsresult
365 {
366  PrefTransform* xform = (PrefTransform*)aTransform;
367  return aBranch->SetIntPref(xform->targetPrefName, xform->boolValue ? 1 : 2);
368 }
369 
370 nsresult
372 {
373  PrefTransform* xform = (PrefTransform*)aTransform;
374  return aBranch->SetBoolPref(xform->targetPrefName, xform->boolValue);
375 }
376 
377 nsresult
379 {
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);
385 }
386 
387 nsresult
389 {
390  PrefTransform* xform = (PrefTransform*)aTransform;
391  return aBranch->SetIntPref(xform->targetPrefName, xform->intValue);
392 }
393 
394 nsresult
396 {
397  PrefTransform* xform = (PrefTransform*)aTransform;
398  return aBranch->SetCharPref(xform->targetPrefName, xform->stringValue);
399 }
400 
401 nsresult
403 {
404  nsresult rv;
405 
406  nsCOMPtr<nsIFile> operaPrefs;
407  mOperaProfile->Clone(getter_AddRefs(operaPrefs));
408  operaPrefs->Append(OPERA_PREFERENCES_FILE_NAME);
409 
410  nsCOMPtr<nsILocalFile> lf(do_QueryInterface(operaPrefs));
411  NS_ENSURE_TRUE(lf, NS_ERROR_UNEXPECTED);
412 
413  nsINIParser parser;
414  rv = parser.Init(lf);
415  NS_ENSURE_SUCCESS(rv, rv);
416 
417  nsCOMPtr<nsIPrefBranch> branch(do_GetService(NS_PREFSERVICE_CONTRACTID));
418 
419  // Traverse the standard transforms
420  PrefTransform* transform;
421  PrefTransform* end = gTransforms + sizeof(gTransforms)/sizeof(PrefTransform);
422 
423  const char* lastSectionName = nsnull;
424  for (transform = gTransforms; transform < end; ++transform) {
425  if (transform->sectionName)
426  lastSectionName = transform->sectionName;
427 
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;
433 
434  transform->prefHasValue = PR_TRUE;
435  transform->prefSetterFunc(transform, branch);
436  }
437  if (colorString)
438  free(colorString);
439  }
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);
453  }
454  break;
455  case _OPM(BOOL): {
456  transform->boolValue = val.ToInteger(&strerr) != 0;
457  }
458  break;
459  default:
460  break;
461  }
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;
467  }
468  }
469  }
470  }
471 
472  // Copy Proxy Settings
473  CopyProxySettings(parser, branch);
474 
475  // Copy User Content Sheet
476  if (aReplace)
477  CopyUserContentSheet(parser);
478 
479  return NS_OK;
480 }
481 
482 nsresult
484  nsIPrefBranch* aBranch)
485 {
486  nsresult rv;
487 
488  PRInt32 networkProxyType = 0;
489 
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;
502  }
503 
504  sprintf(serverBuf, "%s Server", protocols[i]);
505  nsCAutoString proxyServer;
506  rv = aParser.GetString("Proxy", serverBuf, proxyServer);
507  if (NS_FAILED(rv))
508  continue;
509 
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);
515  }
516 
517  GetInteger(aParser, "Proxy", "Use Automatic Proxy Configuration", &enabled);
518  if (enabled)
519  networkProxyType = 2;
520 
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());
526 
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);
534  }
535 
536  aBranch->SetIntPref("network.proxy.type", networkProxyType);
537 
538  return NS_OK;
539 }
540 
541 nsresult
543  const char* aSectionName,
544  const char* aKeyName,
545  PRInt32* aResult)
546 {
547  nsCAutoString val;
548 
549  nsresult rv = aParser.GetString(aSectionName, aKeyName, val);
550  if (NS_FAILED(rv))
551  return rv;
552 
553  *aResult = val.ToInteger(&rv);
554 
555  return rv;
556 }
557 
558 
559 nsresult
561  const char* aSectionName, char** aResult)
562 {
563  nsresult rv;
564  PRInt32 r, g, b;
565 
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.
571 
572  *aResult = (char*)malloc(sizeof(char) * 8);
573  if (!*aResult)
574  return NS_ERROR_OUT_OF_MEMORY;
575 
576  sprintf(*aResult, "#%02X%02X%02X", r, g, b);
577 
578  return NS_OK;
579 }
580 
581 nsresult
583 {
584  nsresult rv;
585 
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;
590 
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;
597 
598  PRBool exists;
599  rv = userContentCSSFile->Exists(&exists);
600  if (NS_FAILED(rv) || !exists)
601  return NS_OK;
602 
603  nsCOMPtr<nsIFile> profileChromeDir;
604  NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR,
605  getter_AddRefs(profileChromeDir));
606  if (!profileChromeDir)
607  return NS_OK;
608 
609  userContentCSSFile->CopyToNative(profileChromeDir,
610  NS_LITERAL_CSTRING("userContent.css"));
611 
612  return NS_OK;
613 }
614 
615 nsresult
617 {
618  nsresult rv = NS_OK;
619 
620  nsCOMPtr<nsIFile> temp;
621  mOperaProfile->Clone(getter_AddRefs(temp));
622  nsCOMPtr<nsILocalFile> historyFile(do_QueryInterface(temp));
623 
624  historyFile->Append(OPERA_COOKIES_FILE_NAME);
625 
626  nsCOMPtr<nsIInputStream> fileStream;
627  NS_NewLocalFileInputStream(getter_AddRefs(fileStream), historyFile);
628  if (!fileStream)
629  return NS_ERROR_OUT_OF_MEMORY;
630 
631  nsOperaCookieMigrator* ocm = new nsOperaCookieMigrator(fileStream);
632  if (!ocm)
633  return NS_ERROR_OUT_OF_MEMORY;
634 
635  rv = ocm->Migrate();
636 
637  if (ocm) {
638  delete ocm;
639  ocm = nsnull;
640  }
641 
642  return rv;
643 }
644 
645 nsOperaCookieMigrator::nsOperaCookieMigrator(nsIInputStream* aSourceStream) :
646  mAppVersion(0), mFileVersion(0), mTagTypeLength(0), mPayloadTypeLength(0),
647  mCookieOpen(PR_FALSE), mCurrHandlingInfo(0)
648 {
649  mStream = do_CreateInstance("@mozilla.org/binaryinputstream;1");
650  if (mStream)
651  mStream->SetInputStream(aSourceStream);
652 
653  mCurrCookie.isSecure = PR_FALSE;
654  mCurrCookie.expiryTime = 0;
655 }
656 
658 {
659  if (mStream)
660  mStream->SetInputStream(nsnull);
661 }
662 
663 
664 nsresult
666 {
667  if (!mStream)
668  return NS_ERROR_FAILURE;
669 
670  nsresult rv;
671 
672  rv = ReadHeader();
673  if (NS_FAILED(rv))
674  return NS_OK;
675 
676  nsCOMPtr<nsICookieManager2> manager(do_GetService(NS_COOKIEMANAGER_CONTRACTID));
677  nsCOMPtr<nsIPermissionManager> permissionManager(do_GetService("@mozilla.org/permissionmanager;1"));
678 
679  PRUint8 tag;
680  PRUint16 length, segmentLength;
681 
682  char* buf = nsnull;
683  do {
684  if (NS_FAILED(mStream->Read8(&tag)))
685  return NS_OK; // EOF.
686 
687  switch (tag) {
689  mStream->Read16(&length);
690  break;
691  case DOMAIN_COMPONENT:
692  {
693  mStream->Read16(&length);
694 
695  mStream->ReadBytes(length, &buf);
696  buf = (char*)nsMemory::Realloc(buf, length+1);
697  buf[length] = '\0';
698  mDomainStack.AppendElement(buf);
699  }
700  break;
701  case END_DOMAIN_SEGMENT:
702  {
703  if (mCurrHandlingInfo)
704  AddCookieOverride(permissionManager);
705 
706  // Pop the domain stack
707  PRUint32 count = mDomainStack.Length();
708  if (count > 0) {
709  char* segment = mDomainStack.ElementAt(count - 1);
710  if (segment)
711  nsMemory::Free(segment);
712  mDomainStack.RemoveElementAt(count - 1);
713  }
714  }
715  break;
716 
717  case BEGIN_PATH_SEGMENT:
718  mStream->Read16(&length);
719  break;
720  case PATH_COMPONENT:
721  {
722  mStream->Read16(&length);
723 
724  mStream->ReadBytes(length, &buf);
725  buf = (char*)nsMemory::Realloc(buf, length+1);
726  buf[length] = '\0';
727  mPathStack.AppendElement(buf);
728  }
729  break;
730  case END_PATH_SEGMENT:
731  {
732  // Add the last remaining cookie for this path.
733  if (mCookieOpen)
734  AddCookie(manager);
735 
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 "/"
738 
739  // Pop the path stack
740  PRUint32 count = mPathStack.Length();
741  if (count > 0) {
742  char* segment = mPathStack.ElementAt(count - 1);
743  if (segment)
744  nsMemory::Free(segment);
745  mPathStack.RemoveElementAt(count - 1);
746  }
747  }
748  break;
749 
750  case FILTERING_INFO:
751  mStream->Read16(&length);
752  mStream->Read8(&mCurrHandlingInfo);
753  break;
754  case PATH_HANDLING_INFO:
756  {
757  mStream->Read16(&length);
758  PRUint8 temp;
759  mStream->Read8(&temp);
760  }
761  break;
762 
764  {
765  // Be sure to save the last cookie before overwriting the buffers
766  // with data from subsequent cookies.
767  if (mCookieOpen)
768  AddCookie(manager);
769 
770  mStream->Read16(&segmentLength);
771  mCookieOpen = PR_TRUE;
772  }
773  break;
774  case COOKIE_ID:
775  {
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;
784  }
785  }
786  break;
787  case COOKIE_DATA:
788  {
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;
797  }
798  }
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;
807 
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:
811  {
812  mStream->Read16(&length);
813  PRTime temp;
814  mStream->Read32(reinterpret_cast<PRUint32*>(&temp));
815  }
816  break;
817  case COOKIE_COMMENT:
818  case COOKIE_COMMENT_URL:
819  case COOKIE_V1_DOMAIN:
820  case COOKIE_V1_PATH:
822  {
823  mStream->Read16(&length);
824  mStream->ReadBytes(length, &buf);
825  if (buf) {
826  nsMemory::Free(buf);
827  buf = nsnull;
828  }
829  }
830  break;
831  case COOKIE_VERSION:
832  {
833  mStream->Read16(&length);
834  PRUint8 temp;
835  mStream->Read8(&temp);
836  }
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;
845  }
846  }
847  while (1);
848 
849  // Make sure the path and domain stacks are clear.
850  char* segment = nsnull;
851  PRUint32 i;
852  PRUint32 count = mPathStack.Length();
853  for (i = 0; i < count; ++i) {
854  segment = mPathStack.ElementAt(i);
855  if (segment) {
856  nsMemory::Free(segment);
857  segment = nsnull;
858  }
859  }
860  count = mDomainStack.Length();
861  for (i = 0; i < count; ++i) {
862  segment = mDomainStack.ElementAt(i);
863  if (segment) {
864  nsMemory::Free(segment);
865  segment = nsnull;
866  }
867  }
868 
869  return NS_OK;
870 }
871 
872 nsresult
874 {
875  nsresult rv;
876 
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);
883 
884  rv = aManager->Add(uri, "cookie",
885  (mCurrHandlingInfo == 1 || mCurrHandlingInfo == 3)
886  ? (PRUint32) nsIPermissionManager::ALLOW_ACTION
887  : (PRUint32) nsIPermissionManager::DENY_ACTION);
888 
889  mCurrHandlingInfo = 0;
890 
891  return rv;
892 }
893 
894 
895 nsresult
896 nsOperaCookieMigrator::AddCookie(nsICookieManager2* aManager)
897 {
898  // This is where we use the information gathered in all the other
899  // states to add a cookie to the Firebird/Firefox Cookie Manager.
900  nsCString domain;
901  SynthesizeDomain(getter_Copies(domain));
902 
903  nsCString path;
904  SynthesizePath(getter_Copies(path));
905 
906  mCookieOpen = PR_FALSE;
907 
908  nsresult rv = aManager->Add(domain,
909  path,
910  mCurrCookie.id,
911  mCurrCookie.data,
912  mCurrCookie.isSecure,
913  PR_FALSE, // isHttpOnly
914  PR_FALSE, // isSession
915  PRInt64(mCurrCookie.expiryTime));
916 
917  mCurrCookie.isSecure = 0;
918  mCurrCookie.expiryTime = 0;
919 
920  return rv;
921 }
922 
923 void
925 {
926  PRUint32 count = mPathStack.Length();
927  nsCAutoString synthesizedPath("/");
928  for (PRUint32 i = 0; i < count; ++i) {
929  synthesizedPath.Append(mPathStack.ElementAt(i));
930  if (i != count-1)
931  synthesizedPath.Append("/");
932  }
933  if (synthesizedPath.IsEmpty())
934  synthesizedPath.Assign("/");
935 
936  *aResult = ToNewCString(synthesizedPath);
937 }
938 
939 void
941 {
942  PRUint32 count = mDomainStack.Length();
943  if (count == 0)
944  return;
945 
946  nsCAutoString synthesizedDomain;
947  for (PRInt32 i = (PRInt32)count - 1; i >= 0; --i) {
948  synthesizedDomain.Append(mDomainStack.ElementAt((PRUint32)i));
949  if (i != 0)
950  synthesizedDomain.Append(".");
951  }
952 
953  *aResult = ToNewCString(synthesizedDomain);
954 }
955 
956 nsresult
958 {
959  mStream->Read32(&mAppVersion);
960  mStream->Read32(&mFileVersion);
961 
962  if (mAppVersion & 0x1000 && mFileVersion & 0x2000) {
963  mStream->Read16(&mTagTypeLength);
964  mStream->Read16(&mPayloadTypeLength);
965 
966  return NS_OK;
967  }
968  return NS_ERROR_FAILURE;
969 }
970 
971 NS_IMETHODIMP
972 nsOperaProfileMigrator::RunBatched(nsISupports* aUserData)
973 {
974  PRUint8 batchAction;
975  nsCOMPtr<nsISupportsPRUint8> strWrapper(do_QueryInterface(aUserData));
976  NS_ASSERTION(strWrapper, "Unable to create nsISupportsPRUint8 wrapper!");
977  nsresult rv = strWrapper->GetData(&batchAction);
978  NS_ENSURE_SUCCESS(rv, rv);
979 
980  switch (batchAction) {
982  rv = CopyHistoryBatched(PR_FALSE);
983  break;
985  rv = CopyHistoryBatched(PR_TRUE);
986  break;
988  rv = CopyBookmarksBatched(PR_FALSE);
989  break;
991  rv = CopyBookmarksBatched(PR_TRUE);
992  break;
993  }
994  NS_ENSURE_SUCCESS(rv, rv);
995 
996  return NS_OK;
997 }
998 
999 nsresult
1001 {
1002  nsresult rv;
1003  nsCOMPtr<nsINavHistoryService> history =
1004  do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
1005  NS_ENSURE_SUCCESS(rv, rv);
1006 
1007  PRUint8 batchAction = aReplace ? BATCH_ACTION_HISTORY_REPLACE
1009  nsCOMPtr<nsISupportsPRUint8> supports =
1010  do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
1011  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
1012  rv = supports->SetData(batchAction);
1013  NS_ENSURE_SUCCESS(rv, rv);
1014 
1015  rv = history->RunInBatchMode(this, supports);
1016  NS_ENSURE_SUCCESS(rv, rv);
1017 
1018  return NS_OK;
1019 }
1020 
1021 nsresult
1023 {
1024  nsCOMPtr<nsIBrowserHistory> hist(do_GetService(NS_GLOBALHISTORY2_CONTRACTID));
1025 
1026  nsCOMPtr<nsIFile> temp;
1027  mOperaProfile->Clone(getter_AddRefs(temp));
1028  nsCOMPtr<nsILocalFile> historyFile(do_QueryInterface(temp));
1029  historyFile->Append(OPERA_HISTORY_FILE_NAME);
1030 
1031  nsCOMPtr<nsIInputStream> fileStream;
1032  NS_NewLocalFileInputStream(getter_AddRefs(fileStream), historyFile);
1033  if (!fileStream) return NS_ERROR_OUT_OF_MEMORY;
1034 
1035  nsCOMPtr<nsILineInputStream> lineStream = do_QueryInterface(fileStream);
1036 
1037  nsCAutoString buffer, url;
1038  nsAutoString title;
1039  PRTime lastVisitDate;
1040  PRBool moreData = PR_FALSE;
1041 
1042  enum { TITLE, URL, LASTVISIT } state = TITLE;
1043 
1044  // Format is "title\nurl\nlastvisitdate"
1045  do {
1046  nsresult rv = lineStream->ReadLine(buffer, &moreData);
1047  if (NS_FAILED(rv))
1048  return rv;
1049 
1050  switch (state) {
1051  case TITLE:
1052  CopyUTF8toUTF16(buffer, title);
1053  state = URL;
1054  break;
1055  case URL:
1056  url = buffer;
1057  state = LASTVISIT;
1058  break;
1059  case LASTVISIT:
1060  // Opera time format is a second offset, PRTime is a microsecond offset
1061  nsresult err;
1062  lastVisitDate = buffer.ToInteger(&err);
1063 
1064  PRInt64 temp, million;
1065  LL_I2L(temp, lastVisitDate);
1066  LL_I2L(million, PR_USEC_PER_SEC);
1067  LL_MUL(lastVisitDate, temp, million);
1068 
1069  nsCOMPtr<nsIURI> uri;
1070  NS_NewURI(getter_AddRefs(uri), url);
1071  if (uri)
1072  hist->AddPageWithDetails(uri, title.get(), lastVisitDate);
1073 
1074  state = TITLE;
1075  break;
1076  }
1077  }
1078  while (moreData);
1079 
1080  return NS_OK;
1081 }
1082 
1083 nsresult
1085 {
1086  nsresult rv;
1087  nsCOMPtr<nsINavBookmarksService> bookmarks =
1088  do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
1089  NS_ENSURE_SUCCESS(rv, rv);
1090 
1091  PRUint8 batchAction = aReplace ? BATCH_ACTION_BOOKMARKS_REPLACE
1093  nsCOMPtr<nsISupportsPRUint8> supports =
1094  do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
1095  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
1096  rv = supports->SetData(batchAction);
1097  NS_ENSURE_SUCCESS(rv, rv);
1098 
1099  rv = bookmarks->RunInBatchMode(this, supports);
1100  NS_ENSURE_SUCCESS(rv, rv);
1101 
1102  return NS_OK;
1103 }
1104 
1105 nsresult
1107 {
1108  // Find Opera Bookmarks
1109  nsCOMPtr<nsIFile> operaBookmarks;
1110  mOperaProfile->Clone(getter_AddRefs(operaBookmarks));
1111  operaBookmarks->Append(OPERA_BOOKMARKS_FILE_NAME);
1112 
1113  nsCOMPtr<nsIInputStream> fileInputStream;
1114  NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), operaBookmarks);
1115  NS_ENSURE_TRUE(fileInputStream, NS_ERROR_OUT_OF_MEMORY);
1116 
1117  nsCOMPtr<nsILineInputStream> lineInputStream(do_QueryInterface(fileInputStream));
1118 
1119  nsresult rv;
1120  nsCOMPtr<nsINavBookmarksService> bms =
1121  do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
1122  NS_ENSURE_SUCCESS(rv, rv);
1123  PRInt64 bookmarksMenuFolderId;
1124  rv = bms->GetBookmarksMenuFolder(&bookmarksMenuFolderId);
1125  NS_ENSURE_SUCCESS(rv, rv);
1126  PRInt64 parentFolder = bookmarksMenuFolderId;
1127 
1128  nsCOMPtr<nsIStringBundleService> bundleService =
1129  do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
1130  NS_ENSURE_SUCCESS(rv, rv);
1131  nsCOMPtr<nsIStringBundle> bundle;
1132  rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
1133  NS_ENSURE_SUCCESS(rv, rv);
1134 
1135  if (!aReplace) {
1136  nsString sourceNameOpera;
1137  rv = bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(),
1138  getter_Copies(sourceNameOpera));
1139  NS_ENSURE_SUCCESS(rv, rv);
1140 
1141  const PRUnichar* sourceNameStrings[] = { sourceNameOpera.get() };
1142  nsString importedOperaHotlistTitle;
1143  rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
1144  sourceNameStrings, 1,
1145  getter_Copies(importedOperaHotlistTitle));
1146  NS_ENSURE_SUCCESS(rv, rv);
1147 
1148  rv = bms->CreateFolder(parentFolder,
1149  NS_ConvertUTF16toUTF8(importedOperaHotlistTitle),
1150  nsINavBookmarksService::DEFAULT_INDEX,
1151  &parentFolder);
1152  NS_ENSURE_SUCCESS(rv, rv);
1153  }
1154  else {
1155  nsCOMPtr<nsIFile> profile;
1156  GetProfilePath(nsnull, profile);
1157  rv = InitializeBookmarks(profile);
1158  NS_ENSURE_SUCCESS(rv, rv);
1159  }
1160 
1161 #if defined(XP_WIN) || (defined(XP_UNIX) && !defined(XP_MACOSX))
1162  CopySmartKeywords(bms, bundle, parentFolder);
1163 #endif
1164 
1165  PRInt64 bookmarksToolbarFolderId;
1166  rv = bms->GetToolbarFolder(&bookmarksToolbarFolderId);
1167  NS_ENSURE_SUCCESS(rv, rv);
1168 
1169  rv = ParseBookmarksFolder(lineInputStream, parentFolder,
1170  bookmarksToolbarFolderId, bms);
1171  NS_ENSURE_SUCCESS(rv, rv);
1172 
1173  return NS_OK;
1174 }
1175 
1176 #if defined(XP_WIN) || (defined(XP_UNIX) && !defined(XP_MACOSX))
1177 nsresult
1178 nsOperaProfileMigrator::CopySmartKeywords(nsINavBookmarksService* aBMS,
1179  nsIStringBundle* aBundle,
1180  PRInt64 aParentFolder)
1181 {
1182  nsresult rv;
1183 
1184  nsCOMPtr<nsIFile> smartKeywords;
1185  mOperaProfile->Clone(getter_AddRefs(smartKeywords));
1186  smartKeywords->Append(NS_LITERAL_STRING("search.ini"));
1187 
1188  nsCOMPtr<nsILocalFile> lf(do_QueryInterface(smartKeywords));
1189  nsINIParser parser;
1190  if (!lf || NS_FAILED(parser.Init(lf)))
1191  return NS_OK;
1192 
1193  nsString sourceNameOpera;
1194  rv = aBundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(),
1195  getter_Copies(sourceNameOpera));
1196  NS_ENSURE_SUCCESS(rv, rv);
1197 
1198  const PRUnichar* sourceNameStrings[] = { sourceNameOpera.get() };
1199  nsString importedSearchUrlsTitle;
1200  rv = aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchURLsFolder").get(),
1201  sourceNameStrings, 1,
1202  getter_Copies(importedSearchUrlsTitle));
1203  NS_ENSURE_SUCCESS(rv, rv);
1204 
1205  PRInt64 keywordsFolder;
1206  rv = aBMS->CreateFolder(aParentFolder,
1207  NS_ConvertUTF16toUTF8(importedSearchUrlsTitle),
1208  nsINavBookmarksService::DEFAULT_INDEX,
1209  &keywordsFolder);
1210  NS_ENSURE_SUCCESS(rv, rv);
1211 
1212  PRInt32 sectionIndex = 1;
1213  nsCAutoString name, url, keyword;
1214  do {
1215  nsCAutoString section("Search Engine ");
1216  section.AppendInt(sectionIndex++);
1217 
1218  rv = parser.GetString(section.get(), "Name", name);
1219  if (NS_FAILED(rv)) {
1220  // No more smart keywords found, stop parsing the file.
1221  break;
1222  }
1223  if (name.IsEmpty())
1224  continue;
1225 
1226  rv = parser.GetString(section.get(), "URL", url);
1227  if (NS_FAILED(rv) || url.IsEmpty())
1228  continue;
1229 
1230  rv = parser.GetString(section.get(), "Key", keyword);
1231  if (NS_FAILED(rv) || keyword.IsEmpty())
1232  continue;
1233 
1234  PRInt32 post;
1235  rv = GetInteger(parser, section.get(), "Is post", &post);
1236  if (NS_SUCCEEDED(rv) && post)
1237  continue;
1238 
1239  PRUint32 length = name.Length();
1240  PRInt32 index = 0;
1241  do {
1242  index = name.FindChar('&', index);
1243  if ((PRUint32)index >= length - 2)
1244  break;
1245 
1246  // Assume "&&" is an escaped ampersand in the search query title.
1247  if (name.CharAt(index + 1) == '&') {
1248  name.Cut(index, 1);
1249  index += 2;
1250  continue;
1251  }
1252 
1253  name.Cut(index, 1);
1254  }
1255  while ((PRUint32)index < length);
1256 
1257  nsCOMPtr<nsIURI> uri;
1258  if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), url.get())) || !uri)
1259  continue;
1260 
1261  nsCAutoString hostCStr;
1262  uri->GetHost(hostCStr);
1263  NS_ConvertASCIItoUTF16 host(hostCStr);
1264 
1265  const PRUnichar* descStrings[] = { NS_ConvertUTF8toUTF16(keyword).get(),
1266  host.get() };
1267  nsString keywordDesc;
1268  rv = aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchUrlDesc").get(),
1269  descStrings, 2,
1270  getter_Copies(keywordDesc));
1271  NS_ENSURE_SUCCESS(rv, rv);
1272 
1273  PRInt64 newId;
1274  rv = aBMS->InsertBookmark(keywordsFolder, uri,
1275  nsINavBookmarksService::DEFAULT_INDEX,
1276  name, &newId);
1277  NS_ENSURE_SUCCESS(rv, rv);
1278  rv = aBMS->SetKeywordForBookmark(newId, NS_ConvertUTF8toUTF16(keyword));
1279  NS_ENSURE_SUCCESS(rv, rv);
1280  // TODO Bug 397771: set bookmark description to keywordDesc.
1281  }
1282  while (1);
1283 
1284  return rv;
1285 }
1286 #endif
1287 
1288 typedef enum { LineType_FOLDER,
1298 
1299 static LineType GetLineType(nsAString& aBuffer, PRUnichar** aData)
1300 {
1301  if (Substring(aBuffer, 0, 7).Equals(NS_LITERAL_STRING("#FOLDER")))
1302  return LineType_FOLDER;
1303  if (Substring(aBuffer, 0, 4).Equals(NS_LITERAL_STRING("#URL")))
1304  return LineType_BOOKMARK;
1305  if (Substring(aBuffer, 0, 1).Equals(NS_LITERAL_STRING("-")))
1306  return LineType_SEPARATOR;
1307  if (Substring(aBuffer, 1, 5).Equals(NS_LITERAL_STRING("NAME="))) {
1308  const nsAString& data = Substring(aBuffer, 6, aBuffer.Length() - 6);
1309  *aData = ToNewUnicode(data);
1310  return LineType_NAME;
1311  }
1312  if (Substring(aBuffer, 1, 4).Equals(NS_LITERAL_STRING("URL="))) {
1313  const nsAString& data = Substring(aBuffer, 5, aBuffer.Length() - 5);
1314  *aData = ToNewUnicode(data);
1315  return LineType_URL;
1316  }
1317  if (Substring(aBuffer, 1, 12).Equals(NS_LITERAL_STRING("DESCRIPTION="))) {
1318  const nsAString& data = Substring(aBuffer, 13, aBuffer.Length() - 13);
1319  *aData = ToNewUnicode(data);
1320  return LineType_DESCRIPTION;
1321  }
1322  if (Substring(aBuffer, 1, 11).Equals(NS_LITERAL_STRING("SHORT NAME="))) {
1323  const nsAString& data = Substring(aBuffer, 12, aBuffer.Length() - 12);
1324  *aData = ToNewUnicode(data);
1325  return LineType_KEYWORD;
1326  }
1327  if (Substring(aBuffer, 1, 15).Equals(NS_LITERAL_STRING("ON PERSONALBAR="))) {
1328  const nsAString& data = Substring(aBuffer, 16, aBuffer.Length() - 16);
1329  *aData = ToNewUnicode(data);
1330  return LineType_ONTOOLBAR;
1331  }
1332  if (aBuffer.IsEmpty())
1333  return LineType_NL; // Newlines separate bookmarks
1334  return LineType_OTHER;
1335 }
1336 
1338 
1339 nsresult
1341  PRInt64 aParent,
1342  PRInt64 aToolbar,
1343  nsINavBookmarksService* aBMS)
1344 {
1345  nsresult rv;
1346  PRBool moreData = PR_FALSE;
1347  nsAutoString buffer;
1348  EntryType entryType = EntryType_BOOKMARK;
1349  nsAutoString keyword, description;
1350  nsCAutoString url, name;
1351  PRBool onToolbar = PR_FALSE;
1352  do {
1353  nsCAutoString cBuffer;
1354  rv = aStream->ReadLine(cBuffer, &moreData);
1355  if (NS_FAILED(rv)) return rv;
1356 
1357  CopyUTF8toUTF16(cBuffer, buffer);
1358  nsString data;
1359  LineType type = GetLineType(buffer, getter_Copies(data));
1360  switch(type) {
1361  case LineType_FOLDER:
1362  entryType = EntryType_FOLDER;
1363  break;
1364  case LineType_BOOKMARK:
1365  entryType = EntryType_BOOKMARK;
1366  break;
1367  case LineType_SEPARATOR:
1368  // If we're here, we need to break out of the loop for the current folder,
1369  // essentially terminating this instance of ParseBookmarksFolder and return
1370  // to the calling function, which is either ParseBookmarksFolder for a parent
1371  // folder, or CopyBookmarks (which means we're done parsing all bookmarks).
1372  goto done;
1373  case LineType_NAME:
1374  name.Assign(NS_ConvertUTF16toUTF8(data));
1375  break;
1376  case LineType_URL:
1377  url.Assign(NS_ConvertUTF16toUTF8(data));
1378  break;
1379  case LineType_KEYWORD:
1380  keyword = data;
1381  break;
1382  case LineType_DESCRIPTION:
1383  description = data;
1384  break;
1385  case LineType_ONTOOLBAR:
1386  if (NS_LITERAL_STRING("YES").Equals(data))
1387  onToolbar = PR_TRUE;
1388  break;
1389  case LineType_NL: {
1390  // XXX We don't know for sure how Opera deals with IDN hostnames in URL.
1391  // Assuming it's in UTF-8 is rather safe because it covers two cases
1392  // (UTF-8 and ASCII) out of three cases (the last is a non-UTF-8
1393  // multibyte encoding).
1394  // XXX Todo: |description| is not saved.
1395  if (entryType == EntryType_BOOKMARK) {
1396  if (!name.IsEmpty() && !url.IsEmpty()) {
1397  nsCOMPtr<nsIURI> uri;
1398  rv = NS_NewURI(getter_AddRefs(uri), url);
1399  if (NS_FAILED(rv))
1400  continue;
1401  PRInt64 id;
1402  rv = aBMS->InsertBookmark(onToolbar ? aToolbar : aParent,
1403  uri, nsINavBookmarksService::DEFAULT_INDEX,
1404  name, &id);
1405  if (NS_FAILED(rv))
1406  continue;
1407  name.Truncate();
1408  url.Truncate();
1409  keyword.Truncate();
1410  description.Truncate();
1411  onToolbar = PR_FALSE;
1412  }
1413  }
1414  else if (entryType == EntryType_FOLDER) {
1415  if (!name.IsEmpty()) {
1416  PRInt64 newFolder;
1417  rv = aBMS->CreateFolder(onToolbar ? aToolbar : aParent,
1418  name, nsINavBookmarksService::DEFAULT_INDEX, &newFolder);
1419  if (NS_FAILED(rv))
1420  continue;
1421  rv = ParseBookmarksFolder(aStream, newFolder, aToolbar, aBMS);
1422  name.Truncate();
1423  }
1424  }
1425  break;
1426  }
1427  case LineType_OTHER:
1428  break;
1429  }
1430  }
1431  while (moreData);
1432 
1433 done:
1434  return rv;
1435 }
1436 
1437 void
1438 nsOperaProfileMigrator::GetOperaProfile(const PRUnichar* aProfile, nsILocalFile** aFile)
1439 {
1440  nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
1441  nsCOMPtr<nsILocalFile> file;
1442 #ifdef XP_WIN
1443  fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
1444 
1445  // Opera profile lives under %APP_DATA%\Opera<operaver>\profile
1446  file->Append(OPERA_PREFERENCES_FOLDER_NAME);
1447  file->Append(nsDependentString(aProfile));
1448  file->Append(NS_LITERAL_STRING("profile"));
1449 #elif defined (XP_MACOSX)
1450  fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
1451 
1452  file->Append(NS_LITERAL_STRING("Preferences"));
1453  file->Append(OPERA_PREFERENCES_FOLDER_NAME);
1454 #elif defined (XP_UNIX)
1455  fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
1456 
1457  file->Append(OPERA_PREFERENCES_FOLDER_NAME);
1458 #endif
1459 
1460  *aFile = file;
1461  NS_ADDREF(*aFile);
1462 }
1463 
#define _OPM(type)
nsresult InitializeBookmarks(nsIFile *aTargetProfile)
static nsresult SetCookieLifetime(void *aTransform, nsIPrefBranch *aBranch)
#define MIGRATION_BUNDLE
static nsOperaProfileMigrator::PrefTransform gTransforms[]
return NS_OK
nsresult CopyCookies(PRBool aReplace)
static nsresult SetWString(void *aTransform, nsIPrefBranch *aBranch)
menuItem id
Definition: FeedWriter.js:971
void ParseOverrideServers(const nsAString &aServers, nsIPrefBranch *aBranch)
NS_IMPL_ISUPPORTS1(sbDeviceCapabilitiesUtils, sbIDeviceCapabilitiesUtils) sbDeviceCapabilitiesUtils
nsresult CopyUserContentSheet(nsINIParser &aParser)
#define BATCH_ACTION_BOOKMARKS
var history
const NS_PREFSERVICE_CONTRACTID
const nsIPrefLocalizedString
nsresult CopyPreferences(PRBool aReplace)
const nsIPrefBranch
static nsresult SetCookieBehavior(void *aTransform, nsIPrefBranch *aBranch)
nsresult CopyBookmarks(PRBool aReplace)
nsresult CopyHistory(PRBool aReplace)
#define BATCH_ACTION_HISTORY_REPLACE
static nsresult SetInt(void *aTransform, nsIPrefBranch *aBranch)
#define NOTIFY_OBSERVERS(message, item)
nsresult ParseBookmarksFolder(nsILineInputStream *aStream, PRInt64 aFolder, PRInt64 aToolbar, nsINavBookmarksService *aBMS)
static LineType GetLineType(nsAString &aBuffer, PRUnichar **aData)
static nsresult SetString(void *aTransform, nsIPrefBranch *aBranch)
var bundle
var count
Definition: test_bug7406.js:32
#define MIGRATION_STARTED
void GetOperaProfile(const PRUnichar *aProfile, nsILocalFile **aFile)
#define COPY_DATA(func, replace, itemIndex)
#define MIGRATION_ENDED
this _dialogInput val(dateText)
unique done
nsresult ParseColor(nsINIParser &aParser, const char *aSectionName, char **aResult)
const nsIPermissionManager
Definition: pageInfo.js:202
static nsresult SetFile(void *aTransform, nsIPrefBranch *aBranch)
function url(spec)
var uri
Definition: FeedWriter.js:1135
StringArrayEnumerator prototype hasMore
static nsresult SetImageBehavior(void *aTransform, nsIPrefBranch *aBranch)
#define OPERA_COOKIES_FILE_NAME
void GetProfilePath(nsIProfileStartup *aStartup, nsCOMPtr< nsIFile > &aProfileDir)
#define BATCH_ACTION_HISTORY
nsresult GetInteger(nsINIParser &aParser, const char *aSectionName, const char *aKeyName, PRInt32 *aResult)
void SetProxyPref(const nsAString &aHostPort, const char *aPref, const char *aPortPref, nsIPrefBranch *aPrefs)
dataSBGenres SBProperties tag
Definition: tuner2.js:871
#define BATCH_ACTION_BOOKMARKS_REPLACE
nsresult CopyHistoryBatched(PRBool aReplace)
nsresult CopyProxySettings(nsINIParser &aParser, nsIPrefBranch *aBranch)
static nsresult SetBool(void *aTransform, nsIPrefBranch *aBranch)
nsresult CopyBookmarksBatched(PRBool aReplace)
observe data
Definition: FeedWriter.js:1329
_getSelectedPageStyle s i
_updateTextAndScrollDataForFrame aData
void GetMigrateDataFromArray(MigrationData *aDataArray, PRInt32 aDataArrayLength, PRBool aReplace, nsIFile *aSourceProfile, PRUint16 *aResult)
var file