Ejemplo n.º 1
0
nsresult
nsMovemailService::GetNewMail(nsIMsgWindow *aMsgWindow,
                              nsIUrlListener *aUrlListener,
                              nsIMsgFolder *aMsgFolder,
                              nsIMovemailIncomingServer *movemailServer,
                              nsIURI ** aURL)
{
  LOG(("nsMovemailService::GetNewMail"));
  nsresult rv = NS_OK;

  nsCOMPtr<nsIMsgIncomingServer> in_server =
      do_QueryInterface(movemailServer);
  if (!in_server)
      return NS_MSG_INVALID_OR_MISSING_SERVER;
  mMsgWindow = aMsgWindow;

  // Attempt to locate the mail spool file
  nsCAutoString spoolPath;
  rv = LocateSpoolFile(spoolPath);
  if (NS_FAILED(rv) || spoolPath.IsEmpty()) {
    Error(MOVEMAIL_SPOOL_FILE_NOT_FOUND, nsnull, 0);
    return NS_ERROR_FAILURE;
  }

  // Create an input stream for the spool file
  nsCOMPtr<nsILocalFile> spoolFile;
  rv = NS_NewNativeLocalFile(spoolPath, true, getter_AddRefs(spoolFile));
  NS_ENSURE_SUCCESS(rv, rv);
  nsCOMPtr<nsIInputStream> spoolInputStream;
  rv = NS_NewLocalFileInputStream(getter_AddRefs(spoolInputStream), spoolFile);
  if (NS_FAILED(rv)) {
    const PRUnichar *params[] = {
      NS_ConvertUTF8toUTF16(spoolPath).get()
    };
    Error(MOVEMAIL_CANT_OPEN_SPOOL_FILE, params, 1);
    return rv;
  }

  // Get a line input interface for the spool file
  nsCOMPtr<nsILineInputStream> lineInputStream =
    do_QueryInterface(spoolInputStream, &rv);
  if (!lineInputStream)
    return rv;

  nsCOMPtr<nsIMsgFolder> serverFolder;
  nsCOMPtr<nsIMsgFolder> inbox;
  nsCOMPtr<nsIMsgFolder> rootMsgFolder;

  rv = in_server->GetRootFolder(getter_AddRefs(serverFolder));
  NS_ENSURE_SUCCESS(rv, rv);

  rootMsgFolder = do_QueryInterface(serverFolder, &rv);
  if (!rootMsgFolder)
    return rv;
  rv = rootMsgFolder->GetFolderWithFlags(nsMsgFolderFlags::Inbox,
                                         getter_AddRefs(inbox));

  NS_ENSURE_TRUE(inbox, NS_ERROR_FAILURE);
  nsCOMPtr <nsIOutputStream> outputStream;
  nsCOMPtr<nsIMsgPluggableStore> msgStore;
  rv = in_server->GetMsgStore(getter_AddRefs(msgStore));
  NS_ENSURE_SUCCESS(rv, rv);
  bool reusable;
  nsCOMPtr<nsIMsgDBHdr> newHdr;
  msgStore->GetNewMsgOutputStream(inbox, getter_AddRefs(newHdr),
                                  &reusable, getter_AddRefs(outputStream));
  NS_ENSURE_SUCCESS(rv, rv);
  nsCOMPtr <nsIInputStream> inputStream = do_QueryInterface(outputStream);
  // create a new mail parser
  nsRefPtr<nsParseNewMailState> newMailParser = new nsParseNewMailState;
  NS_ENSURE_TRUE(newMailParser, NS_ERROR_OUT_OF_MEMORY);

  rv = newMailParser->Init(serverFolder, inbox,
                           nsnull, newHdr, outputStream);
  NS_ENSURE_SUCCESS(rv, rv);

  in_server->SetServerBusy(true);

  // Try and obtain the lock for the spool file
  bool usingLockFile;
  if (!ObtainSpoolLock(spoolPath.get(), 5, &usingLockFile)) {
    nsAutoString lockFile = NS_ConvertUTF8toUTF16(spoolPath);
    lockFile.AppendLiteral(".lock");
    const PRUnichar *params[] = {
      lockFile.get()
    };
    Error(MOVEMAIL_CANT_CREATE_LOCK, params, 1);
    return NS_ERROR_FAILURE;
  }

  // MIDDLE of the FUN : consume the mailbox data.
  bool isMore = true;
  nsCAutoString buffer;
  PRUint32 bytesWritten;

  while (isMore &&
         NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore)))
  {

    // If first string is empty and we're now at EOF then abort parsing.
    if (buffer.IsEmpty() && !isMore) {
      LOG(("Empty spool file"));
      break;
    }

    buffer += MSG_LINEBREAK;

    newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length());
    outputStream->Write(buffer.get(), buffer.Length(), &bytesWritten);

    // 'From' lines delimit messages
    if (isMore && !strncmp(buffer.get(), "From ", 5)) {
      buffer.AssignLiteral("X-Mozilla-Status: 8000" MSG_LINEBREAK);
      newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length());
      outputStream->Write(buffer.get(), buffer.Length(), &bytesWritten);
      buffer.AssignLiteral("X-Mozilla-Status2: 00000000" MSG_LINEBREAK);
      newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length());
      outputStream->Write(buffer.get(), buffer.Length(), &bytesWritten);
    }
  }

  outputStream->Flush();
  newMailParser->OnStopRequest(nsnull, nsnull, NS_OK);
  msgStore->FinishNewMessage(outputStream, newHdr);
  outputStream->Close();

  // Truncate the spool file
  rv = spoolFile->SetFileSize(0);
  if (NS_FAILED(rv)) {
    const PRUnichar *params[] = {
      NS_ConvertUTF8toUTF16(spoolPath).get()
    };
    Error(MOVEMAIL_CANT_TRUNCATE_SPOOL_FILE, params, 1);
  }

  if (!YieldSpoolLock(spoolPath.get(), usingLockFile)) {
    nsAutoString spoolLock = NS_ConvertUTF8toUTF16(spoolPath);
    spoolLock.AppendLiteral(".lock");
    const PRUnichar *params[] = {
      spoolLock.get()
    };
    Error(MOVEMAIL_CANT_DELETE_LOCK, params, 1);
  }

  in_server->SetServerBusy(false);

  LOG(("GetNewMail returning rv=%d", rv));
  return rv;
}
Ejemplo n.º 2
0
nsresult
nsMovemailService::GetNewMail(nsIMsgWindow *aMsgWindow,
                              nsIUrlListener *aUrlListener,
                              nsIMsgFolder *aMsgFolder,
                              nsIMovemailIncomingServer *movemailServer,
                              nsIURI ** aURL)
{
    LOG(("nsMovemailService::GetNewMail"));
    nsresult rv = NS_OK;

    nsCOMPtr<nsIMsgIncomingServer> in_server =
        do_QueryInterface(movemailServer);
    if (!in_server)
        return NS_MSG_INVALID_OR_MISSING_SERVER;
    mMsgWindow = aMsgWindow;

    // Attempt to locate the mail spool file
    nsCAutoString spoolPath;
    rv = LocateSpoolFile(spoolPath);
    if (NS_FAILED(rv) || spoolPath.IsEmpty()) {
        Error(MOVEMAIL_SPOOL_FILE_NOT_FOUND, nsnull, 0);
        return NS_ERROR_FAILURE;
    }

    // Create an input stream for the spool file
    nsCOMPtr<nsILocalFile> spoolFile;
    rv = NS_NewNativeLocalFile(spoolPath, PR_TRUE, getter_AddRefs(spoolFile));
    NS_ENSURE_SUCCESS(rv, rv);
    nsCOMPtr<nsIInputStream> spoolInputStream;
    rv = NS_NewLocalFileInputStream(getter_AddRefs(spoolInputStream), spoolFile);
    if (NS_FAILED(rv)) {
        const PRUnichar *params[] = {
            NS_ConvertUTF8toUCS2(spoolPath).get()
        };
        Error(MOVEMAIL_CANT_OPEN_SPOOL_FILE, params, 1);
        return rv;
    }

    // Get a line input interface for the spool file
    nsCOMPtr<nsILineInputStream> lineInputStream =
        do_QueryInterface(spoolInputStream, &rv);
    if (!lineInputStream)
        return rv;

    nsCOMPtr<nsIFileSpec> mailDirectory;
    rv = in_server->GetLocalPath(getter_AddRefs(mailDirectory));
    NS_ENSURE_SUCCESS(rv, rv);

    nsFileSpec fileSpec;
    mailDirectory->GetFileSpec(&fileSpec);
    fileSpec += "Inbox";
    nsIOFileStream outFileStream(fileSpec);
    outFileStream.seek(fileSpec.GetFileSize());
    nsCOMPtr<nsIMsgFolder> serverFolder;
    nsCOMPtr<nsIMsgFolder> inbox;
    nsCOMPtr<nsIMsgFolder> rootMsgFolder;
        
    // create a new mail parser
    nsRefPtr<nsParseNewMailState> newMailParser = new nsParseNewMailState;
    if (newMailParser == nsnull)
        return NS_ERROR_OUT_OF_MEMORY;

    rv = in_server->GetRootFolder(getter_AddRefs(serverFolder));
    NS_ENSURE_SUCCESS(rv, rv);

    rootMsgFolder = do_QueryInterface(serverFolder, &rv);
    if (!rootMsgFolder)
        return rv;
    PRUint32 numFolders;
    rv = rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, 1,
                                           &numFolders,
                                           getter_AddRefs(inbox));
    NS_ENSURE_SUCCESS(rv, rv);
    rv = newMailParser->Init(serverFolder, inbox, 
                             fileSpec, &outFileStream, nsnull, PR_FALSE);
    NS_ENSURE_SUCCESS(rv, rv);

    in_server->SetServerBusy(PR_TRUE);

    // Try and obtain the lock for the spool file
    if (!ObtainSpoolLock(spoolPath.get(), 5)) {
        nsAutoString lockFile = NS_ConvertUTF8toUCS2(spoolPath);
        lockFile.AppendLiteral(".lock");
        const PRUnichar *params[] = {
            lockFile.get()
        };
        Error(MOVEMAIL_CANT_CREATE_LOCK, params, 1);
        return NS_ERROR_FAILURE;
    }
            
    // MIDDLE of the FUN : consume the mailbox data.
    PRBool isMore = PR_TRUE;
    nsCAutoString buffer;

    while (isMore &&
           NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore)))
    {

        // If first string is empty and we're now at EOF then abort parsing.
        if (buffer.IsEmpty() && !isMore) {
            LOG(("Empty spool file"));
            break;
        }

        buffer += MSG_LINEBREAK;

        newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length());
        outFileStream << buffer.get();

        // 'From' lines delimit messages
        if (isMore && !strncmp(buffer.get(), "From ", 5)) {
            buffer.AssignLiteral("X-Mozilla-Status: 8000" MSG_LINEBREAK);
            newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length());
            outFileStream << buffer.get();
            buffer.AssignLiteral("X-Mozilla-Status2: 00000000" MSG_LINEBREAK);
            newMailParser->HandleLine(buffer.BeginWriting(), buffer.Length());
            outFileStream << buffer.get();
        }
    }

    outFileStream.flush();
    newMailParser->OnStopRequest(nsnull, nsnull, NS_OK);
    newMailParser->SetDBFolderStream(nsnull); // stream is going away
    if (outFileStream.is_open())
        outFileStream.close();

    // Truncate the spool file
    rv = spoolFile->SetFileSize(0);
    if (NS_FAILED(rv)) {
        const PRUnichar *params[] = {
            NS_ConvertUTF8toUCS2(spoolPath).get()
        };
        Error(MOVEMAIL_CANT_TRUNCATE_SPOOL_FILE, params, 1);
    }

    if (!YieldSpoolLock(spoolPath.get())) {
        nsAutoString spoolLock = NS_ConvertUTF8toUCS2(spoolPath);
        spoolLock.AppendLiteral(".lock");
        const PRUnichar *params[] = {
            spoolLock.get()
        };
        Error(MOVEMAIL_CANT_DELETE_LOCK, params, 1);
    }

    in_server->SetServerBusy(PR_FALSE);

    LOG(("GetNewMail returning rv=%d", rv));
    return rv;
}