1 /* vim: set ts=2 et sw=2 tw=80: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "nsString.h"
7 #include "nsCOMPtr.h"
8 #include "nsIFile.h"
9 #include "nsIInputStream.h"
10 #include "nsIOutputStream.h"
11 #include "nsILineInputStream.h"
12 #include "nsNetUtil.h"
13 #include "nsIImportService.h"
14 #include "nsIImportMailboxDescriptor.h"
15 #include "nsIMsgHdr.h"
16 #include "nsIMsgFolder.h"
17 #include "nsIMsgPluggableStore.h"
18 #include "nsMsgUtils.h"
19 #include "nsMsgLocalFolderHdrs.h"
20 #include "nsMsgMessageFlags.h"
21 #include "nsTArray.h"
22 #include "nspr.h"
23 #include "nsThreadUtils.h"
24 #include "nsIDirectoryEnumerator.h"
25
26 #include "nsBeckyMail.h"
27 #include "nsBeckyUtils.h"
28 #include "nsBeckyStringBundle.h"
29
30 #define FROM_LINE "From - Mon Jan 1 00:00:00 1965" MSG_LINEBREAK
31 #define X_BECKY_STATUS_HEADER "X-Becky-Status"
32 #define X_BECKY_INCLUDE_HEADER "X-Becky-Include"
33
34 enum {
35 BECKY_STATUS_READ = 1 << 0,
36 BECKY_STATUS_FORWARDED = 1 << 1,
37 BECKY_STATUS_REPLIED = 1 << 2
38 };
39
NS_IMPL_ISUPPORTS(nsBeckyMail,nsIImportMail)40 NS_IMPL_ISUPPORTS(nsBeckyMail, nsIImportMail)
41
42 nsresult nsBeckyMail::Create(nsIImportMail** aImport) {
43 NS_ENSURE_ARG_POINTER(aImport);
44 NS_ADDREF(*aImport = new nsBeckyMail());
45 return NS_OK;
46 }
47
nsBeckyMail()48 nsBeckyMail::nsBeckyMail() : mReadBytes(0) {}
49
~nsBeckyMail()50 nsBeckyMail::~nsBeckyMail() {}
51
52 NS_IMETHODIMP
GetDefaultLocation(nsIFile ** aLocation,bool * aFound,bool * aUserVerify)53 nsBeckyMail::GetDefaultLocation(nsIFile** aLocation, bool* aFound,
54 bool* aUserVerify) {
55 NS_ENSURE_ARG_POINTER(aFound);
56 NS_ENSURE_ARG_POINTER(aLocation);
57 NS_ENSURE_ARG_POINTER(aUserVerify);
58
59 *aLocation = nullptr;
60 *aUserVerify = true;
61 *aFound = false;
62 if (NS_SUCCEEDED(nsBeckyUtils::GetDefaultMailboxDirectory(aLocation)))
63 *aFound = true;
64
65 return NS_OK;
66 }
67
CreateMailboxDescriptor(nsIImportMailboxDescriptor ** aDescriptor)68 nsresult nsBeckyMail::CreateMailboxDescriptor(
69 nsIImportMailboxDescriptor** aDescriptor) {
70 nsresult rv;
71 nsCOMPtr<nsIImportService> importService;
72 importService = do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv);
73 NS_ENSURE_SUCCESS(rv, rv);
74
75 return importService->CreateNewMailboxDescriptor(aDescriptor);
76 }
77
GetMailboxName(nsIFile * aMailbox,nsAString & aName)78 nsresult nsBeckyMail::GetMailboxName(nsIFile* aMailbox, nsAString& aName) {
79 nsCOMPtr<nsIFile> iniFile;
80 nsBeckyUtils::GetMailboxINIFile(aMailbox, getter_AddRefs(iniFile));
81 if (iniFile) {
82 nsCOMPtr<nsIFile> convertedFile;
83 nsBeckyUtils::ConvertToUTF8File(iniFile, getter_AddRefs(convertedFile));
84 if (convertedFile) {
85 nsAutoCString utf8Name;
86 nsBeckyUtils::GetMailboxNameFromINIFile(convertedFile, utf8Name);
87 convertedFile->Remove(false);
88 CopyUTF8toUTF16(utf8Name, aName);
89 }
90 }
91
92 if (aName.IsEmpty()) {
93 nsAutoString name;
94 aMailbox->GetLeafName(name);
95 name.Trim("!", true, false);
96 aName.Assign(name);
97 }
98
99 return NS_OK;
100 }
101
AppendMailboxDescriptor(nsIFile * aEntry,const nsString & aName,uint32_t aDepth,nsTArray<RefPtr<nsIImportMailboxDescriptor>> & aCollected)102 nsresult nsBeckyMail::AppendMailboxDescriptor(
103 nsIFile* aEntry, const nsString& aName, uint32_t aDepth,
104 nsTArray<RefPtr<nsIImportMailboxDescriptor>>& aCollected) {
105 nsresult rv;
106 nsCOMPtr<nsIImportMailboxDescriptor> descriptor;
107 rv = CreateMailboxDescriptor(getter_AddRefs(descriptor));
108 NS_ENSURE_SUCCESS(rv, rv);
109
110 int64_t size;
111 rv = aEntry->GetFileSize(&size);
112 NS_ENSURE_SUCCESS(rv, rv);
113
114 rv = descriptor->SetSize(size);
115 NS_ENSURE_SUCCESS(rv, rv);
116
117 rv = descriptor->SetDisplayName(aName.get());
118 NS_ENSURE_SUCCESS(rv, rv);
119
120 nsCOMPtr<nsIFile> mailboxFile;
121 rv = descriptor->GetFile(getter_AddRefs(mailboxFile));
122 NS_ENSURE_SUCCESS(rv, rv);
123
124 descriptor->SetDepth(aDepth);
125
126 mailboxFile->InitWithFile(aEntry);
127 aCollected.AppendElement(descriptor);
128
129 return NS_OK;
130 }
131
CollectMailboxesInFolderListFile(nsIFile * aListFile,uint32_t aDepth,nsTArray<RefPtr<nsIImportMailboxDescriptor>> & aCollected)132 nsresult nsBeckyMail::CollectMailboxesInFolderListFile(
133 nsIFile* aListFile, uint32_t aDepth,
134 nsTArray<RefPtr<nsIImportMailboxDescriptor>>& aCollected) {
135 nsresult rv;
136 nsCOMPtr<nsILineInputStream> lineStream;
137 rv = nsBeckyUtils::CreateLineInputStream(aListFile,
138 getter_AddRefs(lineStream));
139 NS_ENSURE_SUCCESS(rv, rv);
140
141 nsCOMPtr<nsIFile> parent;
142 rv = aListFile->GetParent(getter_AddRefs(parent));
143 NS_ENSURE_SUCCESS(rv, rv);
144
145 bool more = true;
146 nsAutoCString folderName;
147 bool isEmpty = true;
148 while (more && NS_SUCCEEDED(rv)) {
149 rv = lineStream->ReadLine(folderName, &more);
150 NS_ENSURE_SUCCESS(rv, rv);
151
152 if (folderName.IsEmpty()) continue;
153
154 nsCOMPtr<nsIFile> folder;
155 rv = parent->Clone(getter_AddRefs(folder));
156 NS_ENSURE_SUCCESS(rv, rv);
157
158 rv = folder->AppendNative(folderName);
159 NS_ENSURE_SUCCESS(rv, rv);
160
161 isEmpty = false;
162 rv = CollectMailboxesInDirectory(folder, aDepth + 1, aCollected);
163 }
164
165 return isEmpty ? NS_ERROR_FILE_NOT_FOUND : NS_OK;
166 }
167
CollectMailboxesInDirectory(nsIFile * aDirectory,uint32_t aDepth,nsTArray<RefPtr<nsIImportMailboxDescriptor>> & aCollected)168 nsresult nsBeckyMail::CollectMailboxesInDirectory(
169 nsIFile* aDirectory, uint32_t aDepth,
170 nsTArray<RefPtr<nsIImportMailboxDescriptor>>& aCollected) {
171 nsAutoString mailboxName;
172 nsresult rv = GetMailboxName(aDirectory, mailboxName);
173 NS_ENSURE_SUCCESS(rv, rv);
174
175 if (aDepth != 0)
176 AppendMailboxDescriptor(aDirectory, mailboxName, aDepth, aCollected);
177
178 nsCOMPtr<nsIFile> folderListFile;
179 rv = nsBeckyUtils::GetFolderListFile(aDirectory,
180 getter_AddRefs(folderListFile));
181 bool folderListExists = false;
182
183 if (NS_SUCCEEDED(rv)) {
184 rv = CollectMailboxesInFolderListFile(folderListFile, aDepth, aCollected);
185 folderListExists = true;
186 }
187
188 nsCOMPtr<nsIDirectoryEnumerator> entries;
189 rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
190 NS_ENSURE_SUCCESS(rv, rv);
191
192 bool more;
193 while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
194 nsCOMPtr<nsIFile> file;
195 rv = entries->GetNextFile(getter_AddRefs(file));
196 NS_ENSURE_SUCCESS(rv, rv);
197
198 nsAutoString name;
199 rv = file->GetLeafName(name);
200 NS_ENSURE_SUCCESS(rv, rv);
201
202 if (StringEndsWith(name, u".bmf"_ns)) {
203 AppendMailboxDescriptor(file, mailboxName, aDepth, aCollected);
204 }
205
206 // The Folder.lst file is not created if there is only one sub folder,
207 // so we need to find the sub folder by our hands.
208 // The folder name does not begin with # or ! maybe. Yes, maybe...
209 if (!folderListExists) {
210 if (StringBeginsWith(name, u"#"_ns) || StringBeginsWith(name, u"!"_ns))
211 continue;
212
213 bool isDirectory = false;
214 rv = file->IsDirectory(&isDirectory);
215 if (isDirectory) {
216 CollectMailboxesInDirectory(file, aDepth + 1, aCollected);
217 continue;
218 }
219 }
220 }
221
222 return NS_OK;
223 }
224
225 NS_IMETHODIMP
FindMailboxes(nsIFile * aLocation,nsTArray<RefPtr<nsIImportMailboxDescriptor>> & boxes)226 nsBeckyMail::FindMailboxes(
227 nsIFile* aLocation, nsTArray<RefPtr<nsIImportMailboxDescriptor>>& boxes) {
228 NS_ENSURE_ARG_POINTER(aLocation);
229
230 boxes.Clear();
231 nsresult rv = CollectMailboxesInDirectory(aLocation, 0, boxes);
232 NS_ENSURE_SUCCESS(rv, rv);
233 return NS_OK;
234 }
235
GetBeckyStatusValue(const nsCString & aHeader,nsACString & aValue)236 static nsresult GetBeckyStatusValue(const nsCString& aHeader,
237 nsACString& aValue) {
238 int32_t valueStartPosition;
239
240 valueStartPosition = aHeader.FindChar(':');
241 if (valueStartPosition < 0) return NS_ERROR_UNEXPECTED;
242
243 valueStartPosition++;
244
245 int32_t commaPosition = aHeader.FindChar(',', valueStartPosition);
246 if (commaPosition < 0) return NS_ERROR_UNEXPECTED;
247
248 nsAutoCString value(Substring(aHeader, valueStartPosition,
249 commaPosition - valueStartPosition));
250 value.Trim(" \t");
251
252 aValue.Assign(value);
253
254 return NS_OK;
255 }
256
GetBeckyIncludeValue(const nsCString & aHeader,nsACString & aValue)257 static nsresult GetBeckyIncludeValue(const nsCString& aHeader,
258 nsACString& aValue) {
259 int32_t valueStartPosition;
260
261 valueStartPosition = aHeader.FindChar(':');
262 if (valueStartPosition < 0) return NS_ERROR_FAILURE;
263
264 valueStartPosition++;
265 nsAutoCString value(Substring(aHeader, valueStartPosition));
266 value.Trim(" \t");
267
268 aValue.Assign(value);
269
270 return NS_OK;
271 }
272
ConvertBeckyStatusToMozillaStatus(const nsCString & aHeader,nsMsgMessageFlagType * aMozillaStatusFlag)273 static bool ConvertBeckyStatusToMozillaStatus(
274 const nsCString& aHeader, nsMsgMessageFlagType* aMozillaStatusFlag) {
275 nsresult rv;
276 nsAutoCString statusString;
277 rv = GetBeckyStatusValue(aHeader, statusString);
278 NS_ENSURE_SUCCESS(rv, false);
279
280 nsresult errorCode;
281 uint32_t beckyStatusFlag =
282 static_cast<uint32_t>(statusString.ToInteger(&errorCode, 16));
283 if (NS_FAILED(errorCode)) return false;
284
285 if (beckyStatusFlag & BECKY_STATUS_READ)
286 *aMozillaStatusFlag |= nsMsgMessageFlags::Read;
287 if (beckyStatusFlag & BECKY_STATUS_FORWARDED)
288 *aMozillaStatusFlag |= nsMsgMessageFlags::Forwarded;
289 if (beckyStatusFlag & BECKY_STATUS_REPLIED)
290 *aMozillaStatusFlag |= nsMsgMessageFlags::Replied;
291
292 return true;
293 }
294
CheckHeaderKey(const nsCString & aHeader,const char * aKeyString)295 static inline bool CheckHeaderKey(const nsCString& aHeader,
296 const char* aKeyString) {
297 nsAutoCString key(StringHead(aHeader, aHeader.FindChar(':')));
298 key.Trim(" \t");
299 return key.Equals(aKeyString);
300 }
301
IsBeckyStatusHeader(const nsCString & aHeader)302 static inline bool IsBeckyStatusHeader(const nsCString& aHeader) {
303 return CheckHeaderKey(aHeader, X_BECKY_STATUS_HEADER);
304 }
305
IsBeckyIncludeLine(const nsCString & aLine)306 static inline bool IsBeckyIncludeLine(const nsCString& aLine) {
307 return CheckHeaderKey(aLine, X_BECKY_INCLUDE_HEADER);
308 }
309
IsEndOfHeaders(const nsCString & aLine)310 static inline bool IsEndOfHeaders(const nsCString& aLine) {
311 return aLine.IsEmpty();
312 }
313
IsEndOfMessage(const nsCString & aLine)314 static inline bool IsEndOfMessage(const nsCString& aLine) {
315 return aLine.EqualsLiteral(".");
316 }
317
318 class ImportMessageRunnable : public mozilla::Runnable {
319 public:
320 ImportMessageRunnable(nsIFile* aMessageFile, nsIMsgFolder* aFolder);
321 NS_DECL_NSIRUNNABLE
322 nsresult mResult;
323
324 private:
325 nsresult WriteHeaders(nsCString& aHeaders, nsIOutputStream* aOutputStream);
326 nsresult HandleHeaderLine(const nsCString& aHeaderLine, nsACString& aHeaders);
327 nsresult GetAttachmentFile(nsIFile* aMailboxFile, const nsCString& aHeader,
328 nsIFile** _retval);
329 nsresult WriteAttachmentFile(nsIFile* aMailboxFile, const nsCString& aHeader,
330 nsIOutputStream* aOutputStream);
331
332 nsCOMPtr<nsIFile> mMessageFile;
333 nsCOMPtr<nsIMsgFolder> mFolder;
334 };
335
ImportMessageRunnable(nsIFile * aMessageFile,nsIMsgFolder * aFolder)336 ImportMessageRunnable::ImportMessageRunnable(nsIFile* aMessageFile,
337 nsIMsgFolder* aFolder)
338 : mozilla::Runnable("ImportMessageRunnable"),
339 mMessageFile(aMessageFile),
340 mFolder(aFolder) {}
341
WriteHeaders(nsCString & aHeaders,nsIOutputStream * aOutputStream)342 nsresult ImportMessageRunnable::WriteHeaders(nsCString& aHeaders,
343 nsIOutputStream* aOutputStream) {
344 nsresult rv;
345 uint32_t writtenBytes = 0;
346
347 rv = aOutputStream->Write(FROM_LINE, strlen(FROM_LINE), &writtenBytes);
348 NS_ENSURE_SUCCESS(rv, rv);
349 rv = aOutputStream->Write(aHeaders.get(), aHeaders.Length(), &writtenBytes);
350 NS_ENSURE_SUCCESS(rv, rv);
351 rv =
352 aOutputStream->Write(MSG_LINEBREAK, strlen(MSG_LINEBREAK), &writtenBytes);
353 NS_ENSURE_SUCCESS(rv, rv);
354 aHeaders.Truncate();
355
356 return NS_OK;
357 }
358
HandleHeaderLine(const nsCString & aHeaderLine,nsACString & aHeaders)359 nsresult ImportMessageRunnable::HandleHeaderLine(const nsCString& aHeaderLine,
360 nsACString& aHeaders) {
361 aHeaders.Append(aHeaderLine);
362 aHeaders.AppendLiteral(MSG_LINEBREAK);
363
364 nsMsgMessageFlagType flag = 0;
365 if (IsBeckyStatusHeader(aHeaderLine) &&
366 ConvertBeckyStatusToMozillaStatus(aHeaderLine, &flag)) {
367 char* statusLine;
368 statusLine = PR_smprintf(X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, flag);
369 aHeaders.Append(statusLine);
370 PR_smprintf_free(statusLine);
371 aHeaders.AppendLiteral(X_MOZILLA_KEYWORDS);
372 }
373
374 return NS_OK;
375 }
376
GetAttachmentFile(nsIFile * aMailboxFile,const nsCString & aHeader,nsIFile ** _retval)377 nsresult ImportMessageRunnable::GetAttachmentFile(nsIFile* aMailboxFile,
378 const nsCString& aHeader,
379 nsIFile** _retval) {
380 nsresult rv;
381 nsCOMPtr<nsIFile> attachmentFile;
382
383 rv = aMailboxFile->Clone(getter_AddRefs(attachmentFile));
384 NS_ENSURE_SUCCESS(rv, rv);
385
386 rv = attachmentFile->Append(u"#Attach"_ns);
387 NS_ENSURE_SUCCESS(rv, rv);
388
389 nsAutoCString nativeAttachmentPath;
390 rv = GetBeckyIncludeValue(aHeader, nativeAttachmentPath);
391 NS_ENSURE_SUCCESS(rv, rv);
392
393 rv = attachmentFile->AppendRelativeNativePath(nativeAttachmentPath);
394 NS_ENSURE_SUCCESS(rv, rv);
395
396 bool exists = false;
397 attachmentFile->Exists(&exists);
398 if (!exists) return NS_ERROR_FILE_NOT_FOUND;
399
400 attachmentFile.forget(_retval);
401 return NS_OK;
402 }
403
WriteAttachmentFile(nsIFile * aMailboxFile,const nsCString & aHeader,nsIOutputStream * aOutputStream)404 nsresult ImportMessageRunnable::WriteAttachmentFile(
405 nsIFile* aMailboxFile, const nsCString& aHeader,
406 nsIOutputStream* aOutputStream) {
407 nsresult rv;
408 nsCOMPtr<nsIFile> parentDirectory;
409 rv = aMailboxFile->GetParent(getter_AddRefs(parentDirectory));
410 NS_ENSURE_SUCCESS(rv, rv);
411
412 nsCOMPtr<nsIFile> attachmentFile;
413 rv = GetAttachmentFile(parentDirectory, aHeader,
414 getter_AddRefs(attachmentFile));
415 NS_ENSURE_SUCCESS(rv, rv);
416
417 nsCOMPtr<nsIInputStream> inputStream;
418 rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), attachmentFile);
419 NS_ENSURE_SUCCESS(rv, rv);
420
421 char buffer[FILE_IO_BUFFER_SIZE];
422 uint32_t readBytes = 0;
423 uint32_t writtenBytes = 0;
424 rv =
425 aOutputStream->Write(MSG_LINEBREAK, strlen(MSG_LINEBREAK), &writtenBytes);
426 while (NS_SUCCEEDED(inputStream->Read(buffer, sizeof(buffer), &readBytes)) &&
427 readBytes > 0) {
428 rv = aOutputStream->Write(buffer, readBytes, &writtenBytes);
429 if (NS_FAILED(rv)) break;
430 }
431
432 return rv;
433 }
434
Run()435 NS_IMETHODIMP ImportMessageRunnable::Run() {
436 nsCOMPtr<nsIMsgPluggableStore> msgStore;
437 mResult = mFolder->GetMsgStore(getter_AddRefs(msgStore));
438 NS_ENSURE_SUCCESS(mResult, NS_OK);
439
440 nsCOMPtr<nsILineInputStream> lineStream;
441 mResult = nsBeckyUtils::CreateLineInputStream(mMessageFile,
442 getter_AddRefs(lineStream));
443 NS_ENSURE_SUCCESS(mResult, NS_OK);
444
445 bool reusable;
446 nsCOMPtr<nsIMsgDBHdr> msgHdr;
447 nsCOMPtr<nsIOutputStream> outputStream;
448 mResult = msgStore->GetNewMsgOutputStream(
449 mFolder, getter_AddRefs(msgHdr), &reusable, getter_AddRefs(outputStream));
450 NS_ENSURE_SUCCESS(mResult, NS_OK);
451
452 bool inHeader = true;
453 bool more = true;
454 nsAutoCString headers;
455 while (NS_SUCCEEDED(mResult) && more) {
456 nsAutoCString line;
457 mResult = lineStream->ReadLine(line, &more);
458 if (NS_FAILED(mResult)) break;
459
460 if (inHeader) {
461 if (IsEndOfHeaders(line)) {
462 inHeader = false;
463 mResult = WriteHeaders(headers, outputStream);
464 } else {
465 mResult = HandleHeaderLine(line, headers);
466 }
467 } else if (IsEndOfMessage(line)) {
468 inHeader = true;
469 mResult = msgStore->FinishNewMessage(outputStream, msgHdr);
470 if (!reusable) outputStream->Close();
471 mResult = msgStore->GetNewMsgOutputStream(mFolder, getter_AddRefs(msgHdr),
472 &reusable,
473 getter_AddRefs(outputStream));
474 } else if (IsBeckyIncludeLine(line)) {
475 mResult = WriteAttachmentFile(mMessageFile, line, outputStream);
476 } else {
477 uint32_t writtenBytes = 0;
478 if (StringBeginsWith(line, ".."_ns))
479 line.Cut(0, 1);
480 else if (CheckHeaderKey(line, "From"))
481 line.Insert('>', 0);
482
483 line.AppendLiteral(MSG_LINEBREAK);
484 mResult = outputStream->Write(line.get(), line.Length(), &writtenBytes);
485 }
486 }
487
488 if (outputStream) {
489 if (NS_FAILED(mResult)) msgStore->DiscardNewMessage(outputStream, msgHdr);
490 outputStream->Close();
491 }
492
493 return NS_OK;
494 }
495
ProxyImportMessage(nsIFile * aMessageFile,nsIMsgFolder * aFolder)496 static nsresult ProxyImportMessage(nsIFile* aMessageFile,
497 nsIMsgFolder* aFolder) {
498 RefPtr<ImportMessageRunnable> importMessage =
499 new ImportMessageRunnable(aMessageFile, aFolder);
500 nsresult rv = NS_DispatchToMainThread(importMessage, NS_DISPATCH_SYNC);
501 NS_ENSURE_SUCCESS(rv, rv);
502 return importMessage->mResult;
503 }
504
ImportMailFile(nsIFile * aMailFile,nsIMsgFolder * aDestination)505 nsresult nsBeckyMail::ImportMailFile(nsIFile* aMailFile,
506 nsIMsgFolder* aDestination) {
507 int64_t size;
508 aMailFile->GetFileSize(&size);
509 if (size == 0) return NS_OK;
510
511 return ProxyImportMessage(aMailFile, aDestination);
512 }
513
514 NS_IMETHODIMP
ImportMailbox(nsIImportMailboxDescriptor * aSource,nsIMsgFolder * aDestination,char16_t ** aErrorLog,char16_t ** aSuccessLog,bool * aFatalError)515 nsBeckyMail::ImportMailbox(nsIImportMailboxDescriptor* aSource,
516 nsIMsgFolder* aDestination, char16_t** aErrorLog,
517 char16_t** aSuccessLog, bool* aFatalError) {
518 NS_ENSURE_ARG_POINTER(aSource);
519 NS_ENSURE_ARG_POINTER(aDestination);
520 NS_ENSURE_ARG_POINTER(aErrorLog);
521 NS_ENSURE_ARG_POINTER(aSuccessLog);
522 NS_ENSURE_ARG_POINTER(aFatalError);
523
524 mReadBytes = 0;
525
526 nsresult rv;
527 nsCOMPtr<nsIFile> mailboxFolder;
528 rv = aSource->GetFile(getter_AddRefs(mailboxFolder));
529 NS_ENSURE_SUCCESS(rv, rv);
530
531 rv = ImportMailFile(mailboxFolder, aDestination);
532 NS_ENSURE_SUCCESS(rv, rv);
533
534 uint32_t finalSize;
535 aSource->GetSize(&finalSize);
536 mReadBytes = finalSize;
537
538 nsAutoString name;
539 aSource->GetDisplayName(getter_Copies(name));
540
541 nsAutoString successMessage;
542 AutoTArray<nsString, 1> format = {name};
543 rv = nsBeckyStringBundle::FormatStringFromName("BeckyImportMailboxSuccess",
544 format, successMessage);
545 successMessage.AppendLiteral("\n");
546 *aSuccessLog = ToNewUnicode(successMessage);
547
548 return rv;
549 }
550
551 NS_IMETHODIMP
GetImportProgress(uint32_t * _retval)552 nsBeckyMail::GetImportProgress(uint32_t* _retval) {
553 NS_ENSURE_ARG_POINTER(_retval);
554 *_retval = mReadBytes;
555 return NS_OK;
556 }
557
558 NS_IMETHODIMP
TranslateFolderName(const nsAString & aFolderName,nsAString & _retval)559 nsBeckyMail::TranslateFolderName(const nsAString& aFolderName,
560 nsAString& _retval) {
561 return nsBeckyUtils::TranslateFolderName(aFolderName, _retval);
562 }
563