コード例 #1
0
NS_IMETHODIMP
nsConverterInputStream::ReadLine(nsAString& aLine, PRBool* aResult)
{
  if (!mLineBuffer) {
    nsresult rv = NS_InitLineBuffer(&mLineBuffer);
    if (NS_FAILED(rv)) return rv;
  }
  return NS_ReadLine(this, mLineBuffer, aLine, aResult);
}
コード例 #2
0
ファイル: nsMsgSendPart.cpp プロジェクト: vanto/comm-central
int 
nsMsgSendPart::Write()
{
  int     status = 0;
  char    *separator = nsnull;
  bool    needToWriteCRLFAfterEncodedBody  = false;

#define PUSHLEN(str, length)                  \
  do {                            \
    status = mime_write_message_body(m_state, str, length); \
    if (status < 0) goto FAIL;                \
  } while (0)                         \

#define PUSH(str) PUSHLEN(str, PL_strlen(str))

  // rhp: Suppress the output of parts that are empty!
  if ( (m_parent) &&
       (m_numchildren == 0) &&
       ( (!m_buffer) || (!*m_buffer) ) &&
       (!m_file) &&
       (!m_mainpart) )
    return SKIP_EMPTY_PART;

  if (m_mainpart && m_type && PL_strcmp(m_type, TEXT_HTML) == 0) 
  {     
    if (m_file) 
    {
      // The "insert HTML links" code requires a memory buffer,
      // so read the file into memory.
      NS_ASSERTION(m_buffer == nsnull, "not-null buffer");
      PRInt32           length = 0;
      PRInt64 fileSize;
      if (NS_SUCCEEDED(m_file->GetFileSize(&fileSize)))
          length = fileSize;
      
      m_buffer = (char *) PR_Malloc(sizeof(char) * (length + 1));
      if (m_buffer) 
      {
        nsCOMPtr<nsIInputStream> inputFile;
        nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inputFile), m_file);
        if (NS_SUCCEEDED(rv)) 
        {
          PRUint32 bytesRead;
          rv = inputFile->Read(m_buffer, length, &bytesRead);
          inputFile->Close();
          m_buffer[length] = '\0';
        }
        else 
          PR_Free(m_buffer);
      }
    }
  }
  
  if (m_parent && m_parent->m_type &&
        !PL_strcasecmp(m_parent->m_type, MULTIPART_DIGEST) &&
        m_type &&
        (!PL_strcasecmp(m_type, MESSAGE_RFC822) ||
        !PL_strcasecmp(m_type, MESSAGE_NEWS))) 
  {
    // If we're in a multipart/digest, and this document is of type
    // message/rfc822, then it's appropriate to emit no headers.
    //
  }
  else 
  {
    char *message_headers = 0;
    char *content_headers = 0;
    char *content_type_header = 0;
    status = divide_content_headers(m_other,
                                    &message_headers,
                                    &content_headers,
                                    &content_type_header);
    if (status < 0)
      goto FAIL;
    
      /* First, write out all of the headers that refer to the message
      itself (From, Subject, MIME-Version, etc.)
    */
    if (message_headers) 
    {
      PUSH(message_headers);
      PR_Free(message_headers);
      message_headers = 0;
    }

    /* Now allow the crypto library to (potentially) insert some text
       (it may want to wrap the body in an envelope.)           */
    if (!m_parent) {
      status = m_state->BeginCryptoEncapsulation();
      if (status < 0) goto FAIL;
    }
          
    /* Now make sure there's a Content-Type header.
    */
    if (!content_type_header) 
    {
      NS_ASSERTION(m_type && *m_type, "null ptr");
      bool needsCharset = mime_type_needs_charset(m_type ? m_type : TEXT_PLAIN);
      if (needsCharset) 
      {
        content_type_header = PR_smprintf("Content-Type: %s; charset=%s" CRLF,
                                          (m_type ? m_type : TEXT_PLAIN), m_charset_name);
      }
      else
        content_type_header = PR_smprintf("Content-Type: %s" CRLF,
                                          (m_type ? m_type : TEXT_PLAIN));
      if (!content_type_header) 
      {
        if (content_headers)
          PR_Free(content_headers);
        status = NS_ERROR_OUT_OF_MEMORY;
        goto FAIL;
      }
    }
    
    /* If this is a compound object, tack a boundary string onto the
    Content-Type header. this
    */
    if (m_numchildren > 0)
    {
      int L;
      char *ct2;
      NS_ASSERTION(m_type, "null ptr");

      if (!separator)
      {
        separator = mime_make_separator("");
        if (!separator)
        {
          status = NS_ERROR_OUT_OF_MEMORY;
          goto FAIL;
        }
      }

      L = PL_strlen(content_type_header);
      
      if (content_type_header[L-1] == '\n')
        content_type_header[--L] = 0;
      if (content_type_header[L-1] == '\r')
        content_type_header[--L] = 0;
      
      ct2 = PR_smprintf("%s;\r\n boundary=\"%s\"" CRLF, content_type_header, separator);
      PR_Free(content_type_header);
      if (!ct2) 
      {
        if (content_headers)
          PR_Free(content_headers);
        status = NS_ERROR_OUT_OF_MEMORY;
        goto FAIL;
      }
      
      content_type_header = ct2;
    }
    
    // Now write out the Content-Type header...
    NS_ASSERTION(content_type_header && *content_type_header, "null ptr");
    PUSH(content_type_header);
    PR_Free(content_type_header);
    content_type_header = 0;
    
    /* ...followed by all of the other headers that refer to the body of
    the message (Content-Transfer-Encoding, Content-Dispositon, etc.)
    */
    if (content_headers) 
    {
      PUSH(content_headers);
      PR_Free(content_headers);
      content_headers = 0;
    }
  }

  PUSH(CRLF);         // A blank line, to mark the end of headers.

  m_firstBlock = true;
  /* only convert if we need to tag charset */
  m_needIntlConversion = mime_type_needs_charset(m_type);
  
  if (m_buffer) 
  {
    status = PushBody(m_buffer, PL_strlen(m_buffer));
    if (status < 0)
      goto FAIL;
  }
  else if (m_file) 
  {
    nsCOMPtr<nsIInputStream> inputStream;
    nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), m_file);
    if (NS_FAILED(rv))
    {
      // mysteriously disappearing?
      nsCOMPtr<nsIMsgSendReport> sendReport;
      m_state->GetSendReport(getter_AddRefs(sendReport));
      if (sendReport)
      {
        nsAutoString error_msg;
        nsMsgBuildMessageWithTmpFile(m_file, error_msg);
        sendReport->SetMessage(nsIMsgSendReport::process_Current, error_msg.get(), false);
      }
      status = NS_MSG_UNABLE_TO_OPEN_TMP_FILE;
      goto FAIL;
    }

    nsCString curLine;
    bool more = true;

    /* Kludge to avoid having to allocate memory on the toy computers... */
    if (!mime_mailto_stream_read_buffer) 
    {
      mime_mailto_stream_read_buffer = (char *) PR_Malloc(MIME_BUFFER_SIZE);
      if (!mime_mailto_stream_read_buffer) 
      {
        status = NS_ERROR_OUT_OF_MEMORY;
        goto FAIL;
      }
    }

    char    *buffer = mime_mailto_stream_read_buffer;
    if (m_strip_sensitive_headers) 
    {
      // We are attaching a message, so we should be careful to
      // strip out certain sensitive internal header fields.
      bool skipping = false;
      nsLineBuffer<char> *lineBuffer;
      
      rv = NS_InitLineBuffer(&lineBuffer);
      NS_ENSURE_SUCCESS(rv, rv);

      while (more) 
      {
        // NS_ReadLine doesn't return line termination chars.
        rv = NS_ReadLine(inputStream.get(), lineBuffer, curLine, &more);
      
        curLine.Append(CRLF);
        
        char *line = (char *) curLine.get();
        if (skipping) {
          if (*line == ' ' || *line == '\t')
            continue;
          else
            skipping = false;
        }
                
        if (!PL_strncasecmp(line, "From -", 6) ||
            !PL_strncasecmp(line, "BCC:", 4) ||
            !PL_strncasecmp(line, "FCC:", 4) ||
            !PL_strncasecmp(line, CONTENT_LENGTH ":", CONTENT_LENGTH_LEN+1) ||
            !PL_strncasecmp(line, "Lines:", 6) ||
            !PL_strncasecmp(line, "Status:", 7) ||
            !PL_strncasecmp(line, X_MOZILLA_STATUS ":", X_MOZILLA_STATUS_LEN+1) ||
            !PL_strncasecmp(line, X_MOZILLA_STATUS2 ":", X_MOZILLA_STATUS2_LEN+1) ||
            !PL_strncasecmp(line, X_MOZILLA_DRAFT_INFO ":", X_MOZILLA_DRAFT_INFO_LEN+1) ||
            !PL_strncasecmp(line, X_MOZILLA_NEWSHOST ":", X_MOZILLA_NEWSHOST_LEN+1) ||
            !PL_strncasecmp(line, X_UIDL ":", X_UIDL_LEN+1) ||
            !PL_strncasecmp(line, "X-VM-", 5)) /* hi Kyle */
        {
          skipping = true;
          continue;
        }
        
        PUSH(line);
        
        if (curLine.Length() == 2) {
          nsCOMPtr <nsISeekableStream> seekableStream = do_QueryInterface(inputStream);
          // seek back the amount of data left in the line buffer...
          seekableStream->Seek(nsISeekableStream::NS_SEEK_CUR, lineBuffer->start - lineBuffer->end);
          break;  // Now can do normal reads for the body.
        }
      }
      PR_Free(lineBuffer);
    }

    while (status >= 0) 
    {
      PRUint32 bytesRead;
      nsresult rv = inputStream->Read(buffer, MIME_BUFFER_SIZE, &bytesRead);
      if (NS_FAILED(rv))
      {  
        nsCOMPtr<nsIMsgSendReport> sendReport;
        m_state->GetSendReport(getter_AddRefs(sendReport));
        if (sendReport)
        {
          nsAutoString error_msg;
          nsMsgBuildMessageWithFile(m_file, error_msg);
          sendReport->SetMessage(nsIMsgSendReport::process_Current, error_msg.get(), false);
          status = NS_MSG_UNABLE_TO_OPEN_FILE;
          goto FAIL;
        }
      }
      status = PushBody(buffer, bytesRead);
      if (status < 0)
        goto FAIL;
      if (bytesRead < MIME_BUFFER_SIZE)
        break;
    }
  }
  
  if (m_encoder_data) 
  {
    status = MIME_EncoderDestroy(m_encoder_data, false);
    m_encoder_data = nsnull;
    needToWriteCRLFAfterEncodedBody = !m_parent;
    if (status < 0)
      goto FAIL;
  }
  
  // 
  // Ok, from here we loop and drive the the output of all children 
  // for this message.
  //
  if (m_numchildren > 0) 
  {
    bool    writeSeparator = true;

    for (int i = 0 ; i < m_numchildren ; i ++) 
    {
      if (writeSeparator)
      {
        PUSH(CRLF);
        PUSH("--");

        PUSH(separator);
        PUSH(CRLF);
      }

      status = m_children[i]->Write();
      if (status < 0)
        goto FAIL;

      if (status == SKIP_EMPTY_PART)
        writeSeparator = false;
      else
        writeSeparator = true;
    }

    PUSH(CRLF);
    PUSH("--");
    PUSH(separator);
    PUSH("--");
    PUSH(CRLF);
  }
  else if (needToWriteCRLFAfterEncodedBody)
    PUSH(CRLF);
  
