Back to index

lightning-sunbird  0.9+nobinonly
nsEudoraMac.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org Code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Pierre Phaneuf <pp@ludusdesign.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsCOMPtr.h"
00041 #include "nsIComponentManager.h"
00042 #include "nsIServiceManager.h"
00043 #include "nsIMsgAccountManager.h"
00044 #include "nsIMsgAccount.h"
00045 #include "nsMsgBaseCID.h"
00046 #include "nsMsgCompCID.h"
00047 #include "nsISmtpService.h"
00048 #include "nsISmtpServer.h"
00049 #include "nsEudoraMac.h"
00050 #include "nsIImportService.h"
00051 #include "nsIImportMailboxDescriptor.h"
00052 #include "nsIImportABDescriptor.h"
00053 #include "nsSpecialSystemDirectory.h"
00054 #include "nsEudoraStringBundle.h"
00055 #include "nsEudoraImport.h"
00056 #include "nsIPop3IncomingServer.h"
00057 #include "nsReadableUtils.h"
00058 #include "nsUnicharUtils.h"
00059 
00060 #include "EudoraDebugLog.h"
00061 
00062 #include <Resources.h>
00063 #include <Files.h>
00064 #include <TextUtils.h>
00065 
00066 #ifdef XP_MACOSX
00067 #include "nsILocalFileMac.h"
00068 #include "MoreFilesX.h"
00069 
00070 static nsresult NS_FileSpecToILocalFileMac(nsFileSpec *aSpec, nsILocalFileMac **aLocalFileMac)
00071 {
00072   nsCOMPtr<nsILocalFile> localFile;
00073   nsresult rv = NS_FileSpecToIFile(aSpec, getter_AddRefs(localFile));
00074   NS_ENSURE_SUCCESS(rv,rv);
00075 
00076   nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(localFile);
00077   if (!macFile)
00078     return NS_ERROR_FAILURE;
00079    
00080   NS_IF_ADDREF(*aLocalFileMac = macFile);
00081   return NS_OK;
00082 }
00083 #else
00084 #include "MoreFiles.h"
00085 #include "MoreFilesExtras.h"
00086 #endif
00087 
00088 static NS_DEFINE_IID(kISupportsIID,                     NS_ISUPPORTS_IID);
00089 
00090 static const char *  kWhitespace = "\b\t\r\n ";
00091 
00092 nsEudoraMac::nsEudoraMac()
00093 {
00094        m_mailImportLocation = nsnull;
00095 }
00096 
00097 nsEudoraMac::~nsEudoraMac()
00098 {
00099        NS_IF_RELEASE( m_mailImportLocation);
00100 }
00101 
00102 PRBool nsEudoraMac::FindMailFolder( nsIFileSpec *pFolder)
00103 {
00104        return( FindEudoraLocation( pFolder));
00105 }
00106 
00107 PRBool nsEudoraMac::FindEudoraLocation( nsIFileSpec *pFolder, PRBool findIni, nsIFileSpec *pLookIn)
00108 {
00109        PRBool result = PR_FALSE;
00110        
00111        // The "default" eudora folder is in the system folder named
00112        // "Eudora Folder" (not sure if this is true for intl versions of Eudora)
00113        
00114        if (!pLookIn) {
00115               nsSpecialSystemDirectory    sysDir( nsSpecialSystemDirectory::Mac_SystemDirectory);
00116               pFolder->SetFromFileSpec( sysDir);
00117               pFolder->AppendRelativeUnixPath( "Eudora Folder");
00118               PRBool link = PR_FALSE;
00119               nsresult rv = pFolder->IsSymlink( &link);
00120               if (NS_SUCCEEDED( rv) && link) {
00121                      rv = pFolder->ResolveSymlink();
00122                      if (NS_FAILED( rv))
00123                             return( PR_FALSE);
00124               }
00125        }
00126        else
00127               pFolder->FromFileSpec( pLookIn);
00128               
00129        PRBool exists = PR_FALSE;
00130        nsresult rv = pFolder->Exists( &exists);
00131        PRBool isFolder = PR_FALSE;
00132        if (NS_SUCCEEDED( rv) && exists)
00133               rv = pFolder->IsDirectory( &isFolder);
00134        if (!exists || !isFolder)
00135               return( PR_FALSE);
00136        
00137        
00138        nsFileSpec                                       pref;
00139        PRBool                                           foundPref = PR_FALSE;
00140        
00141        nsCOMPtr<nsIDirectoryIterator>     dir;
00142        rv = NS_NewDirectoryIterator( getter_AddRefs( dir));
00143        if (NS_SUCCEEDED( rv) && dir) {
00144               exists = PR_FALSE;
00145               rv = dir->Init( pFolder, PR_TRUE);
00146               if (NS_SUCCEEDED( rv)) {
00147                      rv = dir->Exists( &exists);               
00148                      nsCOMPtr<nsIFileSpec>       entry;
00149                      int                                       count = 0;
00150                      OSType                             type, creator;
00151                      while (exists && NS_SUCCEEDED( rv) && (count < 2)) {
00152                             rv = dir->GetCurrentSpec( getter_AddRefs( entry));
00153                             if (NS_SUCCEEDED( rv)) {
00154                                    nsFileSpec spec;
00155                                    rv = entry->GetFileSpec( &spec);
00156                                    if (NS_SUCCEEDED( rv)) {
00157                                           // find a file with TEXT, CSOm that isn't the nicknames file
00158                                           // or just cheat and look for more than 1 file?
00159 #ifdef XP_MACOSX
00160   {
00161     nsCOMPtr<nsILocalFileMac> macFile;
00162     rv = NS_FileSpecToILocalFileMac(&spec, getter_AddRefs(macFile));
00163     if (NS_SUCCEEDED(rv))
00164     {
00165       macFile->GetFileCreator(&creator);
00166       macFile->GetFileType(&type);
00167     }
00168   }
00169 #else
00170                                           rv = spec.GetFileTypeAndCreator( &type, &creator);
00171 #endif
00172                                           if (NS_SUCCEEDED( rv)) {
00173                                                  if ((type == 'TEXT') && (creator == 'CSOm'))
00174                                                         count++;
00175                                                  else if ((type == 'PREF') && (creator == 'CSOm')) {
00176                                                         if (!foundPref) {
00177                                                                pref = spec;
00178                                                                foundPref = PR_TRUE;
00179                                                         }
00180                                                         else {
00181                                                                // does one of them end in ".bkup"?
00182                                                                char *pLeafName = spec.GetLeafName();
00183                                                                PRBool isBk = PR_FALSE;
00184                                                                PRInt32 len;
00185                                                                if (pLeafName) {
00186                                                                       len = strlen( pLeafName);
00187                                                                       if (len > 5)
00188                                                                              isBk = (nsCRT::strcasecmp( pLeafName + len - 5, ".bkup") == 0);
00189                                                                       nsCRT::free( pLeafName);
00190                                                                }
00191                                                                if (!isBk) {
00192                                                                       pLeafName = pref.GetLeafName();
00193                                                                       if (pLeafName) {
00194                                                                              len = strlen( pLeafName);
00195                                                                              if (len > 5)
00196                                                                                     isBk = (nsCRT::strcasecmp( pLeafName + len - 5, ".bkup") == 0);
00197                                                                              nsCRT::free( pLeafName);
00198                                                                       }
00199                                                                       if (isBk) {
00200                                                                              pref = spec;
00201                                                                       }
00202                                                                       else {
00203                                                                              // Neither of the pref files was named .bkup
00204                                                                              // Pick the newest one?
00205                                                                              nsFileSpec::TimeStamp       modDate1, modDate2;
00206                                                                              
00207                                                                              spec.GetModDate( modDate2);
00208                                                                              pref.GetModDate( modDate1);
00209                                                                              if (modDate2 > modDate1)
00210                                                                                     pref = spec;
00211                                                                       }
00212                                                                }
00213                                                         }
00214                                                  }
00215                                           }
00216                                    }
00217                             }
00218                             rv = dir->Next();
00219                             if (NS_SUCCEEDED( rv))
00220                                    rv = dir->Exists( &exists);
00221                      }
00222                      if (count >= 2)
00223                             result = PR_TRUE;
00224               }
00225        }
00226        
00227        if (!findIni)
00228               return( result);
00229                      
00230        if (!foundPref)
00231               return( PR_FALSE);
00232        
00233        pFolder->SetFromFileSpec( pref);
00234        
00235        return( PR_TRUE);
00236 }
00237 
00238 
00239 
00240 nsresult nsEudoraMac::FindMailboxes( nsIFileSpec *pRoot, nsISupportsArray **ppArray)
00241 {
00242        nsresult rv = NS_NewISupportsArray( ppArray);
00243        if (NS_FAILED( rv)) {
00244               IMPORT_LOG0( "FAILED to allocate the nsISupportsArray\n");
00245               return( rv);
00246        }
00247               
00248        nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
00249        if (NS_FAILED( rv))
00250               return( rv);
00251        
00252        m_depth = 0;
00253        NS_IF_RELEASE( m_mailImportLocation);
00254        m_mailImportLocation = pRoot;
00255        NS_IF_ADDREF( m_mailImportLocation);
00256 
00257        return( ScanMailDir( pRoot, *ppArray, impSvc));
00258 }
00259 
00260 
00261 nsresult nsEudoraMac::ScanMailDir( nsIFileSpec *pFolder, nsISupportsArray *pArray, nsIImportService *pImport)
00262 {
00263 
00264        // On Windows, we look for a descmap file but on Mac we just iterate
00265        // the directory
00266        
00267        m_depth++;
00268 
00269        nsresult rv = IterateMailDir( pFolder, pArray, pImport);
00270        
00271        m_depth--;
00272 
00273        return( rv);                
00274 }
00275 
00276 nsresult nsEudoraMac::IterateMailDir( nsIFileSpec *pFolder, nsISupportsArray *pArray, nsIImportService *pImport)
00277 {
00278        nsCOMPtr<nsIDirectoryIterator>     dir;
00279        nsresult rv = NS_NewDirectoryIterator( getter_AddRefs( dir));
00280        if (NS_FAILED( rv))
00281               return( rv);
00282 
00283        PRBool exists = PR_FALSE;
00284        rv = dir->Init( pFolder, PR_TRUE);
00285        if (NS_FAILED( rv))
00286               return( rv);
00287 
00288        rv = dir->Exists( &exists);
00289        if (NS_FAILED( rv))
00290               return( rv);
00291        
00292        PRBool                             isFolder;
00293        PRBool                             isFile;
00294        nsCOMPtr<nsIFileSpec>       entry;
00295        char *                             pName;
00296        nsCString                          fName;
00297        nsCString                          ext;
00298        nsCString                          name;
00299        nsFileSpec                         spec;
00300        OSType                             type;
00301        OSType                             creator;
00302        
00303        while (exists && NS_SUCCEEDED( rv)) {
00304               rv = dir->GetCurrentSpec( getter_AddRefs( entry));
00305               if (NS_SUCCEEDED( rv)) {
00306                      isFolder = PR_FALSE;
00307                      isFile = PR_FALSE;
00308                      pName = nsnull;
00309                      rv = entry->IsDirectory( &isFolder);
00310                      rv = entry->IsFile( &isFile);
00311                      rv = entry->GetLeafName( &pName);
00312                      if (NS_SUCCEEDED( rv) && pName) {
00313                             fName = pName;
00314                             nsCRT::free( pName);
00315                             if (isFolder) {
00316                                    if (IsValidMailFolderName( fName)) {
00317                                           rv = FoundMailFolder( entry, fName.get(), pArray, pImport);
00318                                           if (NS_SUCCEEDED( rv)) {
00319                                                  rv = ScanMailDir( entry, pArray, pImport);
00320                                                  if (NS_FAILED( rv)) {
00321                                                         IMPORT_LOG0( "*** Error scanning mail directory\n");
00322                                                  }
00323                                           }
00324                                    }
00325                             }
00326                             else if (isFile) {
00327                                    rv = entry->GetFileSpec( &spec);
00328                                    if (NS_SUCCEEDED( rv)) {
00329                                           type = 0;
00330                                           creator = 0;
00331 #ifdef XP_MACOSX
00332   {
00333     nsCOMPtr<nsILocalFileMac> macFile;
00334     rv = NS_FileSpecToILocalFileMac(&spec, getter_AddRefs(macFile));
00335     if (NS_SUCCEEDED(rv))
00336     {
00337       macFile->GetFileCreator(&creator);
00338       macFile->GetFileType(&type);
00339     }
00340   }
00341 #else
00342     spec.GetFileTypeAndCreator( &type, &creator);
00343 #endif
00344                                           if ((type == 'TEXT') && IsValidMailboxName( fName) && IsValidMailboxFile( entry)) {
00345                                                  rv = FoundMailbox( entry, fName.get(), pArray, pImport);
00346                                           }
00347                                    }
00348                             }
00349                      }                           
00350               }
00351 
00352               rv = dir->Next();
00353               if (NS_SUCCEEDED( rv))
00354                      rv = dir->Exists( &exists);
00355        }
00356 
00357        return( rv);
00358 }
00359 
00360 
00361 
00362 nsresult nsEudoraMac::FoundMailbox( nsIFileSpec *mailFile, const char *pName, nsISupportsArray *pArray, nsIImportService *pImport)
00363 {
00364        nsAutoString                                            displayName;
00365        nsCOMPtr<nsIImportMailboxDescriptor>      desc;
00366        nsISupports *                                           pInterface;
00367 
00368        NS_CopyNativeToUnicode(nsDependentCString(pName), displayName);
00369 
00370 #ifdef IMPORT_DEBUG
00371        char *pPath = nsnull;
00372        mailFile->GetNativePath( &pPath);
00373        if (pPath) {
00374               IMPORT_LOG2( "Found eudora mailbox, %s: %s\n", pPath, pName);
00375               nsCRT::free( pPath);
00376        }
00377        else {
00378               IMPORT_LOG1( "Found eudora mailbox, %s\n", pName);
00379        }
00380        IMPORT_LOG1( "\tm_depth = %d\n", (int)m_depth);
00381 #endif
00382 
00383        nsresult rv = pImport->CreateNewMailboxDescriptor( getter_AddRefs( desc));
00384        if (NS_SUCCEEDED( rv)) {
00385               PRUint32             sz = 0;
00386               mailFile->GetFileSize( &sz);       
00387               desc->SetDisplayName( displayName.get());
00388               desc->SetDepth( m_depth);
00389               desc->SetSize( sz);
00390               nsIFileSpec *pSpec = nsnull;
00391               desc->GetFileSpec( &pSpec);
00392               if (pSpec) {
00393                      pSpec->FromFileSpec( mailFile);
00394                      NS_RELEASE( pSpec);
00395               }
00396               rv = desc->QueryInterface( kISupportsIID, (void **) &pInterface);
00397               pArray->AppendElement( pInterface);
00398               pInterface->Release();
00399        }
00400 
00401        return( NS_OK);
00402 }
00403 
00404 
00405 nsresult nsEudoraMac::FoundMailFolder( nsIFileSpec *mailFolder, const char *pName, nsISupportsArray *pArray, nsIImportService *pImport)
00406 {
00407        nsAutoString                              displayName;
00408        nsCOMPtr<nsIImportMailboxDescriptor>      desc;
00409        nsISupports *                                           pInterface;
00410 
00411        NS_CopyNativeToUnicode(nsDependentCString(pName), displayName);
00412 
00413 #ifdef IMPORT_DEBUG
00414        char *pPath = nsnull;
00415        mailFolder->GetNativePath( &pPath);
00416        if (pPath) {
00417               IMPORT_LOG2( "Found eudora folder, %s: %s\n", pPath, pName);
00418               nsCRT::free( pPath);
00419        }
00420        else {
00421               IMPORT_LOG1( "Found eudora folder, %s\n", pName);
00422        }
00423        IMPORT_LOG1( "\tm_depth = %d\n", (int)m_depth);
00424 #endif
00425 
00426        nsresult rv = pImport->CreateNewMailboxDescriptor( getter_AddRefs( desc));
00427        if (NS_SUCCEEDED( rv)) {
00428               PRUint32             sz = 0;
00429               desc->SetDisplayName( displayName.get());
00430               desc->SetDepth( m_depth);
00431               desc->SetSize( sz);
00432               nsIFileSpec *pSpec = nsnull;
00433               desc->GetFileSpec( &pSpec);
00434               if (pSpec) {
00435                      pSpec->FromFileSpec( mailFolder);
00436                      NS_RELEASE( pSpec);
00437               }
00438               rv = desc->QueryInterface( kISupportsIID, (void **) &pInterface);
00439               pArray->AppendElement( pInterface);
00440               pInterface->Release();
00441        }
00442 
00443        return( NS_OK);
00444 }
00445 
00446 PRBool nsEudoraMac::CreateTocFromResource( nsIFileSpec *pMail, nsIFileSpec *pToc)
00447 {      
00448        nsFileSpec    spec;
00449        nsresult rv = pMail->GetFileSpec( &spec);
00450        if (NS_FAILED( rv))
00451               return( PR_FALSE);
00452         short resFile = -1;
00453 #ifdef XP_MACOSX
00454         {
00455           nsCOMPtr<nsILocalFileMac> macFile;
00456           rv = NS_FileSpecToILocalFileMac(&spec, getter_AddRefs(macFile));
00457           if (NS_FAILED(rv))
00458             return PR_FALSE;
00459 
00460           FSSpec fsSpec;
00461           rv = macFile->GetFSSpec(&fsSpec);
00462          if (NS_FAILED(rv))
00463             return PR_FALSE;
00464 
00465           resFile = FSpOpenResFile( &fsSpec, fsRdPerm);
00466         }
00467 #else
00468         resFile = FSpOpenResFile( spec.GetFSSpecPtr(), fsRdPerm);
00469 #endif
00470        if (resFile == -1)
00471               return( PR_FALSE);
00472        Handle resH = nil;
00473        short max = Count1Resources( 'TOCF');
00474        if (max) {
00475               resH = Get1IndResource( 'TOCF', 1);
00476        }
00477        PRBool  result = PR_FALSE;
00478        if (resH) {
00479               PRInt32 sz = (PRInt32) GetHandleSize( resH);
00480               if (sz) {
00481                      // Create the new TOC file
00482                      nsSpecialSystemDirectory    dir( nsSpecialSystemDirectory::OS_TemporaryDirectory);
00483                      rv = pToc->SetFromFileSpec( dir);
00484                      if (NS_SUCCEEDED( rv))
00485                             rv = pToc->AppendRelativeUnixPath( "temp.toc");
00486                      if (NS_SUCCEEDED( rv))
00487                             rv = pToc->MakeUnique();
00488                      if (NS_SUCCEEDED( rv))
00489                             rv = pToc->OpenStreamForWriting();
00490                      if (NS_SUCCEEDED( rv)) { 
00491                             HLock( resH);
00492                             PRInt32 written = 0;
00493                             rv = pToc->Write( *resH, sz, &written);
00494                             HUnlock( resH);
00495                             pToc->CloseStream();
00496                             if (NS_FAILED( rv) || (written != sz)) {
00497                                    pToc->GetFileSpec( &spec);
00498                                    spec.Delete( PR_FALSE);
00499                             }
00500                             else
00501                                    result = PR_TRUE;
00502                      }
00503               }             
00504               ReleaseResource( resH);
00505        }
00506        CloseResFile( resFile); 
00507        
00508        return( result);
00509 }
00510 
00511 
00512 nsresult nsEudoraMac::FindTOCFile( nsIFileSpec *pMailFile, nsIFileSpec **ppTOCFile, PRBool *pDeleteToc)
00513 {
00514        nsresult             rv;
00515        char   *             pName = nsnull;
00516 
00517        *pDeleteToc = PR_FALSE;
00518        *ppTOCFile = nsnull;
00519        rv = pMailFile->GetLeafName( &pName);
00520        if (NS_FAILED( rv))
00521               return( rv);
00522        rv = pMailFile->GetParent( ppTOCFile);
00523        if (NS_FAILED( rv))
00524               return( rv);
00525 
00526        nsCString     leaf(pName);
00527        nsCRT::free( pName);
00528        leaf.Append( ".toc");
00529        
00530        OSType type = 0;
00531        OSType creator = 0;
00532        PRBool exists = PR_FALSE;
00533        PRBool isFile = PR_FALSE;
00534        rv = (*ppTOCFile)->AppendRelativeUnixPath( leaf.get());
00535        if (NS_SUCCEEDED( rv))
00536               rv = (*ppTOCFile)->Exists( &exists);
00537        if (NS_SUCCEEDED( rv) && exists)
00538               rv = (*ppTOCFile)->IsFile( &isFile);
00539        if (isFile) {
00540               nsFileSpec    spec;
00541               rv = (*ppTOCFile)->GetFileSpec( &spec);
00542               if (NS_SUCCEEDED( rv))
00543 #ifdef XP_MACOSX
00544   {
00545     nsCOMPtr<nsILocalFileMac> macFile;
00546     rv = NS_FileSpecToILocalFileMac(&spec, getter_AddRefs(macFile));
00547     if (NS_SUCCEEDED(rv))
00548     {
00549       macFile->GetFileCreator(&creator);
00550       macFile->GetFileType(&type);
00551     }
00552   }
00553 #else
00554                      spec.GetFileTypeAndCreator( &type, &creator);
00555 #endif
00556        }
00557        
00558 
00559        if (exists && isFile && (type == 'TOCF') && (creator == 'CSOm'))
00560               return( NS_OK);
00561        
00562        // try and create the file from a resource.
00563        if (CreateTocFromResource( pMailFile, *ppTOCFile)) {
00564               *pDeleteToc = PR_TRUE;
00565               return( NS_OK);
00566        }
00567        return( NS_ERROR_FAILURE);
00568 }
00569 
00570 
00571 // Strings returned:
00572 //     1 - smtp server
00573 //  2 - pop account user name
00574 //     3 - the pop server
00575 //     4 - Return address
00576 //     5 - Full name
00577 //     6 - Leave mail on server
00578 #define       kNumSettingStrs                    6
00579 #define       kSmtpServerStr                     0
00580 #define       kPopAccountNameStr          1
00581 #define       kPopServerStr               2
00582 #define kReturnAddressStr          3
00583 #define       kFullNameStr                4
00584 #define kLeaveOnServerStr          5
00585 
00586 // resource IDs 
00587 #define kSmtpServerID         4
00588 #define kEmailAddressID       3
00589 #define kReturnAddressID      5
00590 #define kFullNameID           77
00591 #define kLeaveMailOnServerID  18
00592 
00593 
00594 PRBool nsEudoraMac::GetSettingsFromResource( nsIFileSpec *pSettings, short resId, nsCString **pStrs, PRBool *pIMAP)
00595 {
00596        *pIMAP = PR_FALSE;
00597        // Get settings from the resources...
00598        nsFileSpec    spec;
00599        nsresult rv = pSettings->GetFileSpec( &spec);
00600        if (NS_FAILED( rv))
00601               return( PR_FALSE);
00602 
00603         short resFile = -1;
00604 #ifdef XP_MACOSX
00605         {
00606           nsCOMPtr<nsILocalFileMac> macFile;
00607           rv = NS_FileSpecToILocalFileMac(&spec, getter_AddRefs(macFile));
00608          if (NS_FAILED(rv))
00609             return PR_FALSE;
00610 
00611           FSSpec fsSpec;
00612           rv = macFile->GetFSSpec(&fsSpec);
00613          if (NS_FAILED(rv))
00614             return PR_FALSE;
00615 
00616           resFile = FSpOpenResFile( &fsSpec, fsRdPerm);
00617         }
00618 #else
00619        resFile = FSpOpenResFile( spec.GetFSSpecPtr(), fsRdPerm);
00620 #endif
00621        if (resFile == -1)
00622               return( PR_FALSE);
00623               
00624        // smtp server, STR# 1000, 4
00625        Handle resH = Get1Resource( 'STR#', resId /* 1000 */);
00626        int           idx;
00627        if (resH) {
00628               ReleaseResource( resH);
00629               StringPtr     pStr[5];
00630               StringPtr     theStr;
00631               short         i;
00632               for (i = 0; i < 5; i++) {
00633                      pStr[i] = (StringPtr) new PRUint8[256];
00634                      (pStr[i])[0] = 0;
00635               }
00636               GetIndString( pStr[0], resId /* 1000 */, kSmtpServerID);
00637               GetIndString( pStr[1], resId, kEmailAddressID); // user name@pop server
00638               GetIndString( pStr[2], resId, kReturnAddressID); 
00639               GetIndString( pStr[3], resId, kFullNameID);
00640               GetIndString( pStr[4], resId, kLeaveMailOnServerID);
00641               CloseResFile( resFile); 
00642               
00643               theStr = pStr[0];
00644               if (*theStr) {
00645                      pStrs[0]->Append( (const char *) (theStr + 1), *theStr);
00646               }
00647               theStr = pStr[1];
00648               if (*theStr) {
00649                      idx = 1;
00650                      while (idx <= *theStr) {
00651                             if (theStr[idx] == '@')
00652                                    break;
00653                             else
00654                                    idx++;
00655                      }
00656                      if (idx <= *theStr) {
00657                             PRUint8       save = *theStr;
00658                             *theStr = idx - 1;
00659                             if (*theStr) {
00660                                    pStrs[1]->Append( (const char *) (theStr + 1), *theStr);
00661                             }
00662                             *theStr = save;
00663                      }
00664                      else
00665                             idx = 0;
00666                      theStr[idx] = theStr[0] - idx;
00667                      if (theStr[idx]) {
00668                             pStrs[2]->Append( (const char *) (theStr + idx + 1), *(theStr + idx));
00669                      }
00670               }
00671               theStr = pStr[2];
00672               if ( *theStr) {
00673                      pStrs[3]->Append( (const char *) (theStr + 1), *theStr);
00674               }
00675               theStr = pStr[3];
00676               if ( *theStr) {
00677                      pStrs[4]->Append( (const char *) (theStr + 1), *theStr);
00678               }
00679               theStr = pStr[4];
00680               if ( *theStr) {
00681                      if (theStr[1] == 'y') {
00682                             *(pStrs[5]) = "Y";
00683                      }
00684                      else {
00685                             *(pStrs[5]) = "N";
00686                      }
00687               }
00688               for (i = 0; i < 5; i++) {
00689                      delete pStr[i];
00690               }
00691               
00692               return( PR_TRUE);
00693        }
00694        else {
00695               CloseResFile( resFile); 
00696               return( PR_FALSE);
00697        }
00698 }
00699 
00700 PRBool nsEudoraMac::ImportSettings( nsIFileSpec *pIniFile, nsIMsgAccount **localMailAccount)
00701 {
00702        nsresult      rv;
00703 
00704        nsCOMPtr<nsIMsgAccountManager> accMgr = 
00705                 do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
00706     if (NS_FAILED(rv)) {
00707               IMPORT_LOG0( "*** Failed to create a account manager!\n");
00708               return( PR_FALSE);
00709        }
00710 
00711        short  baseResId = 1000;
00712        nsCString **pStrs = new nsCString *[kNumSettingStrs];
00713        int           i;
00714        
00715        for (i = 0; i < kNumSettingStrs; i++) {
00716               pStrs[i] = new nsCString;
00717        }
00718        
00719        nsString accName(NS_LITERAL_STRING("Eudora Settings"));
00720        nsEudoraStringBundle::GetStringByID( EUDORAIMPORT_ACCOUNTNAME, accName);
00721        
00722        // This is a little overkill but we're not sure yet how multiple accounts
00723        // are stored in the Mac preferences, hopefully similar to existing prefs
00724        // which means the following is a good start!
00725        PRBool isIMAP = PR_FALSE;   
00726        
00727        int                         popCount = 0;
00728        int                         accounts = 0; 
00729        nsIMsgAccount *      pAccount;
00730 
00731        while (baseResId) {
00732               isIMAP = PR_FALSE;
00733               if (GetSettingsFromResource( pIniFile, baseResId, pStrs, &isIMAP)) {
00734                      pAccount = nsnull;
00735                      if (!isIMAP) {
00736                             // This is a POP account
00737                             if (BuildPOPAccount( accMgr, pStrs, &pAccount, accName)) {
00738                                    accounts++;
00739                                    popCount++;
00740                                    if (popCount > 1) {
00741                                           if (localMailAccount && *localMailAccount) {
00742                                                  NS_RELEASE( *localMailAccount);
00743                                                  *localMailAccount = nsnull;
00744                                           }
00745                                    }
00746                                    else {
00747                                           if (localMailAccount) {
00748                                                  *localMailAccount = pAccount;
00749                                                  NS_IF_ADDREF( pAccount);
00750                                           }                                  
00751                                    }
00752                             }
00753                      }
00754                      else {
00755                             // This is an IMAP account
00756                             if (BuildIMAPAccount( accMgr, pStrs, &pAccount, accName)) {
00757                                    accounts++;
00758                             }
00759                      }
00760                      if (pAccount && (baseResId == 1000)) {
00761                             accMgr->SetDefaultAccount( pAccount);
00762                      }
00763 
00764                      NS_IF_RELEASE( pAccount);
00765               }
00766                             
00767               baseResId = 0;
00768               // Set the next account name???
00769               
00770               if (baseResId) {
00771                      for (i = 0; i < kNumSettingStrs; i++) {
00772                             pStrs[i]->Truncate();
00773                      }
00774               }             
00775        }
00776 
00777        // Now save the new acct info to pref file.
00778        rv = accMgr->SaveAccountInfo();
00779        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't save account info to pref file");
00780 
00781        for (i = 0; i < kNumSettingStrs; i++) {
00782               delete pStrs[i];
00783        }
00784        delete pStrs;
00785 
00786        return( accounts != 0);
00787 }
00788 
00789 
00790 
00791 PRBool nsEudoraMac::BuildPOPAccount( nsIMsgAccountManager *accMgr, nsCString **pStrs, nsIMsgAccount **ppAccount, nsString& accName)
00792 {
00793        if (ppAccount)
00794               *ppAccount = nsnull;
00795        
00796               
00797        if (!pStrs[kPopServerStr]->Length() || !pStrs[kPopAccountNameStr]->Length())
00798               return( PR_FALSE);
00799 
00800        PRBool result = PR_FALSE;
00801 
00802        // I now have a user name/server name pair, find out if it already exists?
00803        nsCOMPtr<nsIMsgIncomingServer>     in;
00804        nsresult rv = accMgr->FindServer( pStrs[kPopAccountNameStr]->get(), pStrs[kPopServerStr]->get(), "pop3", getter_AddRefs( in));
00805        if (NS_FAILED( rv) || (in == nsnull)) {
00806               // Create the incoming server and an account for it?
00807               rv = accMgr->CreateIncomingServer( pStrs[kPopAccountNameStr]->get(), pStrs[kPopServerStr]->get(), "pop3", getter_AddRefs( in));
00808               if (NS_SUCCEEDED( rv) && in) {
00809                      rv = in->SetType( "pop3");
00810                      // rv = in->SetHostName( pStrs[kPopServerStr]->get());
00811                      // rv = in->SetUsername( pStrs[kPopAccountNameStr]->get());
00812 
00813                      IMPORT_LOG2( "Created POP3 server named: %s, userName: %s\n", pStrs[kPopServerStr]->get(), pStrs[kPopAccountNameStr]->get());
00814 
00815                      PRUnichar *pretty = ToNewUnicode(accName);
00816                      IMPORT_LOG1( "\tSet pretty name to: %S\n", pretty);
00817                      rv = in->SetPrettyName( pretty);
00818                      nsCRT::free( pretty);
00819                      
00820                      // We have a server, create an account.
00821                      nsCOMPtr<nsIMsgAccount>     account;
00822                      rv = accMgr->CreateAccount( getter_AddRefs( account));
00823                      if (NS_SUCCEEDED( rv) && account) {
00824                             rv = account->SetIncomingServer( in);
00825                             
00826                             IMPORT_LOG0( "Created a new account and set the incoming server to the POP3 server.\n");
00827                                    
00828         nsCOMPtr<nsIPop3IncomingServer> pop3Server = do_QueryInterface(in, &rv);
00829         NS_ENSURE_SUCCESS(rv,rv);
00830         pop3Server->SetLeaveMessagesOnServer(pStrs[kLeaveOnServerStr]->First() == 'Y' ? PR_TRUE : PR_FALSE);
00831 
00832         // Fiddle with the identities
00833                             SetIdentities(accMgr, account, pStrs[kPopAccountNameStr]->get(), pStrs[kPopServerStr]->get(), pStrs);
00834                             result = PR_TRUE;
00835                             if (ppAccount)
00836                                    account->QueryInterface( NS_GET_IID(nsIMsgAccount), (void **)ppAccount);
00837                      }                           
00838               }
00839        }
00840        else
00841               result = PR_TRUE;
00842        
00843        return( result);
00844 }
00845 
00846 
00847 PRBool nsEudoraMac::BuildIMAPAccount( nsIMsgAccountManager *accMgr, nsCString **pStrs, nsIMsgAccount **ppAccount, nsString& accName)
00848 {      
00849 
00850        if (!pStrs[kPopServerStr]->Length() || !pStrs[kPopAccountNameStr]->Length())
00851               return( PR_FALSE);
00852 
00853        PRBool result = PR_FALSE;
00854 
00855        nsCOMPtr<nsIMsgIncomingServer>     in;
00856        nsresult rv = accMgr->FindServer( pStrs[kPopAccountNameStr]->get(), pStrs[kPopServerStr]->get(), "imap", getter_AddRefs( in));
00857        if (NS_FAILED( rv) || (in == nsnull)) {
00858               // Create the incoming server and an account for it?
00859               rv = accMgr->CreateIncomingServer( pStrs[kPopAccountNameStr]->get(), pStrs[kPopServerStr]->get(), "imap", getter_AddRefs( in));
00860               if (NS_SUCCEEDED( rv) && in) {
00861                      rv = in->SetType( "imap");
00862                      // rv = in->SetHostName( pStrs[kPopServerStr]->get());
00863                      // rv = in->SetUsername( pStrs[kPopAccountNameStr]->get());
00864                      
00865                      IMPORT_LOG2( "Created IMAP server named: %s, userName: %s\n", pStrs[kPopServerStr]->get(), pStrs[kPopAccountNameStr]->get());
00866                      
00867                      PRUnichar *pretty = ToNewUnicode(accName);
00868                      
00869                      IMPORT_LOG1( "\tSet pretty name to: %S\n", pretty);
00870 
00871                      rv = in->SetPrettyName( pretty);
00872                      nsCRT::free( pretty);
00873                      
00874                      // We have a server, create an account.
00875                      nsCOMPtr<nsIMsgAccount>     account;
00876                      rv = accMgr->CreateAccount( getter_AddRefs( account));
00877                      if (NS_SUCCEEDED( rv) && account) {
00878                             rv = account->SetIncomingServer( in);     
00879                             
00880                             IMPORT_LOG0( "Created an account and set the IMAP server as the incoming server\n");
00881 
00882                             // Fiddle with the identities
00883                             SetIdentities(accMgr, account, pStrs[kPopAccountNameStr]->get(), pStrs[kPopServerStr]->get(), pStrs);
00884                             result = PR_TRUE;
00885                             if (ppAccount)
00886                                    account->QueryInterface( NS_GET_IID(nsIMsgAccount), (void **)ppAccount);
00887                      }                           
00888               }
00889        }
00890        else
00891               result = PR_TRUE;
00892 
00893        return( result);
00894 }
00895 
00896 
00897 void nsEudoraMac::SetIdentities(nsIMsgAccountManager *accMgr, nsIMsgAccount *acc, const char *userName, const char *serverName, nsCString **pStrs)
00898 {
00899        nsresult      rv;
00900        
00901        nsCOMPtr<nsIMsgIdentity>    id;
00902        rv = accMgr->CreateIdentity( getter_AddRefs( id));
00903        if (id) {
00904               nsAutoString fullName; 
00905               if (pStrs[kFullNameStr]->Length()) {
00906                      fullName.AssignWithConversion(pStrs[kFullNameStr]->get());
00907               }
00908               id->SetFullName( fullName.get());
00909               id->SetIdentityName( fullName.get());
00910               if (pStrs[kReturnAddressStr]->Length()) {
00911                      id->SetEmail( pStrs[kReturnAddressStr]->get());
00912               }
00913               else {
00914                      nsCAutoString emailAddress;
00915                      emailAddress = userName;
00916                      emailAddress += "@";
00917                      emailAddress += serverName;
00918                      id->SetEmail(emailAddress.get()); 
00919               }
00920               acc->AddIdentity( id);
00921 
00922               IMPORT_LOG0( "Created identity and added to the account\n");
00923               IMPORT_LOG1( "\tname: %s\n", pStrs[kFullNameStr]->get());
00924               IMPORT_LOG1( "\temail: %s\n", pStrs[kReturnAddressStr]->get());
00925        }
00926 
00927        SetSmtpServer( accMgr, acc, pStrs[kSmtpServerStr]->get(), userName);
00928               
00929 }
00930 
00931 
00932 void nsEudoraMac::SetSmtpServer( nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, const char *pServer, const char *pUser)
00933 {
00934        nsresult      rv;
00935        
00936        nsCOMPtr<nsISmtpService> smtpService(do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv)); 
00937        if (NS_SUCCEEDED(rv) && smtpService) {
00938               nsCOMPtr<nsISmtpServer>            foundServer;
00939        
00940               rv = smtpService->FindServer( pUser, pServer, getter_AddRefs( foundServer));
00941               if (NS_SUCCEEDED( rv) && foundServer) {
00942                      IMPORT_LOG1( "SMTP server already exists: %s\n", pServer);
00943                      return;
00944               }
00945               nsCOMPtr<nsISmtpServer>            smtpServer;
00946               
00947               rv = smtpService->CreateSmtpServer( getter_AddRefs( smtpServer));
00948               if (NS_SUCCEEDED( rv) && smtpServer) {
00949                      smtpServer->SetHostname( pServer);
00950                      if (pUser)
00951                             smtpServer->SetUsername( pUser);
00952 
00953                      IMPORT_LOG1( "Created new SMTP server: %s\n", pServer);
00954               }
00955        }
00956 }
00957 
00958 
00959 nsresult nsEudoraMac::GetAttachmentInfo( const char *pFileName, nsIFileSpec *pSpec, nsCString& mimeType, nsCString& aAttachment)
00960 {
00961        mimeType.Truncate();
00962 
00963        // Sample attachment line
00964        // Internet:sandh.jpg (JPEG/JVWR) (0003C2E8)
00965        
00966        OSType        type = '????';
00967        OSType        creator = '????';
00968        PRUint32      fNum = 0;
00969        int                  i;
00970        PRUnichar     c;
00971        
00972        nsCString     str(pFileName);
00973        if (str.Length() > 22) {
00974               // try and extract the mac file info from the attachment line
00975               nsCString     fileNum;
00976               nsCString     types;
00977               
00978               str.Right( fileNum, 10);
00979               if ((fileNum.CharAt( 0) == '(') && (fileNum.CharAt( 9) == ')')) {
00980                      for (i = 1; i < 9; i++) {
00981                             fNum *= 16;
00982                             c = fileNum.CharAt( i);
00983                             if ((c >= '0') && (c <= '9'))
00984                                    fNum += (c - '0');
00985                             else if ((c >= 'a') && (c <= 'f'))
00986                                    fNum += (c - 'a' + 10);
00987                             else if ((c >= 'A') && (c <= 'F'))
00988                                    fNum += (c - 'A' + 10);
00989                             else
00990                                    break;
00991                      }
00992                      if (i == 9) {
00993                             str.Left( fileNum, str.Length() - 10);
00994                             str = fileNum;
00995                             str.Trim( kWhitespace);
00996                             str.Right( types, 11);
00997                             if ((types.CharAt( 0) == '(') && (types.CharAt( 5) == '/') && (types.CharAt( 10) == ')')) {
00998                                    type = ((PRUint32)types.CharAt( 1)) << 24;
00999                                    type |= ((PRUint32)types.CharAt( 2)) << 16;
01000                                    type |= types.CharAt( 3) << 8;
01001                                    type |= types.CharAt( 4);
01002                                    creator = ((PRUint32)types.CharAt( 6)) << 24;
01003                                    creator |= ((PRUint32)types.CharAt( 7)) << 16;
01004                                    creator |= types.CharAt( 8) << 8;
01005                                    creator |= types.CharAt( 9);
01006                                    str.Left( types, str.Length() - 11);
01007                                    str = types;
01008                                    str.Trim( kWhitespace);
01009                             }
01010                      }
01011                      else
01012                             fNum = 0;
01013               }
01014        }
01015        
01016 #ifdef IMPORT_DEBUG
01017        nsCString     typeStr;
01018        nsCString     creatStr;
01019        
01020        creatStr.Append( (const char *)&creator, 4);
01021        typeStr.Append( (const char *)&type, 4);
01022        IMPORT_LOG3( "\tAttachment type: %s, creator: %s, fileNum: %ld\n", typeStr.get(), creatStr.get(), fNum);
01023        IMPORT_LOG1( "\tAttachment file name: %s\n", str.get());
01024 #endif
01025        FSSpec spec;
01026        memset( &spec, 0, sizeof( spec));
01027 #ifdef XP_MACOSX
01028         {
01029           nsresult rv = pSpec->SetNativePath(str.get());
01030           if (NS_FAILED(rv)) {
01031             IMPORT_LOG0("\tfailed to set native path\n");
01032             return rv;
01033           }
01034   
01035           nsFileSpec tempFileSpec;
01036           rv = pSpec->GetFileSpec(&tempFileSpec);
01037           if (NS_FAILED(rv)) {
01038             IMPORT_LOG0("\tfailed to get file spec\n");
01039             return rv;
01040           }
01041 
01042           char *pLeaf = nsnull;
01043                     pSpec->GetLeafName( &pLeaf);
01044           aAttachment.Adopt(pLeaf);
01045 
01046           nsCOMPtr<nsILocalFileMac> macFile;
01047           rv = NS_FileSpecToILocalFileMac(&tempFileSpec, getter_AddRefs(macFile));
01048           if (NS_FAILED(rv)) {
01049             IMPORT_LOG0("\tfailed to get local mac file\n");
01050             return rv;
01051           }
01052           
01053           rv = macFile->GetFSSpec(&spec);
01054           if (NS_FAILED(rv)) {
01055             IMPORT_LOG0("\tfailed to get FSSpec\n");
01056             return rv;
01057           }
01058         }
01059 #else
01060        // Now we have all of the pertinent info, find out if the file exists?
01061        nsCString     fileName;
01062        if ((str.CharAt( 0) == '"') && (str.Last() == '"')) {
01063               str.Mid( fileName, 1, str.Length() - 2);
01064               str = fileName;
01065        }
01066        
01067        PRInt32 idx = str.FindChar( ':');
01068        if (idx == -1) {
01069               return( NS_ERROR_FAILURE);
01070        }
01071        
01072        nsCString     volumeName;
01073        str.Left( volumeName, idx + 1);
01074        str.Right( fileName, str.Length() - idx - 1);
01075        
01076        // Create a FSSpec from the volume name, fileName, and folderNumber
01077        // Assume that we are looking for a file on the volume with macFileId
01078        Str63  str63;
01079        short  vRefNum = 0;
01080        if (volumeName.Length() > 63) {
01081               memcpy( &(str63[1]), volumeName.get(), 63);
01082               str63[0] = 63;
01083        }
01084        else {
01085               memcpy( &(str63[1]), volumeName.get(), volumeName.Length());
01086               str63[0] = volumeName.Length();
01087        }
01088               
01089        OSErr err = DetermineVRefNum( str63, 0, &vRefNum);
01090        if (err != noErr) {
01091               IMPORT_LOG0( "\t*** Error cannot find volume ref num\n");
01092               return( NS_ERROR_FAILURE);
01093        }
01094        
01095        err = FSpResolveFileIDRef( nil, vRefNum, (long) fNum, &spec);
01096        if (err != noErr) {
01097               IMPORT_LOG1( "\t*** Error, cannot resolve fileIDRef: %ld\n", (long) err);
01098               return( NS_ERROR_FAILURE);
01099        }
01100        
01101        
01102        FInfo  fInfo;
01103        err = FSpGetFInfo( &spec, &fInfo);
01104        if ((err != noErr) || (fInfo.fdType != (OSType) type)) {
01105               IMPORT_LOG0( "\t*** Error, file type does not match\n");
01106               return( NS_ERROR_FAILURE);
01107        }
01108        
01109        nsFileSpec    fSpec( spec);
01110        pSpec->SetFromFileSpec( fSpec);
01111 #endif
01112        
01113 #ifdef XP_MACOSX
01114        if (HasResourceFork(&spec)) 
01115 #else
01116         // Need to find the mime type for the attachment?
01117         long    dataSize = 0;
01118         long    rsrcSize = 0;
01119  
01120         err = FSpGetFileSize( &spec, &dataSize, &rsrcSize);
01121  
01122         // TLR: FIXME: Need to get the mime type from the Mac file type.
01123         // Currently we just applsingle if there is a resource fork, otherwise,
01124         // just default to something.
01125  
01126         if (rsrcSize)
01127 #endif
01128               mimeType = "application/applefile";
01129        else
01130               mimeType = "application/octet-stream";
01131        
01132        IMPORT_LOG1( "\tMimeType: %s\n", mimeType.get());
01133        
01134        return( NS_OK);
01135 }
01136               
01137 PRBool nsEudoraMac::HasResourceFork(FSSpec *fsSpec)
01138 {
01139   FSRef fsRef;
01140   if (::FSpMakeFSRef(fsSpec, &fsRef) == noErr)
01141   {
01142     FSCatalogInfo catalogInfo;
01143     OSErr err = ::FSGetCatalogInfo(&fsRef, kFSCatInfoRsrcSizes, &catalogInfo, nsnull, nsnull, nsnull);
01144     return (err == noErr && catalogInfo.rsrcLogicalSize != 0);
01145   }
01146   return PR_FALSE;
01147 }
01148 
01149 
01150 #define              kNumBadFolderNames          7
01151 const char *cBadFolderNames[kNumBadFolderNames] = {
01152        "Attachments Folder",
01153        "Eudora Items",
01154        "Nicknames Folder",
01155        "Parts Folder",
01156        "Signature Folder",
01157        "Spool Folder",
01158        "Stationery Folder"
01159 };
01160 
01161 PRBool nsEudoraMac::IsValidMailFolderName( nsCString& name)
01162 {
01163        if (m_depth > 1)
01164               return( PR_TRUE);
01165        
01166        for (int i = 0; i < kNumBadFolderNames; i++) {
01167               if (name.Equals( cBadFolderNames[i], nsCaseInsensitiveCStringComparator()))
01168                      return( PR_FALSE);
01169        }
01170        
01171        return( PR_TRUE);
01172 }
01173 
01174 
01175 PRBool nsEudoraMac::IsValidMailboxName( nsCString& fName)
01176 {
01177        if (m_depth > 1)
01178               return( PR_TRUE);
01179        if (fName.Equals(NS_LITERAL_CSTRING("Eudora Nicknames"), nsCaseInsensitiveCStringComparator()))
01180               return( PR_FALSE);
01181        return( PR_TRUE);
01182 }
01183 
01184 
01185 PRBool nsEudoraMac::IsValidMailboxFile( nsIFileSpec *pFile)
01186 {
01187        PRUint32      size = 0;
01188        nsresult rv = pFile->GetFileSize( &size);
01189        if (size) {
01190               if (size < 10)
01191                      return( PR_FALSE);
01192               rv = pFile->OpenStreamForReading();
01193               if (NS_FAILED( rv))
01194                      return( PR_FALSE);
01195               PRInt32       read = 0;
01196               char   buffer[6];
01197               char * pBuf = buffer;
01198               rv = pFile->Read( &pBuf, 5, &read);
01199               pFile->CloseStream();
01200               if (NS_FAILED( rv) || (read != 5))
01201                      return( PR_FALSE);
01202               buffer[5] = 0;
01203               if (nsCRT::strcmp( buffer, "From "))
01204                      return( PR_FALSE);
01205        }
01206        
01207        return( PR_TRUE);
01208 }
01209 
01210 
01211 
01212 
01213 PRBool nsEudoraMac::FindAddressFolder( nsIFileSpec *pFolder)
01214 {
01215        return( FindEudoraLocation( pFolder));
01216 }
01217 
01218 nsresult nsEudoraMac::FindAddressBooks( nsIFileSpec *pRoot, nsISupportsArray **ppArray)
01219 {
01220        // Look for the nicknames file in this folder and then
01221        // additional files in the Nicknames folder
01222        // Try and find the nickNames file
01223        nsCOMPtr<nsIFileSpec>       spec;
01224        nsresult rv = NS_NewFileSpec( getter_AddRefs( spec));
01225        if (NS_FAILED( rv))
01226               return( rv);
01227        rv = spec->FromFileSpec( pRoot);
01228        if (NS_FAILED( rv))
01229               return( rv);
01230        rv = NS_NewISupportsArray( ppArray);
01231        if (NS_FAILED( rv)) {
01232               IMPORT_LOG0( "FAILED to allocate the nsISupportsArray\n");
01233               return( rv);
01234        }
01235               
01236        nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
01237        if (NS_FAILED( rv))
01238               return( rv);
01239        
01240        
01241        nsString             displayName;
01242        nsEudoraStringBundle::GetStringByID( EUDORAIMPORT_NICKNAMES_NAME, displayName);
01243        PRUint32             sz = 0;
01244        
01245        // First find the Nicknames file itself
01246        rv = spec->AppendRelativeUnixPath( "Eudora Nicknames");
01247        PRBool exists = PR_FALSE;
01248        PRBool isFile = PR_FALSE;
01249        if (NS_SUCCEEDED( rv))
01250               rv = spec->Exists( &exists);
01251        if (NS_SUCCEEDED( rv) && exists)
01252               rv = spec->IsFile( &isFile);
01253 
01254        nsCOMPtr<nsIImportABDescriptor>    desc;
01255        nsISupports *                             pInterface;
01256        
01257        if (exists && isFile) {
01258               rv = impSvc->CreateNewABDescriptor( getter_AddRefs( desc));
01259               if (NS_SUCCEEDED( rv)) {
01260                      sz = 0;
01261                      spec->GetFileSize( &sz);    
01262                      desc->SetPreferredName( displayName.get());
01263                      desc->SetSize( sz);
01264                      nsIFileSpec *pSpec = nsnull;
01265                      desc->GetFileSpec( &pSpec);
01266                      if (pSpec) {
01267                             pSpec->FromFileSpec( spec);
01268                             NS_RELEASE( pSpec);
01269                      }
01270                      rv = desc->QueryInterface( kISupportsIID, (void **) &pInterface);
01271                      (*ppArray)->AppendElement( pInterface);
01272                      pInterface->Release();
01273               }
01274               if (NS_FAILED( rv)) {
01275                      IMPORT_LOG0( "*** Error creating address book descriptor for eudora nicknames\n");
01276                      return( rv);
01277               }
01278        }
01279        
01280        // Now try the directory of address books!
01281        rv = spec->FromFileSpec( pRoot);
01282        if (NS_SUCCEEDED( rv))
01283               rv = spec->AppendRelativeUnixPath( "Nicknames Folder");
01284        exists = PR_FALSE;
01285        PRBool isDir = PR_FALSE;
01286        if (NS_SUCCEEDED( rv))
01287               rv = spec->Exists( &exists);
01288        if (NS_SUCCEEDED( rv) && exists)
01289               rv = spec->IsDirectory( &isDir);
01290        
01291        if (!isDir)
01292               return( NS_OK);      
01293        
01294        // We need to iterate the directory
01295        nsCOMPtr<nsIDirectoryIterator>     dir;
01296        rv = NS_NewDirectoryIterator( getter_AddRefs( dir));
01297        if (NS_FAILED( rv))
01298               return( rv);
01299 
01300        exists = PR_FALSE;
01301        rv = dir->Init( spec, PR_TRUE);
01302        if (NS_FAILED( rv))
01303               return( rv);
01304 
01305        rv = dir->Exists( &exists);
01306        if (NS_FAILED( rv))
01307               return( rv);
01308        
01309        char *                             pName;
01310        nsFileSpec                         fSpec;
01311        OSType                             type;
01312        OSType                             creator;
01313        
01314        while (exists && NS_SUCCEEDED( rv)) {
01315               rv = dir->GetCurrentSpec( getter_AddRefs( spec));
01316               if (NS_SUCCEEDED( rv)) {
01317                      isFile = PR_FALSE;
01318                      pName = nsnull;
01319                      rv = spec->IsFile( &isFile);
01320                      rv = spec->GetLeafName( &pName);
01321                      if (pName)    {
01322                             NS_CopyNativeToUnicode(nsDependentCString(pName), displayName);
01323                             nsCRT::free( pName);
01324                      }
01325                      if (NS_SUCCEEDED( rv) && pName && isFile) {
01326                             rv = spec->GetFileSpec( &fSpec);
01327                             if (NS_SUCCEEDED( rv)) {
01328                                    type = 0;
01329                                    creator = 0;
01330 #ifdef XP_MACOSX
01331   {
01332     nsCOMPtr<nsILocalFileMac> macFile;
01333     rv = NS_FileSpecToILocalFileMac(&fSpec, getter_AddRefs(macFile));
01334     if (NS_SUCCEEDED(rv))
01335     {
01336       macFile->GetFileCreator(&creator);
01337       macFile->GetFileType(&type);
01338     }
01339   }
01340 #else
01341                                    fSpec.GetFileTypeAndCreator( &type, &creator);
01342 #endif
01343                                    if (type == 'TEXT') {
01344                                           rv = impSvc->CreateNewABDescriptor( getter_AddRefs( desc));
01345                                           if (NS_SUCCEEDED( rv)) {
01346                                                  sz = 0;
01347                                                  spec->GetFileSize( &sz);    
01348                                                  desc->SetPreferredName( displayName.get());
01349                                                  desc->SetSize( sz);
01350                                                  nsIFileSpec *pSpec = nsnull;
01351                                                  desc->GetFileSpec( &pSpec);
01352                                                  if (pSpec) {
01353                                                         pSpec->FromFileSpec( spec);
01354                                                         NS_RELEASE( pSpec);
01355                                                  }
01356                                                  rv = desc->QueryInterface( kISupportsIID, (void **) &pInterface);
01357                                                  (*ppArray)->AppendElement( pInterface);
01358                                                  pInterface->Release();
01359                                           }
01360                                           if (NS_FAILED( rv)) {
01361                                                  IMPORT_LOG0( "*** Error creating address book descriptor for eudora address book\n");
01362                                                  return( rv);
01363                                           }
01364                                    }
01365                             }
01366                      }                           
01367               }
01368 
01369               rv = dir->Next();
01370               if (NS_SUCCEEDED( rv))
01371                      rv = dir->Exists( &exists);
01372        }
01373 
01374        
01375        return( rv);
01376 }
01377