Пример #1
0
NS_IMETHODIMP nsMailDatabase::DeleteMessages(nsTArray<nsMsgKey>* nsMsgKeys, nsIDBChangeListener *instigator)
{
  nsresult rv;
  if (!m_folderStream && m_folder)
  {
    PRBool isLocked;
    m_folder->GetLocked(&isLocked);
    if (isLocked)
    {
      NS_ASSERTION(PR_FALSE, "Some other operation is in progress");
      return NS_MSG_FOLDER_BUSY;
    }
    rv = MsgGetFileStream(m_folderFile, getter_AddRefs(m_folderStream));
    NS_ENSURE_SUCCESS(rv, rv);
    m_ownFolderStream = PR_TRUE;
  }

  rv = nsMsgDatabase::DeleteMessages(nsMsgKeys, instigator);
  if (m_ownFolderStream)//only if we own the stream, then we should close it
  {
    if (m_folderStream)
    {
      m_folderStream->Flush(); // this does a sync
      m_folderStream->Close();
    }
    m_folderStream = nsnull;
    m_ownFolderStream = PR_FALSE;
  }

  SetFolderInfoValid(m_folderFile, 0, 0);
  return rv;
}
// get output stream from header
nsresult
nsMsgMaildirStore::GetOutputStream(nsIMsgDBHdr *aHdr,
                                   nsCOMPtr<nsIOutputStream> &aOutputStream)
{
  // file name is stored in message header property "storeToken"
  nsAutoCString fileName;
  aHdr->GetStringProperty("storeToken", getter_Copies(fileName));
  if (fileName.IsEmpty())
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIMsgFolder> folder;
  nsresult rv = aHdr->GetFolder(getter_AddRefs(folder));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIFile> folderPath;
  rv = folder->GetFilePath(getter_AddRefs(folderPath));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIFile> maildirFile;
  folderPath->Clone(getter_AddRefs(maildirFile));
  maildirFile->Append(NS_LITERAL_STRING("cur"));
  maildirFile->AppendNative(fileName);

  return MsgGetFileStream(maildirFile, getter_AddRefs(aOutputStream));
}
Пример #3
0
NS_IMETHODIMP nsMailDatabase::GetFolderStream(nsIOutputStream **aFileStream)
{
  NS_ENSURE_ARG_POINTER(aFileStream);
  if (!m_folderStream)
  {
    nsresult rv = MsgGetFileStream(m_folderFile, getter_AddRefs(m_folderStream));
    NS_ENSURE_SUCCESS(rv, rv);
    m_ownFolderStream = PR_TRUE;
  }
  
  NS_IF_ADDREF(*aFileStream = m_folderStream);
  return NS_OK;
}
Пример #4
0
// cache m_folderStream to make updating mozilla status flags fast
NS_IMETHODIMP nsMailDatabase::StartBatch()
{
  if (!m_folderStream && m_folder)  //only if we create a stream, set m_ownFolderStream to true.
  {
    PRBool isLocked;
    m_folder->GetLocked(&isLocked);
    if (isLocked)
    {
      NS_ASSERTION(PR_FALSE, "Some other operation is in progress");
      return NS_MSG_FOLDER_BUSY;
    }
    nsresult rv = MsgGetFileStream(m_folderFile, getter_AddRefs(m_folderStream));
    NS_ENSURE_SUCCESS(rv, rv);
    m_ownFolderStream = PR_TRUE;
  }

  return NS_OK;
}
Пример #5
0
nsresult
nsMsgBrkMBoxStore::GetOutputStream(nsIArray *aHdrArray,
                                   nsCOMPtr<nsIOutputStream> &outputStream,
                                   nsCOMPtr<nsISeekableStream> &seekableStream,
                                   int64_t &restorePos)
{
  nsresult rv;
  nsCOMPtr<nsIMsgDBHdr> msgHdr = do_QueryElementAt(aHdrArray, 0, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  nsCOMPtr<nsIMsgFolder> folder;
  msgHdr->GetFolder(getter_AddRefs(folder));
  NS_ENSURE_SUCCESS(rv, rv);
  nsCString URI;
  folder->GetURI(URI);
  restorePos = -1;
  if (m_outputStreams.Get(URI, getter_AddRefs(outputStream)))
  {
    seekableStream = do_QueryInterface(outputStream);
    rv = seekableStream->Tell(&restorePos);
    if (NS_FAILED(rv))
    {
      outputStream = nullptr;
      m_outputStreams.Remove(URI);
    }
  }
  nsCOMPtr<nsIFile> mboxFile;
  folder->GetFilePath(getter_AddRefs(mboxFile));
  if (!outputStream)
  {
    rv = MsgGetFileStream(mboxFile, getter_AddRefs(outputStream));
    seekableStream = do_QueryInterface(outputStream);
    if (NS_SUCCEEDED(rv))
      m_outputStreams.Put(URI, outputStream);
  }
  return rv;
}
NS_IMETHODIMP
nsPop3Sink::IncorporateBegin(const char* uidlString,
                             nsIURI* aURL,
                             uint32_t flags,
                             void** closure)
{
#ifdef DEBUG
    printf("Incorporate message begin:\n");
    if (uidlString)
        printf("uidl string: %s\n", uidlString);
#endif
  nsCOMPtr<nsIFile> path;

  m_folder->GetFilePath(getter_AddRefs(path));

  nsresult rv;
  nsCOMPtr<nsIPrefBranch> pPrefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
  if (pPrefBranch)
  {
    nsCOMPtr<nsIMsgIncomingServer> server;
    m_folder->GetServer(getter_AddRefs(server));
    nsCString plugStoreContract;
    server->GetCharValue("storeContractID", plugStoreContract);
    // Maildir doesn't care about quaranting, but other stores besides berkeley
    // mailbox might. We should probably make this an attribute on the pluggable
    // store, though.
    if (plugStoreContract.Equals(
          NS_LITERAL_CSTRING("@mozilla.org/msgstore/berkeleystore;1")))
      pPrefBranch->GetBoolPref("mailnews.downloadToTempFile", &m_downloadingToTempFile);
  }

  nsCOMPtr<nsIMsgDBHdr> newHdr;

  nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_popServer);
  if (!server)
    return NS_ERROR_UNEXPECTED;

  if (m_downloadingToTempFile)
  {
    // need to create an nsIOFileStream from a temp file...
    nsCOMPtr<nsIFile> tmpDownloadFile;
    rv = GetSpecialDirectoryWithFileName(NS_OS_TEMP_DIR,
                                         "newmsg",
                                         getter_AddRefs(tmpDownloadFile));

    NS_ASSERTION(NS_SUCCEEDED(rv),
                 "writing tmp pop3 download file: failed to append filename");
    if (NS_FAILED(rv))
      return rv;

    if (!m_tmpDownloadFile)
    {
      //need a unique tmp file to prevent dataloss in multiuser environment
      rv = tmpDownloadFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 00600);
      NS_ENSURE_SUCCESS(rv, rv);

      m_tmpDownloadFile = do_QueryInterface(tmpDownloadFile, &rv);
    }
    if (NS_SUCCEEDED(rv))
    {
      rv = MsgGetFileStream(m_tmpDownloadFile, getter_AddRefs(m_outFileStream));
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }
  else
  {
    rv = server->GetMsgStore(getter_AddRefs(m_msgStore));
    bool reusable;
    NS_ENSURE_SUCCESS(rv, rv);
    m_msgStore->GetNewMsgOutputStream(m_folder, getter_AddRefs(newHdr),
                                      &reusable, getter_AddRefs(m_outFileStream));
  }
  // The following (!m_outFileStream etc) was added to make sure that we don't
  // write somewhere where for some reason or another we can't write to and
  // lose the messages. See bug 62480
  if (!m_outFileStream)
      return NS_ERROR_OUT_OF_MEMORY;

  nsCOMPtr<nsISeekableStream> seekableOutStream = do_QueryInterface(m_outFileStream);

  // create a new mail parser
  if (!m_newMailParser)
    m_newMailParser = new nsParseNewMailState;
  NS_ENSURE_TRUE(m_newMailParser, NS_ERROR_OUT_OF_MEMORY);
  if (m_uidlDownload)
    m_newMailParser->DisableFilters();

  nsCOMPtr <nsIMsgFolder> serverFolder;
  rv = GetServerFolder(getter_AddRefs(serverFolder));
  if (NS_FAILED(rv)) return rv;

  rv = m_newMailParser->Init(serverFolder, m_folder,
                             m_window, newHdr, m_outFileStream);
  // If we failed to initialize the parser, then just don't use it!!!
  // We can still continue without one.

  if (NS_FAILED(rv))
  {
    m_newMailParser = nullptr;
    rv = NS_OK;
  }

    if (closure)
        *closure = (void*) this;

    nsCString outputString(GetDummyEnvelope());
    rv = WriteLineToMailbox(outputString);
    NS_ENSURE_SUCCESS(rv, rv);
    // Write out account-key before UIDL so the code that looks for
    // UIDL will find the account first and know it can stop looking
    // once it finds the UIDL line.
    if (!m_accountKey.IsEmpty())
    {
      outputString.AssignLiteral(HEADER_X_MOZILLA_ACCOUNT_KEY ": ");
      outputString.Append(m_accountKey);
      outputString.AppendLiteral(MSG_LINEBREAK);
      rv = WriteLineToMailbox(outputString);
      NS_ENSURE_SUCCESS(rv, rv);
    }
    if (uidlString)
    {
      outputString.AssignLiteral("X-UIDL: ");
      outputString.Append(uidlString);
      outputString.AppendLiteral(MSG_LINEBREAK);
      rv = WriteLineToMailbox(outputString);
      NS_ENSURE_SUCCESS(rv, rv);
    }

    // WriteLineToMailbox("X-Mozilla-Status: 8000" MSG_LINEBREAK);
    char *statusLine = PR_smprintf(X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, flags);
    outputString.Assign(statusLine);
    rv = WriteLineToMailbox(outputString);
    PR_smprintf_free(statusLine);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = WriteLineToMailbox(NS_LITERAL_CSTRING("X-Mozilla-Status2: 00000000" MSG_LINEBREAK));
    NS_ENSURE_SUCCESS(rv, rv);

    // leave space for 60 bytes worth of keys/tags
    rv = WriteLineToMailbox(NS_LITERAL_CSTRING(X_MOZILLA_KEYWORDS));
    return NS_OK;
}
Пример #7
0
NS_IMETHODIMP
nsMsgBrkMBoxStore::GetNewMsgOutputStream(nsIMsgFolder *aFolder,
                                         nsIMsgDBHdr **aNewMsgHdr,
                                         bool *aReusable,
                                         nsIOutputStream **aResult)
{
  NS_ENSURE_ARG_POINTER(aFolder);
  NS_ENSURE_ARG_POINTER(aNewMsgHdr);
  NS_ENSURE_ARG_POINTER(aReusable);
  NS_ENSURE_ARG_POINTER(aResult);

#ifdef _DEBUG
  NS_ASSERTION(m_streamOutstandingFolder != aFolder, "didn't finish prev msg");
  m_streamOutstandingFolder = aFolder;
#endif
  *aReusable = true;
  nsCOMPtr<nsIFile> mboxFile;
  aFolder->GetFilePath(getter_AddRefs(mboxFile));
  nsCOMPtr<nsIMsgDatabase> db;
  aFolder->GetMsgDatabase(getter_AddRefs(db));
  if (!db && !*aNewMsgHdr)
    NS_WARNING("no db, and no message header");
  bool exists;
  mboxFile->Exists(&exists);
  if (!exists)
    mboxFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);

  nsCString URI;
  aFolder->GetURI(URI);
  nsresult rv;
  nsCOMPtr<nsISeekableStream> seekable;
  if (m_outputStreams.Get(URI, aResult))
  {
    seekable = do_QueryInterface(*aResult, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
    if (NS_FAILED(rv))
    {
      m_outputStreams.Remove(URI);
      NS_RELEASE(*aResult);
    }
  }
  if (!*aResult)
  {
    rv = MsgGetFileStream(mboxFile, aResult);
    NS_ASSERTION(NS_SUCCEEDED(rv), "failed opening offline store for output");
    if (NS_FAILED(rv))
      printf("failed opening offline store for %s\n", URI.get());
    NS_ENSURE_SUCCESS(rv, rv);
    seekable = do_QueryInterface(*aResult, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
    NS_ENSURE_SUCCESS(rv, rv);
    m_outputStreams.Put(URI, *aResult);
  }
  int64_t filePos;
  seekable->Tell(&filePos);
  if (db && !*aNewMsgHdr)
  {
    // if mbox is close to 4GB, auto-assign the msg key.
    nsMsgKey key = filePos > 0xFFFFFF00 ? nsMsgKey_None : (nsMsgKey) filePos;
    db->CreateNewHdr(key, aNewMsgHdr);
  }
  if (*aNewMsgHdr)
  {
    char storeToken[100];
    PR_snprintf(storeToken, sizeof(storeToken), "%lld", filePos);
    (*aNewMsgHdr)->SetMessageOffset(filePos);
    (*aNewMsgHdr)->SetStringProperty("storeToken", storeToken);
  }
  return rv;
}
Пример #8
0
nsresult
nsMsgAttachmentHandler::ConvertToAppleEncoding(const nsCString &aFileURI, 
                                               const nsCString &aFilePath, 
                                               nsILocalFileMac *aSourceFile)
{
  // convert the apple file to AppleDouble first, and then patch the
  // address in the url.
  
  //We need to retrieve the file type and creator...

  char fileInfo[32];
  OSType type, creator;

  nsresult rv = aSourceFile->GetFileType(&type);
  if (NS_FAILED(rv))
    return false;
  PR_snprintf(fileInfo, sizeof(fileInfo), "%X", type);
  m_xMacType = fileInfo;

  rv = aSourceFile->GetFileCreator(&creator);
  if (NS_FAILED(rv))
    return false;
  PR_snprintf(fileInfo, sizeof(fileInfo), "%X", creator);
  m_xMacCreator = fileInfo;

  FSRef fsRef;
  aSourceFile->GetFSRef(&fsRef);
  bool sendResourceFork = HasResourceFork(&fsRef);

  // if we have a resource fork, check the filename extension, maybe we don't need the resource fork!
  if (sendResourceFork)
  {
    nsCOMPtr<nsIURL> fileUrl(do_CreateInstance(NS_STANDARDURL_CONTRACTID));
    if (fileUrl)
    {
      rv = fileUrl->SetSpec(aFileURI);
      if (NS_SUCCEEDED(rv))
      {
        nsCAutoString ext;
        rv = fileUrl->GetFileExtension(ext);
        if (NS_SUCCEEDED(rv) && !ext.IsEmpty())
        {
          sendResourceFork =
          PL_strcasecmp(ext.get(), "TXT") &&
          PL_strcasecmp(ext.get(), "JPG") &&
          PL_strcasecmp(ext.get(), "GIF") &&
          PL_strcasecmp(ext.get(), "TIF") &&
          PL_strcasecmp(ext.get(), "HTM") &&
          PL_strcasecmp(ext.get(), "HTML") &&
          PL_strcasecmp(ext.get(), "ART") &&
          PL_strcasecmp(ext.get(), "XUL") &&
          PL_strcasecmp(ext.get(), "XML") &&
          PL_strcasecmp(ext.get(), "CSS") &&
          PL_strcasecmp(ext.get(), "JS");
        }
      }
    }
  }

  // Only use appledouble if we aren't uuencoding.
  if( sendResourceFork )
  {
    char *separator;

    separator = mime_make_separator("ad");
    if (!separator)
      return NS_ERROR_OUT_OF_MEMORY;

    nsCOMPtr <nsIFile> tmpFile;
    nsresult rv = nsMsgCreateTempFile("appledouble", getter_AddRefs(tmpFile));
    if (NS_SUCCEEDED(rv))
      mEncodedWorkingFile = do_QueryInterface(tmpFile);
    if (!mEncodedWorkingFile)
    {
      PR_FREEIF(separator);
      return NS_ERROR_OUT_OF_MEMORY;
    }

    //
    // RICHIE_MAC - ok, here's the deal, we have a file that we need
    // to encode in appledouble encoding for the resource fork and put that
    // into the mEncodedWorkingFile location. Then, we need to patch the new file
    // spec into the array and send this as part of the 2 part appledouble/mime
    // encoded mime part.
    //
    AppleDoubleEncodeObject     *obj = new (AppleDoubleEncodeObject);
    if (obj == NULL)
    {
      mEncodedWorkingFile = nsnull;
      PR_FREEIF(separator);
      return NS_ERROR_OUT_OF_MEMORY;
    }

    rv = MsgGetFileStream(mEncodedWorkingFile, getter_AddRefs(obj->fileStream));
    if (NS_FAILED(rv) || !obj->fileStream)
    {
      PR_FREEIF(separator);
      delete obj;
      return NS_ERROR_OUT_OF_MEMORY;
    }

    PRInt32     bSize = AD_WORKING_BUFF_SIZE;

    char  *working_buff = nsnull;
    while (!working_buff && (bSize >= 512))
    {
      working_buff = (char *)PR_CALLOC(bSize);
      if (!working_buff)
        bSize /= 2;
    }

    if (!working_buff)
    {
      PR_FREEIF(separator);
      delete obj;
      return NS_ERROR_OUT_OF_MEMORY;
    }

    obj->buff = working_buff;
    obj->s_buff = bSize;

    //
    //  Setup all the need information on the apple double encoder.
    //
    ap_encode_init(&(obj->ap_encode_obj), aFilePath.get(), separator);

    PRInt32 count;

    nsresult status = noErr;
    m_size = 0;
    while (status == noErr)
    {
      status = ap_encode_next(&(obj->ap_encode_obj), obj->buff, bSize, &count);
      if (status == noErr || status == errDone)
      {
        //
        // we got the encode data, so call the next stream to write it to the disk.
        //
        PRUint32 bytesWritten;
        obj->fileStream->Write(obj->buff, count, &bytesWritten);
        if (bytesWritten != (PRUint32) count)
          status = NS_MSG_ERROR_WRITING_FILE;
      }
    }

    ap_encode_end(&(obj->ap_encode_obj), (status >= 0)); // if this is true, ok, false abort
    if (obj->fileStream)
      obj->fileStream->Close();

    PR_FREEIF(obj->buff);               /* free the working buff.   */
    PR_FREEIF(obj);

    nsCOMPtr <nsIURI> fileURI;
    NS_NewFileURI(getter_AddRefs(fileURI), mEncodedWorkingFile);

    nsCOMPtr<nsIFileURL> theFileURL = do_QueryInterface(fileURI, &rv);
    NS_ENSURE_SUCCESS(rv,rv);

    nsCString newURLSpec;
    NS_ENSURE_SUCCESS(rv, rv);
    fileURI->GetSpec(newURLSpec);

    if (newURLSpec.IsEmpty())
    {
      PR_FREEIF(separator);
      return NS_ERROR_OUT_OF_MEMORY;
    }

    if (NS_FAILED(nsMsgNewURL(getter_AddRefs(mURL), newURLSpec.get())))
    {
      PR_FREEIF(separator);
      return NS_ERROR_OUT_OF_MEMORY;
    }

    // Now after conversion, also patch the types.
    char        tmp[128];
    PR_snprintf(tmp, sizeof(tmp), MULTIPART_APPLEDOUBLE ";\r\n boundary=\"%s\"", separator);
    PR_FREEIF(separator);
    m_type = tmp;
  }
  else
  {
    if ( sendResourceFork )
    {
      // For now, just do the encoding, but in the old world we would ask the
      // user about doing this conversion
      printf("...we could ask the user about this conversion, but for now, nahh..\n");
    }

    bool      useDefault;
    char      *macType, *macEncoding;
    if (m_type.IsEmpty() || m_type.LowerCaseEqualsLiteral(TEXT_PLAIN))
    {
# define TEXT_TYPE  0x54455854  /* the characters 'T' 'E' 'X' 'T' */
# define text_TYPE  0x74657874  /* the characters 't' 'e' 'x' 't' */

      if (type != TEXT_TYPE && type != text_TYPE)
      {
        MacGetFileType(aSourceFile, &useDefault, &macType, &macEncoding);
        m_type = macType;
      }
    }
    // don't bother to set the types if we failed in getting the file info.
  }

  return NS_OK;
}
Пример #9
0
// We let the caller close the file in case he's updating a lot of flags
// and we don't want to open and close the file every time through.
// As an experiment, try caching the fid in the db as m_folderFile.
// If this is set, use it but don't return *pFid.
void nsMailDatabase::UpdateFolderFlag(nsIMsgDBHdr *mailHdr, PRBool bSet, 
							  MsgFlags flag, nsIOutputStream **ppFileStream)
{
  static char buf[50];
  PRInt64 folderStreamPos = 0; //saves the folderStream pos in case we are sharing the stream with other code
  nsIOutputStream *fileStream = (m_folderStream) ? m_folderStream.get() : *ppFileStream;
  PRUint32 offset;
  (void)mailHdr->GetStatusOffset(&offset);
  nsCOMPtr <nsISeekableStream> seekableStream;
  
  nsresult rv;
  
  if (offset > 0) 
  {
    
    if (fileStream == NULL) 
    {
      rv = MsgGetFileStream(m_folderFile, &fileStream);
      if (NS_FAILED(rv))
        return;
      seekableStream = do_QueryInterface(fileStream);
    }
    else if (!m_ownFolderStream)
    {
      m_folderStream->Flush();
      seekableStream = do_QueryInterface(fileStream);
      seekableStream->Tell(&folderStreamPos);
    }
    else
      seekableStream = do_QueryInterface(m_folderStream);
      
    if (fileStream) 
    {
      PRUint32 msgOffset;
      (void)mailHdr->GetMessageOffset(&msgOffset);
      PRUint32 statusPos = offset + msgOffset;
      PR_ASSERT(offset < 10000);
      seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, statusPos);
      buf[0] = '\0';
      nsCOMPtr <nsIInputStream> inputStream = do_QueryInterface(fileStream);
      PRUint32 bytesRead;
      if (NS_SUCCEEDED(inputStream->Read(buf, X_MOZILLA_STATUS_LEN + 6, &bytesRead)))
      {
        buf[bytesRead] = '\0';
        if (strncmp(buf, X_MOZILLA_STATUS, X_MOZILLA_STATUS_LEN) == 0 &&
          strncmp(buf + X_MOZILLA_STATUS_LEN, ": ", 2) == 0 &&
          strlen(buf) >= X_MOZILLA_STATUS_LEN + 6) 
        {
          PRUint32 flags;
          PRUint32 bytesWritten;
          (void)mailHdr->GetFlags(&flags);
          if (!(flags & MSG_FLAG_EXPUNGED))
          {
            int i;
            char *p = buf + X_MOZILLA_STATUS_LEN + 2;
            
            for (i=0, flags = 0; i<4; i++, p++)
            {
              flags = (flags << 4) | msg_UnHex(*p);
            }
            
            PRUint32 curFlags;
            (void)mailHdr->GetFlags(&curFlags);
            flags = (flags & MSG_FLAG_QUEUED) |
              (curFlags & ~MSG_FLAG_RUNTIME_ONLY);
          }
          else
          {
            flags &= ~MSG_FLAG_RUNTIME_ONLY;
          }
          seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, statusPos);
          // We are filing out x-mozilla-status flags here
          PR_snprintf(buf, sizeof(buf), X_MOZILLA_STATUS_FORMAT,
            flags & 0x0000FFFF);
          PRInt32 lineLen = PL_strlen(buf);
          PRUint32 status2Pos = statusPos + lineLen + MSG_LINEBREAK_LEN;
          fileStream->Write(buf, lineLen, &bytesWritten);
          
          // time to upate x-mozilla-status2
          seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, status2Pos);
          if (NS_SUCCEEDED(inputStream->Read(buf, X_MOZILLA_STATUS2_LEN + 10, &bytesRead)))
          {
            if (strncmp(buf, X_MOZILLA_STATUS2, X_MOZILLA_STATUS2_LEN) == 0 &&
              strncmp(buf + X_MOZILLA_STATUS2_LEN, ": ", 2) == 0 &&
              strlen(buf) >= X_MOZILLA_STATUS2_LEN + 10) 
            {
              PRUint32 dbFlags;
              (void)mailHdr->GetFlags(&dbFlags);
              dbFlags &= 0xFFFF0000;
              seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, status2Pos);
              PR_snprintf(buf, sizeof(buf), X_MOZILLA_STATUS2_FORMAT, dbFlags);
              fileStream->Write(buf, PL_strlen(buf), &bytesWritten);
            }
          }
        } else 
        {
#ifdef DEBUG
          printf("Didn't find %s where expected at position %ld\n"
            "instead, found %s.\n",
            X_MOZILLA_STATUS, (long) statusPos, buf);
#endif
          SetReparse(PR_TRUE);
        }			
      } 
      else 
      {
#ifdef DEBUG
        printf("Couldn't read old status line at all at position %ld\n",
          (long) statusPos);
#endif
        SetReparse(PR_TRUE);
      }
    }
    else
    {
#ifdef DEBUG
      nsCString folderPath;
      m_folderFile->GetNativePath(folderPath);
      printf("Couldn't open mail folder for update%s!\n",
        folderPath.get());
#endif
      PR_ASSERT(PR_FALSE);
    }
  }
  if (!m_folderStream)
    *ppFileStream = fileStream; // This tells the caller that we opened the file, and please to close it.
  else if (!m_ownFolderStream)
    seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, folderStreamPos);
}