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
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Don Bragg <dbragg@netscape.com>
24 * Seth Spitzer <sspitzer@netscape.com>
25 * Pierre Phaneuf <pp@ludusdesign.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
42 #include "nsIComponentManager.h"
43 #include "nsIComponentManager.h"
44 #include "nsIPromptService.h"
45 #include "nsIServiceManager.h"
46 #include "nsPIDOMWindow.h"
47 #include "nsIScriptContext.h"
48 #include "nsILocalFile.h"
49 #include "nsDirectoryServiceUtils.h"
50 #include "nsDirectoryServiceDefs.h"
51 #include "nsDependentString.h"
52 #include "nsFileStream.h"
53 #include "nsIFileSpec.h"
58 #include "nsIPrefService.h"
61 #include "nsXPIDLString.h"
62 #include "nsReadableUtils.h"
63 #include "nsIStringBundle.h"
64 #include "nsProxiedService.h"
66 #include "nsNetUtil.h"
69 #include "nsVoidArray.h"
71 #include "nsIBaseWindow.h"
72 #include "nsIDocShell.h"
73 #include "nsIDocShellTreeItem.h"
74 #include "nsIDocShellTreeOwner.h"
75 #include "nsIWebBrowserChrome.h"
76 #include "nsIWindowWatcher.h"
77 #include "nsEmbedCID.h"
80 #define DEBUG_UTF8_CONVERSION 1
83 #include "nsICharsetConverterManager.h"
84 #include "nsIPlatformCharset.h"
86 #define CHROME_STYLE nsIWebBrowserChrome::CHROME_ALL | nsIWebBrowserChrome::CHROME_CENTER_SCREEN
87 #define MIGRATION_PROPERTIES_URL "chrome://communicator/locale/profile/migration.properties"
91 #include "nsPrefMigration.h"
92 #include "nsPrefMigrationFactory.h"
94 #define PREF_FILE_HEADER_STRING "# Mozilla User Preferences "
96 #define MAX_PREF_LEN 1024
98 #if defined(XP_UNIX) && !defined(XP_MACOSX)
99 #define IMAP_MAIL_FILTER_FILE_NAME_IN_4x "mailrule"
100 #define POP_MAIL_FILTER_FILE_NAME_IN_4x "mailrule"
101 #define MAIL_SUMMARY_SUFFIX_IN_4x ".summary"
102 #define NEWS_SUMMARY_SUFFIX_IN_4x ".snm"
103 #define COOKIES_FILE_NAME_IN_4x "cookies"
104 #define BOOKMARKS_FILE_NAME_IN_4x "bookmarks.html"
105 #define NEWSRC_PREFIX_IN_4x ".newsrc-"
106 #define SNEWSRC_PREFIX_IN_4x ".snewsrc-"
107 #define POPSTATE_FILE_IN_4x "popstate"
108 #define PSM_CERT7_DB "cert7.db"
109 #define PSM_KEY3_DB "key3.db"
110 #define PSM_SECMODULE_DB "secmodule.db"
111 #elif defined(XP_MACOSX)
112 #define MAC_RULES_FILE_ENDING_STRING_IN_4X " Rules"
113 #define IMAP_MAIL_FILTER_FILE_NAME_IN_4x "<hostname> Rules"
114 #define POP_MAIL_FILTER_FILE_NAME_IN_4x "Filter Rules"
115 #define MAIL_SUMMARY_SUFFIX_IN_4x ".snm"
116 #define NEWS_SUMMARY_SUFFIX_IN_4x ".snm"
117 #define COOKIES_FILE_NAME_IN_4x "MagicCookie"
118 #define BOOKMARKS_FILE_NAME_IN_4x "Bookmarks.html"
119 #define POPSTATE_FILE_IN_4x "Pop State"
120 #define SECURITY_PATH "Security"
121 #define PSM_CERT7_DB "Certificates7"
122 #define PSM_KEY3_DB "Key Database3"
123 #define PSM_SECMODULE_DB "Security Modules"
124 #else /* XP_WIN || XP_OS2 */
125 #define IMAP_MAIL_FILTER_FILE_NAME_IN_4x "rules.dat"
126 #define POP_MAIL_FILTER_FILE_NAME_IN_4x "rules.dat"
127 #define MAIL_SUMMARY_SUFFIX_IN_4x ".snm"
128 #define NEWS_SUMMARY_SUFFIX_IN_4x ".snm"
129 #define COOKIES_FILE_NAME_IN_4x "cookies.txt"
130 #define BOOKMARKS_FILE_NAME_IN_4x "bookmark.htm"
131 // purposely not defined, since it was in the right place
132 // and with the right name in 4.x
133 //#define POPSTATE_FILE_IN_4x "popstate.dat"
134 #define PSM_CERT7_DB "cert7.db"
135 #define PSM_KEY3_DB "key3.db"
136 #define PSM_SECMODULE_DB "secmod.db"
139 #define SUMMARY_SUFFIX_IN_5x ".msf"
140 #define COOKIES_FILE_NAME_IN_5x "cookies.txt"
141 #define IMAP_MAIL_FILTER_FILE_NAME_IN_5x "rules.dat"
142 #define POP_MAIL_FILTER_FILE_NAME_IN_5x "rules.dat"
143 #define POPSTATE_FILE_IN_5x "popstate.dat"
144 #define BOOKMARKS_FILE_NAME_IN_5x "bookmarks.html"
145 #define HISTORY_FILE_NAME_IN_5x "history.dat"
147 // only UNIX had movemail in 4.x
148 #if defined(XP_UNIX) && !defined(XP_MACOSX)
149 #define HAVE_MOVEMAIL 1
152 #define PREMIGRATION_PREFIX "premigration."
154 // this is for the hidden preference setting in mozilla/modules/libpref/src/init/mailnews.js
155 // pref("mail.migration.copyMailFiles", true);
157 // see bugzilla bug 80035 (http://bugzilla.mozilla.org/show_bug.cgi?id=80035)
159 // the default value for this setting is true which means when migrating from
160 // Netscape 4.x, mozilla will copy all the contents of Local Folders and Imap
161 // Folder to the newly created subfolders of migrated mozilla profile
162 // when this value is set to false, mozilla will not copy these contents and
163 // still share them with Netscape 4.x
165 // Advantages of forbidding copy operation:
166 // reduce the disk usage
168 // Disadvantage of forbidding copy operation:
169 // without perfect lock mechamism, there is possibility of data corruption
170 // when Netscape 4.x and mozilla run at the same time and access the same
171 // mail file at the same time
172 #define PREF_MIGRATION_MODE_FOR_MAIL "mail.migration.copyMailFiles"
174 #define PREF_MAIL_DIRECTORY "mail.directory"
175 #define PREF_NEWS_DIRECTORY "news.directory"
176 #define PREF_MAIL_IMAP_ROOT_DIR "mail.imap.root_dir"
177 #define PREF_NETWORK_HOSTS_POP_SERVER "network.hosts.pop_server"
178 #define PREF_4X_NETWORK_HOSTS_IMAP_SERVER "network.hosts.imap_servers"
179 #define PREF_MAIL_SERVER_TYPE "mail.server_type"
180 #define PREF_BROWSER_CACHE_DIRECTORY "browser.cache.directory"
181 #define POP_4X_MAIL_TYPE 0
182 #define IMAP_4X_MAIL_TYPE 1
184 #define MOVEMAIL_4X_MAIL_TYPE 2
185 #define NEW_MOVEMAIL_DIR_NAME "movemail"
186 #endif /* HAVE_MOVEMAIL */
188 #if defined(XP_UNIX) && !defined(XP_MACOSX)
189 /* a 4.x profile on UNIX is rooted at something like
190 * "/u/sspitzer/.netscape"
191 * profile + OLD_MAIL_DIR_NAME = "/u/sspitzer/.netscape/../nsmail" = "/u/sspitzer/nsmail"
192 * profile + OLD_NEWS_DIR_NAME = "/u/sspitzer/.netscape/xover-cache"
193 * profile + OLD_IMAPMAIL_DIR_NAME = "/u/sspitzer/.netscape/../ns_imap" = "/u/sspitzer/ns_imap"
194 * which is as good as we're going to get for defaults on UNIX.
196 #define OLD_MAIL_DIR_NAME "/../nsmail"
197 #define OLD_NEWS_DIR_NAME "/xover-cache"
198 #define OLD_IMAPMAIL_DIR_NAME "/../ns_imap"
200 #define OLD_MAIL_DIR_NAME "Mail"
201 #define OLD_NEWS_DIR_NAME "News"
202 #define OLD_IMAPMAIL_DIR_NAME "ImapMail"
205 #define NEW_DIR_SUFFIX "5"
207 #define PREF_FILE_NAME_IN_5x "prefs.js"
209 #define PREF_MIGRATION_PROGRESS_URL "chrome://communicator/content/profile/profileMigrationProgress.xul"
216 } MigrateProfileItem
;
219 * In 4.x the mac cookie file used expiration times starting from
220 * 1900 whereas all the other platforms started from
221 * 1970. In 5.0 it was made cross platform so that all platforms use
222 * expiration times starting from 1970. That means that mac cookies
223 * generated in 4.x cannot be migrated to 5.0 as is -- instead the
224 * expiration time must first be decreased by
225 * the number of seconds between 1-1-1900 and 1-1-1970
227 * 70 years * 365 days/year * 86,400 secs/day = 2,207,520,000 seconds
228 * + 17 leap years * 86,400 additional sec/leapyear = 1,468,800 seconds
229 * = 2,208,988,800 seconds
231 #if defined(XP_MACOSX)
232 #define NEED_TO_FIX_4X_COOKIES 1
233 #define SECONDS_BETWEEN_1900_AND_1970 2208988800UL
234 #endif /* XP_MACOSX */
236 /*-----------------------------------------------------------------
238 *-----------------------------------------------------------------*/
239 nsPrefMigration
* nsPrefMigration::mInstance
= nsnull
;
242 nsPrefMigration::GetInstance()
244 if (mInstance
== nsnull
)
246 mInstance
= new nsPrefMigration();
253 nsPrefMigration::nsPrefMigration()
260 PRBool
ProfilesToMigrateCleanup(void* aElement
, void *aData
)
263 delete (MigrateProfileItem
*)aElement
;
268 nsPrefMigration::~nsPrefMigration()
270 mProfilesToMigrate
.EnumerateForwards((nsVoidArrayEnumFunc
)ProfilesToMigrateCleanup
, nsnull
);
277 nsPrefMigration::getPrefService()
279 // get the prefs service
282 nsCOMPtr
<nsIPrefBranch
> pIMyService(do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
));
283 if(NS_FAILED(rv
)) return rv
;
285 return NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD
, NS_GET_IID(nsIPrefBranch
),
286 pIMyService
, NS_PROXY_SYNC
,
287 getter_AddRefs(m_prefBranch
));
291 NS_IMPL_THREADSAFE_ISUPPORTS1(nsPrefMigration
, nsIPrefMigration
)
294 nsPrefMigration::AddProfilePaths(const char * oldProfilePathStr
, const char * newProfilePathStr
)
296 MigrateProfileItem
* item
= new MigrateProfileItem();
298 return NS_ERROR_OUT_OF_MEMORY
;
300 item
->oldFile
= oldProfilePathStr
;
301 item
->newFile
= newProfilePathStr
;
303 if (mProfilesToMigrate
.AppendElement((void*)item
))
306 return NS_ERROR_FAILURE
;
311 nsPrefMigration::ProcessPrefs(PRBool showProgressAsModalWindow
)
315 nsCOMPtr
<nsIWindowWatcher
> windowWatcher(do_GetService(NS_WINDOWWATCHER_CONTRACTID
, &rv
));
316 if (NS_FAILED(rv
)) return rv
;
318 // WindowWatcher can work with or without parent window
319 rv
= windowWatcher
->OpenWindow(nsnull
,
320 PREF_MIGRATION_PROGRESS_URL
,
322 "centerscreen,modal,titlebar",
324 getter_AddRefs(mPMProgressWindow
));
325 if (NS_FAILED(rv
)) return rv
;
331 static PRThread
* gMigrationThread
= nsnull
;
334 extern "C" void ProfileMigrationController(void *data
)
338 nsPrefMigration
* migrator
= (nsPrefMigration
*)data
;
339 nsIPrefMigration
* interfaceM
= (nsIPrefMigration
*)data
;
344 nsCOMPtr
<nsIPrefMigration
> prefProxy
;
349 migrator
->mErrorCode
= 0;
350 MigrateProfileItem
* item
= nsnull
;
352 if (migrator
->mProfilesToMigrate
.Count() != 0)
353 item
= (MigrateProfileItem
*)migrator
->mProfilesToMigrate
.ElementAt(index
);
356 rv
= migrator
->ProcessPrefsCallback(item
->oldFile
, item
->newFile
);
359 migrator
->mErrorCode
= rv
;
361 printf("failed to migrate properly. err=%d\n",rv
);
367 migrator
->mErrorCode
= NS_ERROR_FAILURE
;
371 nsCOMPtr
<nsIPrefMigration
> migratorInterface
= do_QueryInterface(interfaceM
, &rv
);
374 migrator
->mErrorCode
= rv
;
380 rv
= NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD
,
381 NS_GET_IID(nsIPrefMigration
),
382 migratorInterface
, NS_PROXY_SYNC
,
383 getter_AddRefs(prefProxy
));
386 migrator
->mErrorCode
= rv
;
392 if (migrator
->mErrorCode
!= 0)
394 if (migrator
->mErrorCode
== MIGRATION_RETRY
)
396 rv
= prefProxy
->ShowSpaceDialog(&choice
);
399 migrator
->mErrorCode
= rv
;
402 choice
++;// Increment choice to match the RETRY=1, CANCEL=2 and CREATE_NEW=3 format
406 } while (choice
== MIGRATION_RETRY
);
408 prefProxy
->WindowCloseCallback();
409 migrator
->mErrorCode
= choice
;
414 nsPrefMigration::WindowCloseCallback()
416 nsCOMPtr
<nsPIDOMWindow
> window(do_QueryInterface(mPMProgressWindow
));
417 if (!window
) return NS_ERROR_FAILURE
;
419 nsCOMPtr
<nsIDocShellTreeItem
> treeItem
=
420 do_QueryInterface(window
->GetDocShell());
421 if (!treeItem
) return NS_ERROR_FAILURE
;
422 nsCOMPtr
<nsIDocShellTreeOwner
> treeOwner
;
423 treeItem
->GetTreeOwner(getter_AddRefs(treeOwner
));
424 if (!treeOwner
) return NS_ERROR_FAILURE
;
425 nsCOMPtr
<nsIBaseWindow
> baseWindow(do_QueryInterface(treeOwner
));
427 baseWindow
->Destroy();
430 printf("end of pref migration\n");
437 nsPrefMigration::ShowSpaceDialog(PRInt32
*choice
)
440 nsCOMPtr
<nsIStringBundleService
> bundleService
= do_GetService(NS_STRINGBUNDLE_CONTRACTID
, &rv
);
441 if (NS_FAILED(rv
)) return rv
;
443 nsCOMPtr
<nsIStringBundle
> bundle
;
444 rv
= bundleService
->CreateBundle(MIGRATION_PROPERTIES_URL
, getter_AddRefs(bundle
));
445 if (NS_FAILED(rv
)) return rv
;
447 nsXPIDLString noSpaceTitle
, noSpaceText
, retryLabel
, createNewLabel
;
448 rv
= bundle
->GetStringFromName(NS_LITERAL_STRING("noSpace.title").get(), getter_Copies(noSpaceTitle
));
449 if (NS_FAILED(rv
)) return rv
;
450 rv
= bundle
->GetStringFromName(NS_LITERAL_STRING("noSpace.text").get(), getter_Copies(noSpaceText
));
451 if (NS_FAILED(rv
)) return rv
;
452 rv
= bundle
->GetStringFromName(NS_LITERAL_STRING("retry.label").get(), getter_Copies(retryLabel
));
453 if (NS_FAILED(rv
)) return rv
;
454 rv
= bundle
->GetStringFromName(NS_LITERAL_STRING("createNew.label").get(), getter_Copies(createNewLabel
));
455 if (NS_FAILED(rv
)) return rv
;
457 nsCOMPtr
<nsIPromptService
> promptService
= do_GetService(NS_PROMPTSERVICE_CONTRACTID
, &rv
);
458 if (NS_FAILED(rv
)) return rv
;
460 const PRUint32 buttons
=
461 (nsIPromptService::BUTTON_TITLE_IS_STRING
* nsIPromptService::BUTTON_POS_0
)+
462 (nsIPromptService::BUTTON_TITLE_CANCEL
* nsIPromptService::BUTTON_POS_1
)+
463 (nsIPromptService::BUTTON_TITLE_IS_STRING
* nsIPromptService::BUTTON_POS_2
);
464 return promptService
->ConfirmEx(mPMProgressWindow
, noSpaceTitle
, noSpaceText
,
465 buttons
, retryLabel
, nsnull
, createNewLabel
,
466 nsnull
, nsnull
, choice
);
471 nsPrefMigration::ProcessPrefsFromJS() // called via js so that we can have progress bar that show up.
473 gMigrationThread
= PR_CreateThread(PR_USER_THREAD
,
474 ProfileMigrationController
,
478 PR_UNJOINABLE_THREAD
,
485 nsPrefMigration::GetError()
491 nsPrefMigration::ConvertPersistentStringToFileSpec(const char *str
, nsIFileSpec
*path
)
494 if (!str
|| !path
) return NS_ERROR_NULL_POINTER
;
496 rv
= path
->SetPersistentDescriptorString(str
);
500 /*--------------------------------------------------------------------------
501 * ProcessPrefsCallback is the primary funtion for the class nsPrefMigration.
503 * Called by: The Profile Manager (nsProfile.cpp)
504 * INPUT: The specific profile path (prefPath) and the 5.0 installed path
505 * OUTPUT: The modified 5.0 prefs files
506 * RETURN: Success or a failure code
508 *-------------------------------------------------------------------------*/
510 nsPrefMigration::ProcessPrefsCallback(const char* oldProfilePathStr
, const char * newProfilePathStr
)
514 nsCOMPtr
<nsIFileSpec
> oldProfilePath
;
515 nsCOMPtr
<nsIFileSpec
> newProfilePath
;
516 nsCOMPtr
<nsIFileSpec
> oldPOPMailPath
;
517 nsCOMPtr
<nsIFileSpec
> newPOPMailPath
;
518 nsCOMPtr
<nsIFileSpec
> oldIMAPMailPath
;
519 nsCOMPtr
<nsIFileSpec
> newIMAPMailPath
;
520 nsCOMPtr
<nsIFileSpec
> oldIMAPLocalMailPath
;
521 nsCOMPtr
<nsIFileSpec
> newIMAPLocalMailPath
;
522 nsCOMPtr
<nsIFileSpec
> oldNewsPath
;
523 nsCOMPtr
<nsIFileSpec
> newNewsPath
;
524 nsCOMPtr
<nsILocalFile
> newPrefsFile
;
526 nsCOMPtr
<nsIFileSpec
> oldMOVEMAILMailPath
;
527 nsCOMPtr
<nsIFileSpec
> newMOVEMAILMailPath
;
528 #endif /* HAVE_MOVEMAIL */
529 PRBool exists
= PR_FALSE
,
530 enoughSpace
= PR_TRUE
,
531 localMailDriveDefault
= PR_FALSE
,
532 summaryMailDriveDefault
= PR_FALSE
,
533 newsDriveDefault
= PR_FALSE
,
534 copyMailFileInMigration
= PR_TRUE
;
536 nsFileSpec localMailSpec
,
539 oldProfileSpec
, newProfileSpec
;
541 PRInt32 serverType
= POP_4X_MAIL_TYPE
;
542 char *popServerName
= nsnull
;
544 PRUint32 totalLocalMailSize
= 0,
545 totalSummaryFileSize
= 0,
547 totalProfileSize
= 0,
551 PRInt64 localMailDrive
= LL_Zero(),
552 summaryMailDrive
= LL_Zero(),
553 newsDrive
= LL_Zero(),
554 profileDrive
= LL_Zero();
556 PRInt64 DriveID
[MAX_DRIVES
];
557 PRUint32 SpaceRequired
[MAX_DRIVES
];
559 #if defined(NS_DEBUG)
560 printf("*Entered Actual Migration routine*\n");
563 for (int i
=0; i
< MAX_DRIVES
; i
++)
565 DriveID
[i
] = LL_Zero();
566 SpaceRequired
[i
] = 0;
569 rv
= getPrefService();
570 if (NS_FAILED(rv
)) return rv
;
572 rv
= NS_NewFileSpec(getter_AddRefs(oldProfilePath
));
573 if (NS_FAILED(rv
)) return rv
;
574 rv
= NS_NewFileSpec(getter_AddRefs(newProfilePath
));
575 if (NS_FAILED(rv
)) return rv
;
577 rv
= ConvertPersistentStringToFileSpec(oldProfilePathStr
, oldProfilePath
);
578 if (NS_FAILED(rv
)) return rv
;
579 rv
= ConvertPersistentStringToFileSpec(newProfilePathStr
, newProfilePath
);
580 if (NS_FAILED(rv
)) return rv
;
582 oldProfilePath
->GetFileSpec(&oldProfileSpec
);
583 newProfilePath
->GetFileSpec(&newProfileSpec
);
586 /* initialize prefs with the old prefs.js file (which is a copy of the 4.x preferences file) */
587 nsCOMPtr
<nsIFileSpec
> PrefsFile4x
;
589 //Get the location of the 4.x prefs file
590 rv
= NS_NewFileSpec(getter_AddRefs(PrefsFile4x
));
591 if (NS_FAILED(rv
)) return rv
;
593 rv
= PrefsFile4x
->FromFileSpec(oldProfilePath
);
594 if (NS_FAILED(rv
)) return rv
;
596 rv
= PrefsFile4x
->AppendRelativeUnixPath(PREF_FILE_NAME_IN_4x
);
597 if (NS_FAILED(rv
)) return rv
;
599 //Need to convert PrefsFile4x to an IFile in order to copy it to a
600 //unique name in the system temp directory.
601 nsFileSpec PrefsFile4xAsFileSpec
;
602 rv
= PrefsFile4x
->GetFileSpec(&PrefsFile4xAsFileSpec
);
603 if (NS_FAILED(rv
)) return rv
;
605 nsCOMPtr
<nsILocalFile
> PrefsFile4xAsIFile
;
606 rv
= NS_FileSpecToIFile(&PrefsFile4xAsFileSpec
,
607 getter_AddRefs(PrefsFile4xAsIFile
));
608 if (NS_FAILED(rv
)) return rv
;
610 nsCOMPtr
<nsIFile
> systemTempDir
;
611 rv
= NS_GetSpecialDirectory(NS_OS_TEMP_DIR
, getter_AddRefs(systemTempDir
));
612 if (NS_FAILED(rv
)) return rv
;
614 systemTempDir
->AppendNative(NS_LITERAL_CSTRING("migrate"));
616 //Create a unique directory in the system temp dir based on the name of the 4.x prefs file
617 rv
= systemTempDir
->CreateUnique(nsIFile::DIRECTORY_TYPE
, 0700);
618 if (NS_FAILED(rv
)) return rv
;
620 rv
= PrefsFile4xAsIFile
->CopyToNative(systemTempDir
, NS_LITERAL_CSTRING(PREF_FILE_NAME_IN_4x
));
621 if (NS_FAILED(rv
)) return rv
;
623 nsCOMPtr
<nsIFile
> cloneFile
;
624 rv
= systemTempDir
->Clone(getter_AddRefs(cloneFile
));
625 if (NS_FAILED(rv
)) return rv
;
627 m_prefsFile
= do_QueryInterface(cloneFile
, &rv
);
628 if (NS_FAILED(rv
)) return rv
;
630 rv
= m_prefsFile
->AppendNative(NS_LITERAL_CSTRING(PREF_FILE_NAME_IN_4x
));
631 if (NS_FAILED(rv
)) return rv
;
633 nsCOMPtr
<nsIPrefService
> psvc(do_QueryInterface(m_prefBranch
));
635 //Clear the prefs in case a previous set was read in.
638 //Now read the prefs from the prefs file in the system directory
639 psvc
->ReadUserPrefs(m_prefsFile
);
642 // Start computing the sizes required for migration
644 rv
= GetSizes(oldProfileSpec
, PR_FALSE
, &totalProfileSize
);
645 profileDrive
= newProfileSpec
.GetDiskSpaceAvailable();
647 rv
= m_prefBranch
->GetIntPref(PREF_MAIL_SERVER_TYPE
, &serverType
);
648 if (NS_FAILED(rv
)) return rv
;
650 // get the migration mode for mail
651 rv
= m_prefBranch
->GetBoolPref(PREF_MIGRATION_MODE_FOR_MAIL
,
652 ©MailFileInMigration
);
656 if (serverType
== POP_4X_MAIL_TYPE
) {
657 summaryMailDriveDefault
= PR_TRUE
; //summary files are only used in IMAP so just set it to true here.
658 summaryMailDrive
= profileDrive
; //just set the drive for summary files to be the same as the new profile
660 rv
= NS_NewFileSpec(getter_AddRefs(newPOPMailPath
));
661 if (NS_FAILED(rv
)) return rv
;
663 rv
= NS_NewFileSpec(getter_AddRefs(oldPOPMailPath
));
664 if (NS_FAILED(rv
)) return rv
;
666 rv
= GetDirFromPref(oldProfilePath
,newProfilePath
,NEW_MAIL_DIR_NAME
, PREF_MAIL_DIRECTORY
, newPOPMailPath
, oldPOPMailPath
);
668 rv
= DetermineOldPath(oldProfilePath
, OLD_MAIL_DIR_NAME
, "mailDirName", oldPOPMailPath
);
669 if (NS_FAILED(rv
)) return rv
;
671 rv
= SetPremigratedFilePref(PREF_MAIL_DIRECTORY
, oldPOPMailPath
);
672 if (NS_FAILED(rv
)) return rv
;
674 rv
= newPOPMailPath
->FromFileSpec(newProfilePath
);
675 if (NS_FAILED(rv
)) return rv
;
677 localMailDriveDefault
= PR_TRUE
;
679 oldPOPMailPath
->GetFileSpec(&localMailSpec
);
680 rv
= GetSizes(localMailSpec
, PR_TRUE
, &totalLocalMailSize
);
681 localMailDrive
= localMailSpec
.GetDiskSpaceAvailable();
683 else if(serverType
== IMAP_4X_MAIL_TYPE
) {
684 rv
= NS_NewFileSpec(getter_AddRefs(newIMAPLocalMailPath
));
685 if (NS_FAILED(rv
)) return rv
;
687 rv
= NS_NewFileSpec(getter_AddRefs(oldIMAPLocalMailPath
));
688 if (NS_FAILED(rv
)) return rv
;
690 /* First get the actual 4.x "Local Mail" files location */
691 rv
= GetDirFromPref(oldProfilePath
,newProfilePath
, NEW_MAIL_DIR_NAME
, PREF_MAIL_DIRECTORY
, newIMAPLocalMailPath
, oldIMAPLocalMailPath
);
693 rv
= DetermineOldPath(oldProfilePath
, OLD_MAIL_DIR_NAME
, "mailDirName", oldIMAPLocalMailPath
);
694 if (NS_FAILED(rv
)) return rv
;
696 rv
= SetPremigratedFilePref(PREF_MAIL_DIRECTORY
, oldIMAPLocalMailPath
);
697 if (NS_FAILED(rv
)) return rv
;
699 rv
= newIMAPLocalMailPath
->FromFileSpec(newProfilePath
);
700 if (NS_FAILED(rv
)) return rv
;
702 localMailDriveDefault
= PR_TRUE
;
705 oldIMAPLocalMailPath
->GetFileSpec(&localMailSpec
);
706 rv
= GetSizes(localMailSpec
, PR_TRUE
, &totalLocalMailSize
);
707 localMailDrive
= localMailSpec
.GetDiskSpaceAvailable();
709 /* Next get IMAP mail summary files location */
710 rv
= NS_NewFileSpec(getter_AddRefs(newIMAPMailPath
));
711 if (NS_FAILED(rv
)) return rv
;
713 rv
= NS_NewFileSpec(getter_AddRefs(oldIMAPMailPath
));
714 if (NS_FAILED(rv
)) return rv
;
716 rv
= GetDirFromPref(oldProfilePath
,newProfilePath
, NEW_IMAPMAIL_DIR_NAME
, PREF_MAIL_IMAP_ROOT_DIR
,newIMAPMailPath
,oldIMAPMailPath
);
718 rv
= oldIMAPMailPath
->FromFileSpec(oldProfilePath
);
719 if (NS_FAILED(rv
)) return rv
;
721 /* we didn't over localize "ImapMail" in 4.x, so this is all we have to do */
722 rv
= oldIMAPMailPath
->AppendRelativeUnixPath(OLD_IMAPMAIL_DIR_NAME
);
723 if (NS_FAILED(rv
)) return rv
;
725 rv
= SetPremigratedFilePref(PREF_MAIL_IMAP_ROOT_DIR
, oldIMAPMailPath
);
726 if (NS_FAILED(rv
)) return rv
;
728 rv
= newIMAPMailPath
->FromFileSpec(newProfilePath
);
729 if (NS_FAILED(rv
)) return rv
;
731 summaryMailDriveDefault
= PR_TRUE
;
734 oldIMAPMailPath
->GetFileSpec(&summaryMailSpec
);
735 rv
= GetSizes(summaryMailSpec
, PR_TRUE
, &totalSummaryFileSize
);
736 summaryMailDrive
= summaryMailSpec
.GetDiskSpaceAvailable();
740 else if (serverType
== MOVEMAIL_4X_MAIL_TYPE
) {
742 summaryMailDriveDefault
= PR_TRUE
;
743 summaryMailDrive
= profileDrive
;
745 rv
= NS_NewFileSpec(getter_AddRefs(newMOVEMAILMailPath
));
746 if (NS_FAILED(rv
)) return rv
;
748 rv
= NS_NewFileSpec(getter_AddRefs(oldMOVEMAILMailPath
));
749 if (NS_FAILED(rv
)) return rv
;
751 rv
= GetDirFromPref(oldProfilePath
,newProfilePath
,NEW_MAIL_DIR_NAME
, PREF_MAIL_DIRECTORY
, newMOVEMAILMailPath
, oldMOVEMAILMailPath
);
753 rv
= oldMOVEMAILMailPath
->FromFileSpec(oldProfilePath
);
754 if (NS_FAILED(rv
)) return rv
;
756 /* we didn't over localize this in 4.x, so this is all we have to do */
757 rv
= oldMOVEMAILMailPath
->AppendRelativeUnixPath(OLD_MAIL_DIR_NAME
);
758 if (NS_FAILED(rv
)) return rv
;
760 rv
= SetPremigratedFilePref(PREF_MAIL_DIRECTORY
, oldMOVEMAILMailPath
);
761 if (NS_FAILED(rv
)) return rv
;
763 rv
= newMOVEMAILMailPath
->FromFileSpec(newProfilePath
);
764 if (NS_FAILED(rv
)) return rv
;
766 localMailDriveDefault
= PR_TRUE
;
768 oldMOVEMAILMailPath
->GetFileSpec(&localMailSpec
);
769 rv
= GetSizes(localMailSpec
, PR_TRUE
, &totalLocalMailSize
);
771 localMailDrive
= localMailSpec
.GetDiskSpaceAvailable();
774 #endif //HAVE_MOVEMAIL
776 ////////////////////////////////////////////////////////////////////////////
777 // Now get the NEWS disk space requirements for migration.
778 ////////////////////////////////////////////////////////////////////////////
779 rv
= NS_NewFileSpec(getter_AddRefs(newNewsPath
));
780 if (NS_FAILED(rv
)) return rv
;
782 rv
= NS_NewFileSpec(getter_AddRefs(oldNewsPath
));
783 if (NS_FAILED(rv
)) return rv
;
785 rv
= GetDirFromPref(oldProfilePath
,newProfilePath
, NEW_NEWS_DIR_NAME
, PREF_NEWS_DIRECTORY
, newNewsPath
,oldNewsPath
);
787 rv
= DetermineOldPath(oldProfilePath
, OLD_NEWS_DIR_NAME
, "newsDirName", oldNewsPath
);
788 if (NS_FAILED(rv
)) return rv
;
790 rv
= SetPremigratedFilePref(PREF_NEWS_DIRECTORY
, oldNewsPath
);
791 if (NS_FAILED(rv
)) return rv
;
793 rv
= newNewsPath
->FromFileSpec(newProfilePath
);
794 if (NS_FAILED(rv
)) return rv
;
796 newsDriveDefault
= PR_TRUE
;
798 oldNewsPath
->GetFileSpec(&newsSpec
);
799 rv
= GetSizes(newsSpec
, PR_TRUE
, &totalNewsSize
);
800 newsDrive
= newsSpec
.GetDiskSpaceAvailable();
803 // Compute the space needed to migrate the profile
805 if(newsDriveDefault
&& localMailDriveDefault
&& summaryMailDriveDefault
) // DEFAULT: All on the same drive
807 totalRequired
= totalNewsSize
+ totalLocalMailSize
+ totalSummaryFileSize
+ totalProfileSize
;
808 rv
= ComputeSpaceRequirements(DriveID
, SpaceRequired
, profileDrive
, totalRequired
);
810 enoughSpace
= PR_FALSE
;
814 rv
= ComputeSpaceRequirements(DriveID
, SpaceRequired
, profileDrive
, totalProfileSize
);
816 enoughSpace
= PR_FALSE
;
817 rv
= ComputeSpaceRequirements(DriveID
, SpaceRequired
, localMailDrive
, totalLocalMailSize
);
819 enoughSpace
= PR_FALSE
;
820 rv
= ComputeSpaceRequirements(DriveID
, SpaceRequired
, summaryMailDrive
, totalSummaryFileSize
);
822 enoughSpace
= PR_FALSE
;
823 rv
= ComputeSpaceRequirements(DriveID
, SpaceRequired
, newsDrive
, totalNewsSize
);
825 enoughSpace
= PR_FALSE
;
830 mErrorCode
= MIGRATION_RETRY
;
834 ////////////////////////////////////////////////////////////////////////////
835 // If we reached this point, there is enough room to do a migration.
836 // Start creating directories and setting new pref values.
837 ////////////////////////////////////////////////////////////////////////////
839 /* Create the new profile tree for 5.x */
840 rv
= CreateNewUser5Tree(oldProfilePath
, newProfilePath
);
841 if (NS_FAILED(rv
)) return rv
;
844 if (serverType
== POP_4X_MAIL_TYPE
) {
846 rv
= newPOPMailPath
->Exists(&exists
);
847 if (NS_FAILED(rv
)) return rv
;
849 rv
= newPOPMailPath
->CreateDir();
850 if (NS_FAILED(rv
)) return rv
;
853 rv
= newPOPMailPath
->AppendRelativeUnixPath(NEW_MAIL_DIR_NAME
);
854 if (NS_FAILED(rv
)) return rv
;
856 rv
= newPOPMailPath
->Exists(&exists
);
857 if (NS_FAILED(rv
)) return rv
;
859 rv
= newPOPMailPath
->CreateDir();
860 if (NS_FAILED(rv
)) return rv
;
864 // temporarily go through nsFileSpec
865 nsFileSpec newPOPMailPathSpec
;
866 newPOPMailPath
->GetFileSpec(&newPOPMailPathSpec
);
868 nsCOMPtr
<nsILocalFile
> newPOPMailPathFile
;
869 NS_FileSpecToIFile(&newPOPMailPathSpec
,
870 getter_AddRefs(newPOPMailPathFile
));
872 rv
= m_prefBranch
->SetComplexValue(PREF_MAIL_DIRECTORY
,
873 NS_GET_IID(nsILocalFile
),
875 if (NS_FAILED(rv
)) return rv
;
878 m_prefBranch
->GetCharPref(PREF_NETWORK_HOSTS_POP_SERVER
, &popServerName
);
880 nsCAutoString
popServerNamewithoutPort(popServerName
);
881 PRInt32 colonPos
= popServerNamewithoutPort
.FindChar(':');
883 if (colonPos
!= -1 ) {
884 popServerNamewithoutPort
.Truncate(colonPos
);
885 rv
= newPOPMailPath
->AppendRelativeUnixPath(popServerNamewithoutPort
.get());
888 rv
= newPOPMailPath
->AppendRelativeUnixPath(popServerName
);
891 if (NS_FAILED(rv
)) return rv
;
893 rv
= newPOPMailPath
->Exists(&exists
);
894 if (NS_FAILED(rv
)) return rv
;
896 rv
= newPOPMailPath
->CreateDir();
897 if (NS_FAILED(rv
)) return rv
;
900 else if (serverType
== IMAP_4X_MAIL_TYPE
) {
901 if( copyMailFileInMigration
) // copy mail files in migration
903 rv
= newIMAPLocalMailPath
->Exists(&exists
);
904 if (NS_FAILED(rv
)) return rv
;
906 rv
= newIMAPLocalMailPath
->CreateDir();
907 if (NS_FAILED(rv
)) return rv
;
910 rv
= newIMAPLocalMailPath
->AppendRelativeUnixPath(NEW_MAIL_DIR_NAME
);
911 if (NS_FAILED(rv
)) return rv
;
913 /* Now create the new "Mail/Local Folders" directory */
914 rv
= newIMAPLocalMailPath
->Exists(&exists
);
915 if (NS_FAILED(rv
)) return rv
;
917 newIMAPLocalMailPath
->CreateDir();
921 // temporarily go through nsFileSpec
922 nsFileSpec newIMAPLocalMailPathSpec
;
923 newIMAPLocalMailPath
->GetFileSpec(&newIMAPLocalMailPathSpec
);
925 nsCOMPtr
<nsILocalFile
> newIMAPLocalMailPathFile
;
926 NS_FileSpecToIFile(&newIMAPLocalMailPathSpec
,
927 getter_AddRefs(newIMAPLocalMailPathFile
));
929 rv
= m_prefBranch
->SetComplexValue(PREF_MAIL_DIRECTORY
,
930 NS_GET_IID(nsILocalFile
),
931 newIMAPLocalMailPathFile
);
932 if (NS_FAILED(rv
)) return rv
;
935 rv
= newIMAPLocalMailPath
->AppendRelativeUnixPath(NEW_LOCAL_MAIL_DIR_NAME
);
936 if (NS_FAILED(rv
)) return rv
;
937 rv
= newIMAPLocalMailPath
->Exists(&exists
);
938 if (NS_FAILED(rv
)) return rv
;
940 rv
= newIMAPLocalMailPath
->CreateDir();
941 if (NS_FAILED(rv
)) return rv
;
944 /* Now deal with the IMAP mail summary file location */
945 rv
= newIMAPMailPath
->Exists(&exists
);
946 if (NS_FAILED(rv
)) return rv
;
948 rv
= newIMAPMailPath
->CreateDir();
949 if (NS_FAILED(rv
)) return rv
;
952 rv
= newIMAPMailPath
->AppendRelativeUnixPath(NEW_IMAPMAIL_DIR_NAME
);
953 if (NS_FAILED(rv
)) return rv
;
955 rv
= newIMAPMailPath
->Exists(&exists
);
956 if (NS_FAILED(rv
)) return rv
;
958 rv
= newIMAPMailPath
->CreateDir();
959 if (NS_FAILED(rv
)) return rv
;
963 // temporarily go through nsFileSpec
964 nsFileSpec newIMAPMailPathSpec
;
965 newIMAPMailPath
->GetFileSpec(&newIMAPMailPathSpec
);
967 nsCOMPtr
<nsILocalFile
> newIMAPMailPathFile
;
968 NS_FileSpecToIFile(&newIMAPMailPathSpec
,
969 getter_AddRefs(newIMAPMailPathFile
));
971 rv
= m_prefBranch
->SetComplexValue(PREF_MAIL_IMAP_ROOT_DIR
,
972 NS_GET_IID(nsILocalFile
),
973 newIMAPMailPathFile
);
974 if (NS_FAILED(rv
)) return rv
;
980 // temporarily go through nsFileSpec
981 nsFileSpec oldIMAPLocalMailPathSpec
;
982 oldIMAPLocalMailPath
->GetFileSpec(&oldIMAPLocalMailPathSpec
);
984 nsCOMPtr
<nsILocalFile
> oldIMAPLocalMailPathFile
;
985 NS_FileSpecToIFile(&oldIMAPLocalMailPathSpec
,
986 getter_AddRefs(oldIMAPLocalMailPathFile
));
988 rv
= m_prefBranch
->SetComplexValue(PREF_MAIL_DIRECTORY
,
989 NS_GET_IID(nsILocalFile
),
990 oldIMAPLocalMailPathFile
);
991 if (NS_FAILED(rv
)) return rv
;
994 // temporarily go through nsFileSpec
995 nsFileSpec oldIMAPMailPathSpec
;
996 oldIMAPMailPath
->GetFileSpec(&oldIMAPMailPathSpec
);
998 nsCOMPtr
<nsILocalFile
> oldIMAPMailPathFile
;
999 NS_FileSpecToIFile(&oldIMAPMailPathSpec
,
1000 getter_AddRefs(oldIMAPMailPathFile
));
1002 rv
= m_prefBranch
->SetComplexValue(PREF_MAIL_IMAP_ROOT_DIR
,
1003 NS_GET_IID(nsILocalFile
),
1004 oldIMAPMailPathFile
);
1005 if (NS_FAILED(rv
)) return rv
;
1010 #ifdef HAVE_MOVEMAIL
1011 else if (serverType
== MOVEMAIL_4X_MAIL_TYPE
) {
1013 rv
= newMOVEMAILMailPath
->Exists(&exists
);
1014 if (NS_FAILED(rv
)) return rv
;
1016 rv
= newMOVEMAILMailPath
->CreateDir();
1017 if (NS_FAILED(rv
)) return rv
;
1020 rv
= newMOVEMAILMailPath
->AppendRelativeUnixPath(NEW_MAIL_DIR_NAME
);
1021 if (NS_FAILED(rv
)) return rv
;
1023 rv
= newMOVEMAILMailPath
->Exists(&exists
);
1024 if (NS_FAILED(rv
)) return rv
;
1026 rv
= newMOVEMAILMailPath
->CreateDir();
1027 if (NS_FAILED(rv
)) return rv
;
1031 // temporarily go through nsFileSpec
1032 nsFileSpec newMOVEMAILPathSpec
;
1033 newMOVEMAILMailPath
->GetFileSpec(&newMOVEMAILPathSpec
);
1035 nsCOMPtr
<nsILocalFile
> newMOVEMAILPathFile
;
1036 NS_FileSpecToIFile(&newMOVEMAILPathSpec
,
1037 getter_AddRefs(newMOVEMAILPathFile
));
1039 rv
= m_prefBranch
->SetComplexValue(PREF_MAIL_DIRECTORY
,
1040 NS_GET_IID(nsILocalFile
),
1041 newMOVEMAILPathFile
);
1042 if (NS_FAILED(rv
)) return rv
;
1045 rv
= newMOVEMAILMailPath
->AppendRelativeUnixPath(NEW_MOVEMAIL_DIR_NAME
);
1046 if (NS_FAILED(rv
)) return rv
;
1048 rv
= newMOVEMAILMailPath
->Exists(&exists
);
1049 if (NS_FAILED(rv
)) return rv
;
1051 rv
= newMOVEMAILMailPath
->CreateDir();
1052 if (NS_FAILED(rv
)) return rv
;
1056 #endif /* HAVE_MOVEMAIL */
1058 NS_ASSERTION(0,"failure, didn't recognize your mail server type.\n");
1059 return NS_ERROR_UNEXPECTED
;
1062 ////////////////////////////////////////////////////////////////////////////
1063 // Set all the appropriate NEWS prefs.
1064 ////////////////////////////////////////////////////////////////////////////
1066 rv
= newNewsPath
->Exists(&exists
);
1067 if (NS_FAILED(rv
)) return rv
;
1069 rv
= newNewsPath
->CreateDir();
1070 if (NS_FAILED(rv
)) return rv
;
1073 rv
= newNewsPath
->AppendRelativeUnixPath(NEW_NEWS_DIR_NAME
);
1074 if (NS_FAILED(rv
)) return rv
;
1076 rv
= newNewsPath
->Exists(&exists
);
1077 if (NS_FAILED(rv
)) return rv
;
1079 rv
= newNewsPath
->CreateDir();
1080 if (NS_FAILED(rv
)) return rv
;
1084 // temporarily go through nsFileSpec
1085 nsFileSpec newNewsPathSpec
;
1086 newNewsPath
->GetFileSpec(&newNewsPathSpec
);
1088 nsCOMPtr
<nsILocalFile
> newNewsPathFile
;
1089 NS_FileSpecToIFile(&newNewsPathSpec
,
1090 getter_AddRefs(newNewsPathFile
));
1092 rv
= m_prefBranch
->SetComplexValue(PREF_NEWS_DIRECTORY
,
1093 NS_GET_IID(nsILocalFile
),
1095 if (NS_FAILED(rv
)) return rv
;
1098 PRBool needToRenameFilterFiles
;
1099 if (PL_strcmp(IMAP_MAIL_FILTER_FILE_NAME_IN_4x
,IMAP_MAIL_FILTER_FILE_NAME_IN_5x
)) {
1100 #ifdef IMAP_MAIL_FILTER_FILE_NAME_FORMAT_IN_4x
1101 // if we defined a format, the filter files don't live in the host directories
1102 // (mac does this.) we'll take care of those filter files later, in DoSpecialUpdates()
1103 needToRenameFilterFiles
= PR_FALSE
;
1105 needToRenameFilterFiles
= PR_TRUE
;
1106 #endif /* IMAP_MAIL_FILTER_FILE_NAME_FORMAT_IN_4x */
1109 // if the name was the same in 4x as in 5x, no need to rename it
1110 needToRenameFilterFiles
= PR_FALSE
;
1113 // just copy what we need
1114 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, COOKIES_FILE_NAME_IN_4x
);
1115 if (NS_FAILED(rv
)) return rv
;
1116 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, BOOKMARKS_FILE_NAME_IN_4x
);
1117 if (NS_FAILED(rv
)) return rv
;
1118 #if defined(XP_MACOSX)
1119 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, SECURITY_PATH
, PR_TRUE
);
1120 if (NS_FAILED(rv
)) return rv
;
1122 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, PSM_CERT7_DB
);
1123 if (NS_FAILED(rv
)) return rv
;
1124 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, PSM_KEY3_DB
);
1125 if (NS_FAILED(rv
)) return rv
;
1126 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, PSM_SECMODULE_DB
);
1127 if (NS_FAILED(rv
)) return rv
;
1128 #endif /* XP_MACOSX */
1130 #if defined(XP_MACOSX)
1131 // Copy the Mac filter rule files which sits at the top level dir of a 4.x profile.
1132 if(serverType
== IMAP_4X_MAIL_TYPE
) {
1133 rv
= CopyFilesByPattern(oldProfilePath
, newProfilePath
, MAC_RULES_FILE_ENDING_STRING_IN_4X
);
1134 NS_ENSURE_SUCCESS(rv
,rv
);
1138 rv
= DoTheCopy(oldNewsPath
, newNewsPath
, PR_TRUE
);
1139 if (NS_FAILED(rv
)) return rv
;
1141 #ifdef NEED_TO_COPY_AND_RENAME_NEWSRC_FILES
1142 /* in 4.x, the newsrc files were in $HOME. Now that we can have multiple
1143 * profiles in 5.x, with the same user, this won't fly.
1144 * when they migrate, we need to copy from $HOME/.newsrc-<host> to
1145 * ~/.mozilla/<profile>/News/newsrc-<host>
1147 rv
= CopyAndRenameNewsrcFiles(newNewsPath
);
1148 if (NS_FAILED(rv
)) return rv
;
1149 #endif /* NEED_TO_COPY_AND_RENAME_NEWSRC_FILES */
1151 if (serverType
== IMAP_4X_MAIL_TYPE
) {
1152 if( copyMailFileInMigration
) // copy mail files in migration
1154 rv
= DoTheCopyAndRename(oldIMAPMailPath
, newIMAPMailPath
, PR_TRUE
, needToRenameFilterFiles
, IMAP_MAIL_FILTER_FILE_NAME_IN_4x
, IMAP_MAIL_FILTER_FILE_NAME_IN_5x
);
1155 if (NS_FAILED(rv
)) return rv
;
1156 rv
= DoTheCopyAndRename(oldIMAPLocalMailPath
, newIMAPLocalMailPath
, PR_TRUE
, needToRenameFilterFiles
,IMAP_MAIL_FILTER_FILE_NAME_IN_4x
,IMAP_MAIL_FILTER_FILE_NAME_IN_5x
);
1157 if (NS_FAILED(rv
)) return rv
;
1159 else // Copy & Rename filter files
1162 // don't care if this fails
1163 (void)DoTheCopyAndRename(oldIMAPMailPath
, PR_TRUE
, IMAP_MAIL_FILTER_FILE_NAME_IN_4x
, IMAP_MAIL_FILTER_FILE_NAME_IN_5x
);
1165 // Local Folders path
1166 // don't care if this fails
1167 (void)DoTheCopyAndRename(oldIMAPLocalMailPath
, PR_TRUE
, IMAP_MAIL_FILTER_FILE_NAME_IN_4x
, IMAP_MAIL_FILTER_FILE_NAME_IN_5x
);
1170 else if (serverType
== POP_4X_MAIL_TYPE
) {
1171 // fix for bug #202010
1172 // copy over the pop filter and popstate files now
1173 // and later, in DoSpecialUpdates()
1174 // we'll move and rename them
1175 #ifdef POP_MAIL_FILTER_FILE_NAME_IN_4x
1176 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, POP_MAIL_FILTER_FILE_NAME_IN_4x
);
1177 if (NS_FAILED(rv
)) return rv
;
1180 #ifdef POPSTATE_FILE_IN_4x
1181 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, POPSTATE_FILE_IN_4x
);
1182 if (NS_FAILED(rv
)) return rv
;
1185 rv
= DoTheCopy(oldPOPMailPath
, newPOPMailPath
, PR_TRUE
);
1186 if (NS_FAILED(rv
)) return rv
;
1188 #ifdef HAVE_MOVEMAIL
1189 else if (serverType
== MOVEMAIL_4X_MAIL_TYPE
) {
1190 // in 4.x, the movemail filter name was the same as the pop filter name
1191 // copy over the filter file now
1192 // and later, in DoSpecialUpdates()
1193 // we'll move and rename them
1194 rv
= DoTheCopy(oldProfilePath
, newProfilePath
, POP_MAIL_FILTER_FILE_NAME_IN_4x
);
1195 if (NS_FAILED(rv
)) return rv
;
1197 rv
= DoTheCopy(oldMOVEMAILMailPath
, newMOVEMAILMailPath
, PR_TRUE
);
1199 #endif /* HAVE_MOVEMAIL */
1201 NS_ASSERTION(0, "unknown mail server type!");
1202 return NS_ERROR_FAILURE
;
1205 // Don't inherit the 4.x cache file location for mozilla!
1206 // The cache pref later gets set with a default in nsAppRunner::InitCachePrefs().
1207 m_prefBranch
->ClearUserPref(PREF_BROWSER_CACHE_DIRECTORY
);
1209 rv
= DoSpecialUpdates(newProfilePath
);
1210 if (NS_FAILED(rv
)) return rv
;
1211 PR_FREEIF(popServerName
);
1213 nsXPIDLCString path
;
1215 newProfilePath
->GetNativePath(getter_Copies(path
));
1216 NS_NewNativeLocalFile(path
, PR_TRUE
, getter_AddRefs(newPrefsFile
));
1218 rv
= newPrefsFile
->AppendNative(NS_LITERAL_CSTRING(PREF_FILE_NAME_IN_5x
));
1219 if (NS_FAILED(rv
)) return rv
;
1221 rv
=psvc
->SavePrefFile(newPrefsFile
);
1222 if (NS_FAILED(rv
)) return rv
;
1223 rv
=psvc
->ResetPrefs();
1224 if (NS_FAILED(rv
)) return rv
;
1226 PRBool flagExists
= PR_FALSE
;
1227 m_prefsFile
->Exists(&flagExists
); //Delete the prefs.js file in the temp directory.
1229 m_prefsFile
->Remove(PR_FALSE
);
1231 systemTempDir
->Exists(&flagExists
); //Delete the unique dir in the system temp dir.
1233 systemTempDir
->Remove(PR_FALSE
);
1239 /*----------------------------------------------------------------------------
1240 * CreateNewUsers5Tree creates the directory called users5 (parent of the
1241 * of the profile directories) and the profile directory itself
1242 *---------------------------------------------------------------------------*/
1245 nsPrefMigration::CreateNewUser5Tree(nsIFileSpec
* oldProfilePath
, nsIFileSpec
* newProfilePath
)
1250 NS_ASSERTION(*PREF_FILE_NAME_IN_4x
, "don't know how to migrate your platform");
1251 if (!*PREF_FILE_NAME_IN_4x
) {
1252 return NS_ERROR_UNEXPECTED
;
1255 /* Copy the old prefs file to the new profile directory for modification and reading.
1256 after copying it, rename it to pref.js, the 5.x pref file name on all platforms */
1257 nsCOMPtr
<nsIFileSpec
> oldPrefsFile
;
1258 rv
= NS_NewFileSpec(getter_AddRefs(oldPrefsFile
));
1259 if (NS_FAILED(rv
)) return rv
;
1261 rv
= oldPrefsFile
->FromFileSpec(oldProfilePath
);
1262 if (NS_FAILED(rv
)) return rv
;
1264 rv
= oldPrefsFile
->AppendRelativeUnixPath(PREF_FILE_NAME_IN_4x
);
1265 if (NS_FAILED(rv
)) return rv
;
1268 /* the new prefs file */
1269 nsCOMPtr
<nsIFileSpec
> newPrefsFile
;
1270 rv
= NS_NewFileSpec(getter_AddRefs(newPrefsFile
));
1271 if (NS_FAILED(rv
)) return rv
;
1273 rv
= newPrefsFile
->FromFileSpec(newProfilePath
);
1274 if (NS_FAILED(rv
)) return rv
;
1276 rv
= newPrefsFile
->Exists(&exists
);
1279 rv
= newPrefsFile
->CreateDir();
1282 rv
= oldPrefsFile
->CopyToDir(newPrefsFile
);
1283 NS_ASSERTION(NS_SUCCEEDED(rv
),"failed to copy prefs file");
1285 rv
= newPrefsFile
->AppendRelativeUnixPath(PREF_FILE_NAME_IN_4x
);
1286 rv
= newPrefsFile
->Rename(PREF_FILE_NAME_IN_5x
);
1288 rv
= getPrefService();
1289 if (NS_FAILED(rv
)) return rv
;
1294 /*---------------------------------------------------------------------------------
1295 * GetDirFromPref gets a directory based on a preference set in the 4.x
1296 * preferences file, adds a 5 and resets the preference.
1299 * oldProfilePath - the path to the old 4.x profile directory.
1300 * currently only used by UNIX
1302 * newProfilePath - the path to the 5.0 profile directory
1303 * currently only used by UNIX
1305 * newDirName - the leaf name of the directory in the 5.0 world that corresponds to
1306 * this pref. Examples: "Mail", "ImapMail", "News".
1307 * only used on UNIX.
1309 * pref - the pref in the "dot" format (e.g. mail.directory)
1311 * OUTPUT: newPath - The old path with a 5 added (on mac and windows)
1312 * the newProfilePath + "/" + newDirName (on UNIX)
1313 * oldPath - The old path from the pref (if any)
1316 * RETURNS: NS_OK if the pref was successfully pulled from the prefs file
1318 *--------------------------------------------------------------------------------*/
1320 nsPrefMigration::GetDirFromPref(nsIFileSpec
* oldProfilePath
, nsIFileSpec
* newProfilePath
, const char *newDirName
, const char* pref
, nsIFileSpec
* newPath
, nsIFileSpec
* oldPath
)
1324 if (!oldProfilePath
|| !newProfilePath
|| !newDirName
|| !pref
|| !newPath
|| !oldPath
) return NS_ERROR_NULL_POINTER
;
1326 rv
= getPrefService();
1327 if (NS_FAILED(rv
)) return rv
;
1329 nsCOMPtr
<nsIFileSpec
> oldPrefPath
;
1330 nsXPIDLCString oldPrefPathStr
;
1331 rv
= m_prefBranch
->GetCharPref(pref
, getter_Copies(oldPrefPathStr
));
1332 if (NS_FAILED(rv
)) return rv
;
1334 // the default on the mac was "". doing GetFileXPref on that would return
1335 // the current working directory, like viewer_debug. yikes!
1336 if (oldPrefPathStr
.IsEmpty()) {
1337 rv
= NS_ERROR_FAILURE
;
1339 if (NS_FAILED(rv
)) return rv
;
1341 nsCOMPtr
<nsILocalFile
> oldPrefPathFile
;
1342 rv
= m_prefBranch
->GetComplexValue(pref
, NS_GET_IID(nsILocalFile
),
1343 getter_AddRefs(oldPrefPathFile
));
1344 if (NS_FAILED(rv
)) return rv
;
1346 // convert nsILocalFile to nsIFileSpec
1347 rv
= oldPrefPathFile
->GetNativePath(oldPrefPathStr
);
1348 if (NS_FAILED(rv
)) return rv
;
1350 rv
= NS_NewFileSpec(getter_AddRefs(oldPrefPath
));
1351 if (NS_FAILED(rv
)) return rv
;
1353 rv
= oldPrefPath
->SetNativePath(oldPrefPathStr
);
1354 if (NS_FAILED(rv
)) return rv
;
1356 // oldPath will also needs the conversion from nsILocalFile
1357 // this is nasty, eventually we'll switch entirely over to nsILocalFile
1358 rv
= oldPath
->SetNativePath(oldPrefPathStr
);
1359 if (NS_FAILED(rv
)) return rv
;
1363 // what if they don't want to go to <profile>/<newDirName>?
1364 // what if unix users want "mail.directory" + "5" (like "~/ns_imap5")
1365 // or "mail.imap.root_dir" + "5" (like "~/nsmail5")?
1366 // should we let them? no. let's migrate them to
1367 // <profile>/Mail and <profile>/ImapMail
1368 // let's make all three platforms the same.
1371 nsCOMPtr
<nsIFileSpec
> oldPrefPathParent
;
1372 rv
= oldPrefPath
->GetParent(getter_AddRefs(oldPrefPathParent
));
1373 if (NS_FAILED(rv
)) return rv
;
1375 // if the pref pointed to the default directory
1376 // treat it as if the pref wasn't set
1377 // this way it will get migrated as the user expects
1379 rv
= oldProfilePath
->Equals(oldPrefPathParent
, &pathsMatch
);
1380 if (NS_SUCCEEDED(rv
) && pathsMatch
) {
1381 #endif /* XP_UNIX */
1382 rv
= newPath
->FromFileSpec(newProfilePath
);
1383 if (NS_FAILED(rv
)) return rv
;
1386 nsXPIDLCString leafname
;
1387 rv
= newPath
->FromFileSpec(oldPath
);
1388 if (NS_FAILED(rv
)) return rv
;
1389 rv
= newPath
->GetLeafName(getter_Copies(leafname
));
1390 if (NS_FAILED(rv
)) return rv
;
1391 nsCString
newleafname((const char *)leafname
);
1392 newleafname
+= NEW_DIR_SUFFIX
;
1393 rv
= newPath
->SetLeafName(newleafname
.get());
1394 if (NS_FAILED(rv
)) return rv
;
1397 rv
= SetPremigratedFilePref(pref
, oldPath
);
1398 if (NS_FAILED(rv
)) return rv
;
1401 /* on UNIX, we kept the newsrc files in "news.directory", (which was usually ~)
1402 * and the summary files in ~/.netscape/xover-cache
1403 * oldPath should point to ~/.netscape/xover-cache, not "news.directory"
1404 * but we want to save the old "news.directory" in "premigration.news.directory"
1405 * later, again for UNIX only,
1406 * we will copy the .newsrc files (from "news.directory") into the new <profile>/News directory.
1409 if (PL_strcmp(PREF_NEWS_DIRECTORY
, pref
) == 0) {
1410 rv
= oldPath
->FromFileSpec(oldProfilePath
);
1411 if (NS_FAILED(rv
)) return rv
;
1412 rv
= oldPath
->AppendRelativeUnixPath(OLD_NEWS_DIR_NAME
);
1413 if (NS_FAILED(rv
)) return rv
;
1415 #endif /* XP_UNIX */
1420 nsCStringEndsWith(nsCString
& name
, const char *ending
)
1422 if (!ending
) return PR_FALSE
;
1424 PRInt32 len
= name
.Length();
1425 if (len
== 0) return PR_FALSE
;
1427 PRInt32 endingLen
= PL_strlen(ending
);
1428 if (len
> endingLen
&& name
.RFind(ending
, PR_TRUE
) == len
- endingLen
) {
1436 #ifdef NEED_TO_COPY_AND_RENAME_NEWSRC_FILES
1438 nsCStringStartsWith(nsCString
& name
, const char *starting
)
1440 if (!starting
) return PR_FALSE
;
1441 PRInt32 len
= name
.Length();
1442 if (len
== 0) return PR_FALSE
;
1444 PRInt32 startingLen
= PL_strlen(starting
);
1445 if (len
> startingLen
&& name
.RFind(starting
, PR_TRUE
) == 0) {
1454 /*---------------------------------------------------------------------------------
1455 * GetSizes reads the 4.x files in the profile tree and accumulates their sizes
1463 *--------------------------------------------------------------------------------*/
1465 nsPrefMigration::GetSizes(nsFileSpec inputPath
, PRBool readSubdirs
, PRUint32
*sizeTotal
)
1467 nsCAutoString fileOrDirNameStr
;
1469 for (nsDirectoryIterator
dir(inputPath
, PR_FALSE
); dir
.Exists(); dir
++)
1471 nsFileSpec fileOrDirName
= dir
.Spec();
1472 char* folderName
= fileOrDirName
.GetLeafName();
1473 fileOrDirNameStr
.Assign(folderName
);
1474 if (!nsCStringEndsWith(fileOrDirNameStr
, MAIL_SUMMARY_SUFFIX_IN_4x
) && !nsCStringEndsWith(fileOrDirNameStr
, NEWS_SUMMARY_SUFFIX_IN_4x
) && !nsCStringEndsWith(fileOrDirNameStr
, SUMMARY_SUFFIX_IN_5x
)) /* Don't copy the summary files */
1476 if (fileOrDirName
.IsDirectory())
1480 GetSizes(fileOrDirName
, PR_TRUE
, sizeTotal
); /* re-enter the GetSizes function */
1484 *sizeTotal
+= fileOrDirName
.GetFileSize();
1486 nsCRT::free(folderName
);
1492 /*---------------------------------------------------------------------------*
1493 * ComputeSpaceRequirments
1495 *---------------------------------------------------------------------------*/
1497 nsPrefMigration::ComputeSpaceRequirements(PRInt64 DriveArray
[MAX_DRIVES
],
1498 PRUint32 SpaceReqArray
[MAX_DRIVES
],
1500 PRUint32 SpaceNeeded
)
1505 while(LL_NE(DriveArray
[i
],LL_Zero()) && LL_NE(DriveArray
[i
], Drive
) && i
< MAX_DRIVES
)
1508 if (LL_EQ(DriveArray
[i
], LL_Zero()))
1510 DriveArray
[i
] = Drive
;
1511 SpaceReqArray
[i
] += SpaceNeeded
;
1513 else if (LL_EQ(DriveArray
[i
], Drive
))
1514 SpaceReqArray
[i
] += SpaceNeeded
;
1516 return NS_ERROR_FAILURE
;
1518 LL_L2F(temp
, DriveArray
[i
]);
1519 if (SpaceReqArray
[i
] > temp
)
1520 return NS_ERROR_FAILURE
;
1525 #ifdef NEED_TO_COPY_AND_RENAME_NEWSRC_FILES
1527 nsPrefMigration::CopyAndRenameNewsrcFiles(nsIFileSpec
* newPathSpec
)
1530 nsCOMPtr
<nsIFileSpec
>oldPathSpec
;
1533 nsCAutoString fileOrDirNameStr
;
1535 rv
= GetPremigratedFilePref(PREF_NEWS_DIRECTORY
, getter_AddRefs(oldPathSpec
));
1536 if (NS_FAILED(rv
)) return rv
;
1537 rv
= oldPathSpec
->GetFileSpec(&oldPath
);
1538 if (NS_FAILED(rv
)) return rv
;
1539 rv
= newPathSpec
->GetFileSpec(&newPath
);
1540 if (NS_FAILED(rv
)) return rv
;
1542 for (nsDirectoryIterator
dir(oldPath
, PR_FALSE
); dir
.Exists(); dir
++)
1544 nsFileSpec fileOrDirName
= dir
.Spec(); //set first file or dir to a nsFileSpec
1545 //get the filename without the full path
1546 char* folderName
= fileOrDirName
.GetLeafName();
1547 fileOrDirNameStr
.Assign(folderName
);
1549 if (nsCStringStartsWith(fileOrDirNameStr
, NEWSRC_PREFIX_IN_4x
) || nsCStringStartsWith(fileOrDirNameStr
, SNEWSRC_PREFIX_IN_4x
)) {
1551 printf("newsrc file == %s\n",folderName
);
1552 #endif /* DEBUG_seth */
1554 rv
= fileOrDirName
.CopyToDir(newPath
);
1555 NS_ASSERTION(NS_SUCCEEDED(rv
),"failed to copy news file");
1557 nsFileSpec newFile
= newPath
;
1558 newFile
+= fileOrDirNameStr
.get();
1559 newFile
.Rename(folderName
+ 1); /* rename .newsrc-news to newsrc-news, no need to keep it hidden anymore */
1561 nsCRT::free(folderName
);
1566 #endif /* NEED_TO_COPY_AND_RENAME_NEWSRC_FILES */
1568 /*-------------------------------------------------------------------------
1569 * DoTheCopyAndRename copies the files listed in oldPath to newPath
1570 * and renames files, if necessary
1572 * INPUT: oldPath - The old profile path plus the specific data type
1573 * (e.g. mail or news)
1574 * newPath - The new profile path plus the specific data type
1578 * needToRenameFiles - do we need to search for files named oldFile
1579 * and rename them to newFile
1581 * oldFile - old file name (used for renaming)
1583 * newFile - new file name (used for renaming)
1585 * RETURNS: NS_OK if successful
1586 * NS_ERROR_FAILURE if failed
1588 *--------------------------------------------------------------------------*/
1590 nsPrefMigration::DoTheCopyAndRename(nsIFileSpec
* oldPathSpec
, nsIFileSpec
*newPathSpec
, PRBool readSubdirs
, PRBool needToRenameFiles
, const char *oldName
, const char *newName
)
1593 nsCAutoString fileOrDirNameStr
;
1597 rv
= oldPathSpec
->GetFileSpec(&oldPath
);
1598 if (NS_FAILED(rv
)) return rv
;
1599 rv
= newPathSpec
->GetFileSpec(&newPath
);
1600 if (NS_FAILED(rv
)) return rv
;
1602 for (nsDirectoryIterator
dir(oldPath
, PR_FALSE
); dir
.Exists(); dir
++)
1604 nsFileSpec fileOrDirName
= dir
.Spec(); //set first file or dir to a nsFileSpec
1605 //get the filename without the full path
1606 char* folderName
= fileOrDirName
.GetLeafName();
1607 fileOrDirNameStr
.Assign(folderName
);
1609 if (!nsCStringEndsWith(fileOrDirNameStr
, MAIL_SUMMARY_SUFFIX_IN_4x
) && !nsCStringEndsWith(fileOrDirNameStr
, NEWS_SUMMARY_SUFFIX_IN_4x
) && !nsCStringEndsWith(fileOrDirNameStr
, SUMMARY_SUFFIX_IN_5x
)) /* Don't copy the summary files */
1611 if (fileOrDirName
.IsDirectory())
1615 nsCOMPtr
<nsIFileSpec
> newPathExtended
;
1616 rv
= NS_NewFileSpecWithSpec(newPath
, getter_AddRefs(newPathExtended
));
1617 rv
= newPathExtended
->AppendRelativeUnixPath(folderName
);
1618 rv
= newPathExtended
->CreateDir();
1620 nsCOMPtr
<nsIFileSpec
>fileOrDirNameSpec
;
1621 rv
= NS_NewFileSpecWithSpec(fileOrDirName
, getter_AddRefs(fileOrDirNameSpec
));
1622 DoTheCopyAndRename(fileOrDirNameSpec
, newPathExtended
, PR_TRUE
, needToRenameFiles
, oldName
, newName
); /* re-enter the DoTheCopyAndRename function */
1627 rv
= fileOrDirName
.CopyToDir(newPath
);
1628 NS_ASSERTION(NS_SUCCEEDED(rv
),"failed to copy file");
1630 if (needToRenameFiles
) {
1631 // rename the file, if it matches
1632 if (fileOrDirNameStr
.Equals(oldName
)) {
1633 nsFileSpec newFile
= newPath
;
1634 newFile
+= fileOrDirNameStr
.get();
1635 newFile
.Rename(newName
);
1640 nsCRT::free(folderName
);
1646 /*-------------------------------------------------------------------------
1647 * DoTheCopyAndRename copies and renames files
1649 * INPUT: aPath - the path
1651 * aReadSubdirs - if sub directories should be handled
1653 * aOldFile - old file name (used for renaming)
1655 * aNewFile - new file name (used for renaming)
1657 * RETURNS: NS_OK if successful
1658 * NS_ERROR_FAILURE if failed
1660 *--------------------------------------------------------------------------*/
1662 nsPrefMigration::DoTheCopyAndRename(nsIFileSpec
* aPathSpec
, PRBool aReadSubdirs
, const char *aOldName
, const char *aNewName
)
1664 if( !aOldName
|| !aNewName
|| !strcmp(aOldName
, aNewName
) )
1665 return NS_ERROR_FAILURE
;
1668 nsFileSpec path
, file
;
1670 rv
= aPathSpec
->GetFileSpec(&path
);
1673 rv
= aPathSpec
->GetFileSpec(&file
);
1678 // Handle sub folders
1679 for (nsDirectoryIterator
dir(path
, PR_FALSE
); dir
.Exists(); dir
++)
1681 nsFileSpec fileOrDirName
= dir
.Spec(); //set first file or dir to a nsFileSpec
1682 if (fileOrDirName
.IsDirectory())
1686 nsCOMPtr
<nsIFileSpec
>fileOrDirNameSpec
;
1687 rv
= NS_NewFileSpecWithSpec(fileOrDirName
, getter_AddRefs(fileOrDirNameSpec
));
1688 DoTheCopyAndRename(fileOrDirNameSpec
, aReadSubdirs
, aOldName
, aNewName
); /* re-enter the DoTheCopyAndRename function */
1695 nsCOMPtr
<nsILocalFile
> localFileOld
, localFileDirectory
;
1696 rv
= NS_FileSpecToIFile(&file
, getter_AddRefs(localFileOld
));
1699 rv
= NS_FileSpecToIFile(&path
, getter_AddRefs(localFileDirectory
));
1702 NS_ConvertUTF8toUTF16
newName(aNewName
);
1703 localFileOld
->CopyTo(localFileDirectory
, newName
);
1709 nsPrefMigration::CopyFilesByPattern(nsIFileSpec
* oldPathSpec
, nsIFileSpec
* newPathSpec
, const char *pattern
)
1714 nsresult rv
= oldPathSpec
->GetFileSpec(&oldPath
);
1715 NS_ENSURE_SUCCESS(rv
,rv
);
1716 rv
= newPathSpec
->GetFileSpec(&newPath
);
1717 NS_ENSURE_SUCCESS(rv
,rv
);
1719 for (nsDirectoryIterator
dir(oldPath
, PR_FALSE
); dir
.Exists(); dir
++)
1721 nsFileSpec fileOrDirName
= dir
.Spec(); //set first file or dir to a nsFileSpec
1723 if (fileOrDirName
.IsDirectory())
1726 nsCAutoString
fileOrDirNameStr(fileOrDirName
.GetLeafName());
1727 if (!nsCStringEndsWith(fileOrDirNameStr
, pattern
))
1731 rv
= fileOrDirName
.CopyToDir(newPath
);
1732 NS_ENSURE_SUCCESS(rv
,rv
);
1739 nsPrefMigration::DoTheCopy(nsIFileSpec
* oldPath
, nsIFileSpec
* newPath
, PRBool readSubdirs
)
1741 return DoTheCopyAndRename(oldPath
, newPath
, readSubdirs
, PR_FALSE
, "", "");
1745 nsPrefMigration::DoTheCopy(nsIFileSpec
* oldPath
, nsIFileSpec
* newPath
, const char *fileOrDirName
, PRBool isDirectory
)
1751 nsCOMPtr
<nsIFileSpec
> oldSubPath
;
1753 NS_NewFileSpec(getter_AddRefs(oldSubPath
));
1754 oldSubPath
->FromFileSpec(oldPath
);
1755 rv
= oldSubPath
->AppendRelativeUnixPath(fileOrDirName
);
1756 if (NS_FAILED(rv
)) return rv
;
1758 rv
= oldSubPath
->Exists(&exist
);
1759 if (NS_FAILED(rv
)) return rv
;
1762 rv
= oldSubPath
->CreateDir();
1763 if (NS_FAILED(rv
)) return rv
;
1766 nsCOMPtr
<nsIFileSpec
> newSubPath
;
1768 NS_NewFileSpec(getter_AddRefs(newSubPath
));
1769 newSubPath
->FromFileSpec(newPath
);
1770 rv
= newSubPath
->AppendRelativeUnixPath(fileOrDirName
);
1771 if (NS_FAILED(rv
)) return rv
;
1772 rv
= newSubPath
->Exists(&exist
);
1773 if (NS_FAILED(rv
)) return rv
;
1776 rv
= newSubPath
->CreateDir();
1777 if (NS_FAILED(rv
)) return rv
;
1780 DoTheCopy(oldSubPath
, newSubPath
, PR_TRUE
);
1784 nsCOMPtr
<nsIFileSpec
> file
;
1785 NS_NewFileSpec(getter_AddRefs(file
));
1786 file
->FromFileSpec(oldPath
);
1787 rv
= file
->AppendRelativeUnixPath(fileOrDirName
);
1788 if( NS_FAILED(rv
) ) return rv
;
1790 rv
= file
->Exists(&exist
);
1791 if( NS_FAILED(rv
) ) return rv
;
1793 file
->CopyToDir(newPath
);
1800 #if defined(NEED_TO_FIX_4X_COOKIES)
1801 /* this code only works on the mac. in 4.x, the line endings where '\r' on the mac.
1802 this code will fix the expire times and the line endings, so the code is nsCookie.cpp
1803 can read the migrate cookies. */
1805 GetCookieLine(nsInputFileStream
&strm
, nsAutoString
& aLine
)
1813 /* note that eof is not set until we read past the end of the file */
1818 /* stop at the '\r' */
1820 aLine
.Append(PRUnichar(c
));
1830 PutCookieLine(nsOutputFileStream
&strm
, const nsString
& aLine
)
1832 /* allocate a buffer from the heap */
1833 char * cp
= ToNewCString(aLine
);
1835 return NS_ERROR_FAILURE
;
1838 /* output each character */
1844 // the lines in a 5.x cookie file call end with '\n', on all platforms
1850 Fix4xCookies(nsIFileSpec
* profilePath
) {
1851 nsAutoString inBuffer
, outBuffer
;
1852 nsFileSpec profileDirectory
;
1853 nsresult rv
= profilePath
->GetFileSpec(&profileDirectory
);
1854 if (NS_FAILED(rv
)) {
1858 /* open input file */
1859 nsFileSpec
oldCookies(profileDirectory
);
1860 oldCookies
+= COOKIES_FILE_NAME_IN_4x
;
1862 /* it is possible that the 4.x cookies file does not exist. just return normally. see #55444 */
1863 if (!oldCookies
.Exists()) return NS_OK
;
1865 nsInputFileStream
inStream(oldCookies
);
1866 if (!inStream
.is_open()) {
1867 return NS_ERROR_FAILURE
;
1870 /* open output file */
1871 nsFileSpec
newCookies(profileDirectory
);
1872 newCookies
+= COOKIES_FILE_NAME_IN_5x
;
1874 nsOutputFileStream
outStream(newCookies
);
1875 if (!outStream
.is_open()) {
1876 return NS_ERROR_FAILURE
;
1879 while (GetCookieLine(inStream
,inBuffer
) != -1){
1881 /* skip line if it is a comment or null line */
1882 if (inBuffer
.IsEmpty() || inBuffer
.CharAt(0) == '#' ||
1883 inBuffer
.CharAt(0) == nsCRT::CR
|| inBuffer
.CharAt(0) == nsCRT::LF
) {
1884 PutCookieLine(outStream
, inBuffer
);
1888 /* locate expire field, skip line if it does not contain all its fields */
1889 int hostIndex
, isDomainIndex
, pathIndex
, xxxIndex
, expiresIndex
, nameIndex
, cookieIndex
;
1891 if ((isDomainIndex
=inBuffer
.FindChar('\t', hostIndex
)+1) == 0 ||
1892 (pathIndex
=inBuffer
.FindChar('\t', isDomainIndex
)+1) == 0 ||
1893 (xxxIndex
=inBuffer
.FindChar('\t', pathIndex
)+1) == 0 ||
1894 (expiresIndex
=inBuffer
.FindChar('\t', xxxIndex
)+1) == 0 ||
1895 (nameIndex
=inBuffer
.FindChar('\t', expiresIndex
)+1) == 0 ||
1896 (cookieIndex
=inBuffer
.FindChar('\t', nameIndex
)+1) == 0 ) {
1900 /* separate the expires field from the rest of the cookie line */
1901 nsAutoString prefix
, expiresString
, suffix
;
1902 inBuffer
.Mid(prefix
, hostIndex
, expiresIndex
-hostIndex
-1);
1903 inBuffer
.Mid(expiresString
, expiresIndex
, nameIndex
-expiresIndex
-1);
1904 inBuffer
.Mid(suffix
, nameIndex
, inBuffer
.Length()-nameIndex
);
1906 /* correct the expires field */
1907 char * expiresCString
= ToNewCString(expiresString
);
1908 unsigned long expires
= strtoul(expiresCString
, nsnull
, 10);
1909 NS_Free(expiresCString
);
1911 /* if the cookie is supposed to expire at the end of the session
1912 * expires == 0. don't adjust those cookies.
1915 expires
-= SECONDS_BETWEEN_1900_AND_1970
;
1917 char dateString
[36];
1918 PR_snprintf(dateString
, sizeof(dateString
), "%lu", expires
);
1920 /* generate the output buffer and write it to file */
1922 outBuffer
.Append(PRUnichar('\t'));
1923 outBuffer
.AppendWithConversion(dateString
);
1924 outBuffer
.Append(PRUnichar('\t'));
1925 outBuffer
.Append(suffix
);
1926 PutCookieLine(outStream
, outBuffer
);
1934 #endif /* NEED_TO_FIX_4X_COOKIES */
1936 /*----------------------------------------------------------------------------
1937 * DoSpecialUpdates updates is a routine that does some miscellaneous updates
1938 * like renaming certain files, etc.
1939 *--------------------------------------------------------------------------*/
1941 nsPrefMigration::DoSpecialUpdates(nsIFileSpec
* profilePath
)
1947 rv
= profilePath
->GetFileSpec(&fs
);
1948 if (NS_FAILED(rv
)) return rv
;
1950 fs
+= PREF_FILE_NAME_IN_5x
;
1952 nsOutputFileStream
fsStream(fs
, (PR_WRONLY
| PR_CREATE_FILE
| PR_APPEND
));
1954 if (!fsStream
.is_open())
1956 return NS_ERROR_FAILURE
;
1959 /* Need to add a string to the top of the prefs.js file to prevent it
1960 * from being loaded as a standard javascript file which would be a
1963 fsStream
<< PREF_FILE_HEADER_STRING
<< nsEndl
;
1966 // rename the cookies file, but only if we need to.
1967 #if defined(NEED_TO_FIX_4X_COOKIES)
1968 rv
= Fix4xCookies(profilePath
);
1969 if (NS_FAILED(rv
)) {
1973 rv
= Rename4xFileAfterMigration(profilePath
,COOKIES_FILE_NAME_IN_4x
,COOKIES_FILE_NAME_IN_5x
);
1974 if (NS_FAILED(rv
)) return rv
;
1975 #endif /* NEED_TO_FIX_4X_COOKIES */
1977 // rename the bookmarks file, but only if we need to.
1978 rv
= Rename4xFileAfterMigration(profilePath
,BOOKMARKS_FILE_NAME_IN_4x
,BOOKMARKS_FILE_NAME_IN_5x
);
1979 if (NS_FAILED(rv
)) return rv
;
1981 /* Create the new mail directory from the setting in prefs.js or a default */
1982 rv
= m_prefBranch
->GetIntPref(PREF_MAIL_SERVER_TYPE
, &serverType
);
1983 if (NS_FAILED(rv
)) return rv
;
1984 if (serverType
== POP_4X_MAIL_TYPE
) {
1985 rv
= RenameAndMove4xPopFilterFile(profilePath
);
1986 if (NS_FAILED(rv
)) return rv
;
1988 rv
= RenameAndMove4xPopStateFile(profilePath
);
1989 if (NS_FAILED(rv
)) return rv
;
1991 #ifdef IMAP_MAIL_FILTER_FILE_NAME_FORMAT_IN_4x
1992 else if (serverType
== IMAP_4X_MAIL_TYPE
) {
1993 rv
= RenameAndMove4xImapFilterFiles(profilePath
);
1994 if (NS_FAILED(rv
)) return rv
;
1996 #endif /* IMAP_MAIL_FILTER_FILE_NAME_FORMAT_IN_4x */
2002 nsPrefMigration::RenameAndMove4xPopFilterFile(nsIFileSpec
* profilePath
)
2004 return RenameAndMove4xPopFile(profilePath
, POP_MAIL_FILTER_FILE_NAME_IN_4x
, POP_MAIL_FILTER_FILE_NAME_IN_5x
);
2008 nsPrefMigration::RenameAndMove4xPopStateFile(nsIFileSpec
* profilePath
)
2010 #ifdef POPSTATE_FILE_IN_4x
2011 return RenameAndMove4xPopFile(profilePath
, POPSTATE_FILE_IN_4x
, POPSTATE_FILE_IN_5x
);
2013 // on windows, popstate.dat was in Users\<profile>\MAIL\popstate.dat
2014 // which is the right place, unlike linux and mac.
2015 // so, when we migrate Users\<profile>\Mail to Users50\<profile>\Mail\<hostname>
2018 #endif /* POPSTATE_FILE_IN_4x */
2022 nsPrefMigration::RenameAndMove4xPopFile(nsIFileSpec
* profilePath
, const char *fileNameIn4x
, const char *fileNameIn5x
)
2025 nsresult rv
= profilePath
->GetFileSpec(&file
);
2026 if (NS_FAILED(rv
)) return rv
;
2028 // we assume the 4.x pop files live at <profile>/<fileNameIn4x>
2029 file
+= fileNameIn4x
;
2031 // figure out where the 4.x pop mail directory got copied to
2032 char *popServerName
= nsnull
;
2033 nsFileSpec migratedPopDirectory
;
2034 rv
= profilePath
->GetFileSpec(&migratedPopDirectory
);
2035 migratedPopDirectory
+= NEW_MAIL_DIR_NAME
;
2036 m_prefBranch
->GetCharPref(PREF_NETWORK_HOSTS_POP_SERVER
, &popServerName
);
2037 migratedPopDirectory
+= popServerName
;
2038 PR_FREEIF(popServerName
);
2040 // copy the 4.x file from <profile>/<fileNameIn4x> to the <profile>/Mail/<hostname>/<fileNameIn4x>
2041 rv
= file
.CopyToDir(migratedPopDirectory
);
2042 NS_ASSERTION(NS_SUCCEEDED(rv
),"failed to copy pop file");
2044 // XXX todo, delete the old file
2045 // we are leaving it behind
2047 // make migratedPopDirectory point the the copied filter file,
2048 // <profile>/Mail/<hostname>/<fileNameIn4x>
2049 migratedPopDirectory
+= fileNameIn4x
;
2051 // rename <profile>/Mail/<hostname>/<fileNameIn4x>to <profile>/Mail/<hostname>/<fileNameIn5x>, if necessary
2052 if (PL_strcmp(fileNameIn4x
,fileNameIn5x
)) {
2053 migratedPopDirectory
.Rename(fileNameIn5x
);
2060 #ifdef IMAP_MAIL_FILTER_FILE_NAME_FORMAT_IN_4x
2061 #define BUFFER_LEN 128
2063 nsPrefMigration::RenameAndMove4xImapFilterFile(nsIFileSpec
* profilePath
, const char *hostname
)
2065 nsresult rv
= NS_OK
;
2066 char imapFilterFileName
[BUFFER_LEN
];
2068 // the 4.x imap filter file lives in "<profile>/<hostname> Rules"
2070 rv
= profilePath
->GetFileSpec(&file
);
2071 if (NS_FAILED(rv
)) return rv
;
2073 PR_snprintf(imapFilterFileName
, BUFFER_LEN
, IMAP_MAIL_FILTER_FILE_NAME_FORMAT_IN_4x
, hostname
);
2074 file
+= imapFilterFileName
;
2076 // if that file didn't exist, because they didn't use filters for that server, return now
2077 if (!file
.Exists()) return NS_OK
;
2079 // figure out where the 4.x pop mail directory got copied to
2080 nsFileSpec migratedImapDirectory
;
2081 rv
= profilePath
->GetFileSpec(&migratedImapDirectory
);
2082 migratedImapDirectory
+= NEW_IMAPMAIL_DIR_NAME
;
2083 migratedImapDirectory
+= hostname
;
2085 // copy the 4.x file from "<profile>/<hostname> Rules" to <profile>/ImapMail/<hostname>/
2086 rv
= file
.CopyToDir(migratedImapDirectory
);
2087 NS_ASSERTION(NS_SUCCEEDED(rv
),"failed to copy imap file");
2089 // make migratedPopDirectory point the the copied filter file,
2090 // "<profile>/ImapMail/<hostname>/<hostname> Rules"
2091 migratedImapDirectory
+= imapFilterFileName
;
2093 // rename "<profile>/ImapMail/<hostname>/<hostname> Rules" to "<profile>/ImapMail/<hostname>/rules.dat"
2094 migratedImapDirectory
.Rename(IMAP_MAIL_FILTER_FILE_NAME_IN_5x
);
2100 nsPrefMigration::RenameAndMove4xImapFilterFiles(nsIFileSpec
* profilePath
)
2103 char *hostList
=nsnull
;
2105 rv
= m_prefBranch
->GetCharPref(PREF_4X_NETWORK_HOSTS_IMAP_SERVER
, &hostList
);
2106 if (NS_FAILED(rv
)) return rv
;
2108 if (!hostList
|| !*hostList
) return NS_OK
;
2110 char *token
= nsnull
;
2111 char *rest
= hostList
;
2114 token
= nsCRT::strtok(rest
, ",", &rest
);
2115 while (token
&& *token
) {
2117 str
.StripWhitespace();
2119 if (!str
.IsEmpty()) {
2120 // str is the hostname
2121 rv
= RenameAndMove4xImapFilterFile(profilePath
,str
.get());
2122 if (NS_FAILED(rv
)) {
2123 // failed to migrate. bail.
2128 token
= nsCRT::strtok(rest
, ",", &rest
);
2130 PR_FREEIF(hostList
);
2133 #endif /* IMAP_MAIL_FILTER_FILE_NAME_FORMAT_IN_4x */
2136 nsPrefMigration::Rename4xFileAfterMigration(nsIFileSpec
* profilePath
, const char *oldFileName
, const char *newFileName
)
2138 nsresult rv
= NS_OK
;
2139 // if they are the same, don't bother to rename the file.
2140 if (PL_strcmp(oldFileName
, newFileName
) == 0) {
2145 rv
= profilePath
->GetFileSpec(&file
);
2146 if (NS_FAILED(rv
)) return rv
;
2148 file
+= oldFileName
;
2150 // make sure it exists before you try to rename it
2151 if (file
.Exists()) {
2152 file
.Rename(newFileName
);
2157 #ifdef NEED_TO_COPY_AND_RENAME_NEWSRC_FILES
2159 nsPrefMigration::GetPremigratedFilePref(const char *pref_name
, nsIFileSpec
**path
)
2163 if (!pref_name
) return NS_ERROR_FAILURE
;
2165 char premigration_pref
[MAX_PREF_LEN
];
2166 PR_snprintf(premigration_pref
,MAX_PREF_LEN
,"%s%s",PREMIGRATION_PREFIX
,pref_name
);
2168 printf("getting %s (into a nsFileSpec)\n", premigration_pref
);
2170 rv
= m_prefBranch
->GetComplexValue((const char *)premigration_pref
,
2171 NS_GET_IID(nsIFileSpec
),
2176 #endif /* NEED_TO_COPY_AND_RENAME_NEWSRC_FILES */
2179 nsPrefMigration::SetPremigratedFilePref(const char *pref_name
, nsIFileSpec
*path
)
2183 if (!pref_name
) return NS_ERROR_FAILURE
;
2185 // save off the old pref, prefixed with "premigration"
2186 // for example, we need the old "mail.directory" pref when
2187 // migrating the copies and folder prefs in nsMsgAccountManager.cpp
2189 // note we do this for all platforms.
2190 char premigration_pref
[MAX_PREF_LEN
];
2191 PR_snprintf(premigration_pref
,MAX_PREF_LEN
,"%s%s",PREMIGRATION_PREFIX
,pref_name
);
2193 printf("setting %s (from a nsFileSpec) for later...\n", premigration_pref
);
2196 // need to convert nsIFileSpec->nsILocalFile
2197 nsFileSpec pathSpec
;
2198 path
->GetFileSpec(&pathSpec
);
2200 nsCOMPtr
<nsILocalFile
> pathFile
;
2201 rv
= NS_FileSpecToIFile(&pathSpec
, getter_AddRefs(pathFile
));
2202 if (NS_FAILED(rv
)) return rv
;
2204 PRBool exists
= PR_FALSE
;
2205 pathFile
->Exists(&exists
);
2207 NS_ASSERTION(exists
, "the path does not exist. see bug #55444");
2208 if (!exists
) return NS_OK
;
2210 rv
= m_prefBranch
->SetComplexValue((const char *)premigration_pref
,
2211 NS_GET_IID(nsILocalFile
), pathFile
);
2216 nsPrefMigration::DetermineOldPath(nsIFileSpec
*profilePath
, const char *oldPathName
, const char *oldPathEntityName
, nsIFileSpec
*oldPath
)
2220 /* set oldLocalFile to profilePath. need to convert nsIFileSpec->nsILocalFile */
2221 nsCOMPtr
<nsILocalFile
> oldLocalFile
;
2222 nsFileSpec pathSpec
;
2223 profilePath
->GetFileSpec(&pathSpec
);
2224 rv
= NS_FileSpecToIFile(&pathSpec
, getter_AddRefs(oldLocalFile
));
2225 if (NS_FAILED(rv
)) return rv
;
2227 /* get the string bundle, and get the appropriate localized string out of it */
2228 nsCOMPtr
<nsIStringBundleService
> bundleService
= do_GetService(NS_STRINGBUNDLE_CONTRACTID
, &rv
);
2229 if (NS_FAILED(rv
)) return rv
;
2231 nsCOMPtr
<nsIStringBundle
> bundle
;
2232 rv
= bundleService
->CreateBundle(MIGRATION_PROPERTIES_URL
, getter_AddRefs(bundle
));
2233 if (NS_FAILED(rv
)) return rv
;
2235 nsXPIDLString localizedDirName
;
2236 nsAutoString entityName
;
2237 entityName
.AssignWithConversion(oldPathEntityName
);
2238 rv
= bundle
->GetStringFromName(entityName
.get(), getter_Copies(localizedDirName
));
2239 if (NS_FAILED(rv
)) return rv
;
2241 rv
= oldLocalFile
->AppendRelativePath(localizedDirName
);
2242 if (NS_FAILED(rv
)) return rv
;
2244 PRBool exists
= PR_FALSE
;
2245 rv
= oldLocalFile
->Exists(&exists
);
2247 /* if the localized name doesn't exist, use the english name */
2248 rv
= oldPath
->FromFileSpec(profilePath
);
2249 if (NS_FAILED(rv
)) return rv
;
2251 rv
= oldPath
->AppendRelativeUnixPath(oldPathName
);
2252 if (NS_FAILED(rv
)) return rv
;
2257 /* at this point, the folder with the localized name exists, so use it */
2258 nsCAutoString persistentDescriptor
;
2259 rv
= oldLocalFile
->GetPersistentDescriptor(persistentDescriptor
);
2260 if (NS_FAILED(rv
)) return rv
;
2261 rv
= oldPath
->SetPersistentDescriptorString(persistentDescriptor
.get());
2262 if (NS_FAILED(rv
)) return rv
;
2267 ////////////////////////////////////////////////////////////////////////
2269 ////////////////////////////////////////////////////////////////////////
2272 these are the prefs we know we need to convert to utf8.
2273 we'll also be converting:
2275 Please make sure that any pref that contains native characters
2276 in its value is not included in this list as we do not want to
2277 convert them into UTF-8 format. Prefs are being get and set in a
2278 unicode format (FileXPref) now and there is no need for
2279 conversion of those prefs.
2281 "ldap_2.server.*.description"
2282 "intl.font*.fixed_font"
2283 "intl.font*.prop_font"
2284 "mail.identity.vcard.*"
2287 static const char *prefsToConvert
[] = {
2288 "custtoolbar.personal_toolbar_folder",
2290 "li.server.ldap.userbase",
2291 "mail.identity.organization",
2292 "mail.identity.username",
2296 nsPrefConverter::~nsPrefConverter()
2301 nsPrefConverter::nsPrefConverter()
2305 NS_IMPL_ISUPPORTS1(nsPrefConverter
, nsIPrefConverter
)
2307 // Apply a charset conversion from the given charset to UTF-8 for the input C string.
2310 ConvertStringToUTF8(const char* aCharset
, const char* inString
, char** outString
)
2312 if (nsnull
== outString
)
2313 return NS_ERROR_NULL_POINTER
;
2316 // convert result to unicode
2317 nsCOMPtr
<nsICharsetConverterManager
> ccm
=
2318 do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID
, &rv
);
2320 if(NS_SUCCEEDED(rv
)) {
2321 nsCOMPtr
<nsIUnicodeDecoder
> decoder
; // this may be cached
2323 rv
= ccm
->GetUnicodeDecoderRaw(aCharset
, getter_AddRefs(decoder
));
2324 if(NS_SUCCEEDED(rv
) && decoder
) {
2325 PRInt32 uniLength
= 0;
2326 PRInt32 srcLength
= strlen(inString
);
2327 rv
= decoder
->GetMaxLength(inString
, srcLength
, &uniLength
);
2328 if (NS_SUCCEEDED(rv
)) {
2329 PRUnichar
*unichars
= new PRUnichar
[uniLength
];
2331 if (nsnull
!= unichars
) {
2332 // convert to unicode
2333 rv
= decoder
->Convert(inString
, &srcLength
, unichars
, &uniLength
);
2334 if (NS_SUCCEEDED(rv
)) {
2335 nsAutoString aString
;
2336 aString
.Assign(unichars
, uniLength
);
2338 *outString
= ToNewUTF8String(aString
);
2343 rv
= NS_ERROR_OUT_OF_MEMORY
;
2353 ConvertPrefToUTF8(const char *prefname
, nsIPrefBranch
*prefs
, const char* charSet
)
2357 if (!prefname
|| !prefs
) return NS_ERROR_FAILURE
;
2358 #ifdef DEBUG_UTF8_CONVERSION
2359 printf("converting %s to UTF8\n", prefname
);
2360 #endif /* DEBUG_UTF8_CONVERSION */
2362 nsXPIDLCString prefval
;
2364 rv
= prefs
->GetCharPref(prefname
, getter_Copies(prefval
));
2365 if (NS_FAILED(rv
)) return rv
;
2367 if (prefval
.IsEmpty()) {
2368 // no need to convert ""
2372 nsXPIDLCString outval
;
2373 rv
= ConvertStringToUTF8(charSet
, (const char *)prefval
, getter_Copies(outval
));
2374 // only set the pref if the conversion worked, and it convert to something non null
2375 if (NS_SUCCEEDED(rv
) && (const char *)outval
&& PL_strlen((const char *)outval
)) {
2376 #ifdef DEBUG_UTF8_CONVERSION
2377 printf("converting %s to %s\n",(const char *)prefval
, (const char *)outval
);
2378 #endif /* DEBUG_UTF8_CONVERSION */
2379 rv
= prefs
->SetCharPref(prefname
, (const char *)outval
);
2386 static PRBool
charEndsWith(const char *str
, const char *endStr
)
2388 PRUint32 endStrLen
= PL_strlen(endStr
);
2389 PRUint32 strLen
= PL_strlen(str
);
2391 if (strLen
< endStrLen
) return PR_FALSE
;
2393 PRUint32 pos
= strLen
- endStrLen
;
2394 if (PL_strncmp(str
+ pos
, endStr
, endStrLen
) == 0) {
2403 void fontPrefEnumerationFunction(const char *name
, nsCStringArray
*arr
)
2405 #ifdef DEBUG_UTF8_CONVERSION
2406 printf("fontPrefEnumerationFunction: %s\n", name
);
2409 if (charEndsWith(name
,".fixed_font") || charEndsWith(name
,".prop_font")) {
2410 nsCString
str(name
);
2411 arr
->AppendCString(str
);
2416 void ldapPrefEnumerationFunction(const char *name
, nsCStringArray
*arr
)
2418 #ifdef DEBUG_UTF8_CONVERSION
2419 printf("ldapPrefEnumerationFunction: %s\n", name
);
2422 // we only want to convert "ldap_2.servers.*.description"
2423 if (charEndsWith(name
,".description")) {
2424 nsCString
str(name
);
2425 arr
->AppendCString(str
);
2430 void vCardPrefEnumerationFunction(const char *name
, nsCStringArray
*arr
)
2432 #ifdef DEBUG_UTF8_CONVERSION
2433 printf("vCardPrefEnumerationFunction: %s\n", name
);
2436 // the 4.x vCard prefs might need converting
2437 nsCString
str(name
);
2438 arr
->AppendCString(str
);
2443 nsIPrefBranch
*prefs
;
2444 const char* charSet
;
2445 } PrefEnumerationClosure
;
2448 convertPref(nsCString
&aElement
, void *aData
)
2450 PrefEnumerationClosure
*closure
;
2451 closure
= (PrefEnumerationClosure
*)aData
;
2453 ConvertPrefToUTF8(aElement
.get(), closure
->prefs
, closure
->charSet
);
2458 nsPrefConverter::ConvertPrefsToUTF8()
2462 nsCStringArray prefsToMigrate
;
2464 nsCOMPtr
<nsIPrefBranch
> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
));
2465 if(NS_FAILED(rv
)) return rv
;
2466 if (!prefs
) return NS_ERROR_FAILURE
;
2468 nsCAutoString charSet
;
2469 rv
= GetPlatformCharset(charSet
);
2471 if (NS_FAILED(rv
)) return rv
;
2475 for (i
= 0; prefsToConvert
[i
]; i
++) {
2476 nsCString
prefnameStr( prefsToConvert
[i
] );
2477 prefsToMigrate
.AppendCString(prefnameStr
);
2483 if (NS_SUCCEEDED(prefs
->GetChildList("intl.font.", &count
, &childArray
))) {
2484 for (i
= 0; i
< count
; i
++)
2485 fontPrefEnumerationFunction(childArray
[i
], &prefsToMigrate
);
2487 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count
, childArray
);
2490 if (NS_SUCCEEDED(prefs
->GetChildList("ldap_2.servers.", &count
, &childArray
))) {
2491 for (i
= 0; i
< count
; i
++)
2492 ldapPrefEnumerationFunction(childArray
[i
], &prefsToMigrate
);
2494 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count
, childArray
);
2497 if (NS_SUCCEEDED(prefs
->GetChildList("mail.identity.vcard.", &count
, &childArray
))) {
2498 for (i
= 0; i
< count
; i
++)
2499 vCardPrefEnumerationFunction(childArray
[i
], &prefsToMigrate
);
2501 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count
, childArray
);
2504 PrefEnumerationClosure closure
;
2506 closure
.prefs
= prefs
;
2507 closure
.charSet
= charSet
.get();
2509 prefsToMigrate
.EnumerateForwards((nsCStringArrayEnumFunc
)convertPref
, (void *)(&closure
));
2511 rv
= prefs
->SetBoolPref("prefs.converted-to-utf8", PR_TRUE
);
2515 // A wrapper function to call the interface to get a platform file charset.
2517 nsPrefConverter::GetPlatformCharset(nsCString
& aCharset
)
2521 // we may cache it since the platform charset will not change through application life
2522 nsCOMPtr
<nsIPlatformCharset
> platformCharset
= do_GetService(NS_PLATFORMCHARSET_CONTRACTID
, &rv
);
2523 if (NS_SUCCEEDED(rv
) && platformCharset
) {
2524 rv
= platformCharset
->GetCharset(kPlatformCharsetSel_4xPrefsJS
, aCharset
);
2526 if (NS_FAILED(rv
)) {
2527 aCharset
.AssignLiteral("ISO-8859-1"); // use ISO-8859-1 in case of any error