FAIL:
  PR_FREEIF(separator);
  return status;
}
コード例 #3
0
NS_IMETHODIMP nsMsgBrkMBoxStore::ChangeKeywords(nsIArray *aHdrArray,
                                             const nsACString &aKeywords,
                                             bool aAdd)
{
  NS_ENSURE_ARG_POINTER(aHdrArray);
  nsCOMPtr<nsIOutputStream> outputStream;
  nsCOMPtr<nsISeekableStream> seekableStream;
  int64_t restoreStreamPos;

  uint32_t messageCount;
  nsresult rv = aHdrArray->GetLength(&messageCount);
  NS_ENSURE_SUCCESS(rv, rv);
  if (!messageCount)
    return NS_ERROR_INVALID_ARG;

  rv = GetOutputStream(aHdrArray, outputStream, seekableStream,
                       restoreStreamPos);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIInputStream> inputStream = do_QueryInterface(outputStream, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsLineBuffer<char> *lineBuffer;
  rv = NS_InitLineBuffer(&lineBuffer);
  NS_ENSURE_SUCCESS(rv, rv);

  // For each message, we seek to the beginning of the x-mozilla-status header,
  // and start reading lines, looking for x-mozilla-keys: headers; If we're
  // adding the keyword and we find
  // a header with the desired keyword already in it, we don't need to
  // do anything. Likewise, if removing keyword and we don't find it,
  // we don't need to do anything. Otherwise, if adding, we need to
  // see if there's an x-mozilla-keys
  // header with room for the new keyword. If so, we replace the
  // corresponding number of spaces with the keyword. If no room,
  // we can't do anything until the folder is compacted and another
  // x-mozilla-keys header is added. In that case, we set a property
  // on the header, which the compaction code will check.

  nsTArray<nsCString> keywordArray;
  ParseString(aKeywords, ' ', keywordArray);

  nsCOMPtr<nsIMsgDBHdr> msgHdr;
  for (uint32_t i = 0; i < messageCount; ++i) // for each message
  {
    msgHdr = do_QueryElementAt(aHdrArray, i, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    uint64_t messageOffset;
    msgHdr->GetMessageOffset(&messageOffset);
    uint32_t statusOffset = 0;
    (void)msgHdr->GetStatusOffset(&statusOffset);
    uint64_t desiredOffset = messageOffset + statusOffset;

    ChangeKeywordsHelper(msgHdr, desiredOffset, lineBuffer, keywordArray,
                         aAdd, outputStream, seekableStream, inputStream);
  }
  PR_Free(lineBuffer);
  if (restoreStreamPos != -1)
    seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, restoreStreamPos);
  else if (outputStream)
    outputStream->Close();
  if (messageCount > 0)
  {
    msgHdr = do_QueryElementAt(aHdrArray, 0);
    SetDBValid(msgHdr);
  }
  return NS_OK;
}