示例#1
0
void OESettings::SetIdentities(nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc,
                               HKEY hKey, char *pIncomgUserName,
                               PRInt32 authMethodIncoming, bool isNNTP)
{
  // Get the relevant information for an identity
  char *pSmtpServer = (char *)nsOERegUtil::GetValueBytes(hKey, "SMTP Server");
  char *pName = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Display Name" : "SMTP Display Name");
  char *pEmail = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Email Address" : "SMTP Email Address");
  char *pReply = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Reply To Email Address" : "SMTP Reply To Email Address");
  char *pOrgName = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Organization Name" : "SMTP Organization Name");

  nsresult rv;

    nsCOMPtr<nsIMsgIdentity> id;
    rv = pMgr->CreateIdentity(getter_AddRefs(id));
    if (id) {
      nsAutoString fullName, organization;
      rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
                                     nsCString(pName), fullName);
      if (NS_SUCCEEDED(rv))
        id->SetFullName(fullName);
// BUG 470587. Don't set this: id->SetIdentityName(fullName);

      rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
                                     nsCString(pOrgName), organization);
      if (NS_SUCCEEDED(rv))
        id->SetOrganization(organization);

      id->SetEmail(nsCString(pEmail));
      if (pReply)
        id->SetReplyTo(nsCString(pReply));

      // Outlook Express users are used to top style quoting.
      id->SetReplyOnTop(isNNTP ? 0 : 1);
      pAcc->AddIdentity(id);

      IMPORT_LOG0("Created identity and added to the account\n");
      IMPORT_LOG1("\tname: %s\n", pName);
      IMPORT_LOG1("\temail: %s\n", pEmail);
    }

  if (!isNNTP)  // NNTP does not use SMTP in OE or TB
    SetSmtpServer(pSmtpServer, hKey, id, pIncomgUserName, authMethodIncoming);

  nsOERegUtil::FreeValueBytes((BYTE *)pName);
  nsOERegUtil::FreeValueBytes((BYTE *)pSmtpServer);
  nsOERegUtil::FreeValueBytes((BYTE *)pEmail);
  nsOERegUtil::FreeValueBytes((BYTE *)pReply);
}
示例#2
0
void nsOutlookMail::BuildAttachments( CMapiMessage& msg, int count)
{
  EmptyAttachments();
  if (count) {
    nsresult rv;
    nsCOMPtr <nsILocalFile>  pFile;
    for (int i = 0; i < count; i++) {
      if (!msg.GetAttachmentInfo( i)) {
        IMPORT_LOG1( "*** Error getting attachment info for #%d\n", i);
      }

      pFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
      if (NS_FAILED( rv) || !pFile) {
        IMPORT_LOG0( "*** Error creating file spec for attachment\n");
      }
      else {
        if (msg.GetAttachFileLoc( pFile)) {
          PRBool isFile = PR_FALSE;
          PRBool exists = PR_FALSE;
          pFile->Exists( &exists);
          pFile->IsFile( &isFile);

          if (!exists || !isFile) {
            IMPORT_LOG0( "Attachment file does not exist\n");
          }
          else {
            // We have a file spec, now get the other info
            OutlookAttachment *a = new OutlookAttachment;
            a->mimeType = strdup( msg.GetMimeType());
            // Init description here so that we cacn tell
            // if defaul tattacchment is needed later.
            a->description = nsnull;

            const char *fileName = msg.GetFileName();
            if (fileName && fileName[0]) {
              // Convert description to unicode.
              nsAutoString description;
              rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
                nsDependentCString(fileName), description);
              NS_ASSERTION(NS_SUCCEEDED(rv), "failed to convert system string to unicode");
              if (NS_SUCCEEDED(rv))
                a->description = ToNewUTF8String(description);
            }

            // If no description use "Attachment i" format.
            if (!a->description) {
              nsCAutoString  str("Attachment ");
              str.AppendInt( (PRInt32) i);
              a->description = ToNewCString( str);
            }

            a->pAttachment = pFile;
            m_attachments.AppendElement( a);
          }
        }
      }
    }
  }
}
示例#3
0
nsresult OESettings::GetAccountName(HKEY hKey, char *defaultName, nsString &acctName)
{
  BYTE *pAccName = nsOERegUtil::GetValueBytes(hKey, "Account Name");
  nsresult rv = NS_OK;
  if (pAccName) {
    rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
                                   nsDependentCString((const char *)pAccName), acctName);
    nsOERegUtil::FreeValueBytes(pAccName);
  }
  else
    acctName.AssignASCII(defaultName);
  return rv;
}
示例#4
0
void CMapiMessageHeaders::CHeaderField::GetUnfoldedString(nsString& dest,
                                          const char* fallbackCharset) const
{
  dest.Truncate();
  if (!m_fbody)
    return;

  nsCString unfolded;
  const char* pos = m_fbody;
  while (*pos) {
    if ((*pos == nsCRT::CR) && (*(pos+1) == nsCRT::LF) && IsWSP(*(pos+2)))
      pos += 2; // Skip CRLF if it is followed by SPACE or TAB
    else
      unfolded.Append(*(pos++));
  }
  if (m_fbody_utf8)
    CopyUTF8toUTF16(unfolded, dest);
  else
    nsMsgI18NConvertToUnicode(fallbackCharset, unfolded, dest);
}
示例#5
0
static int
MimeInlineTextPlainFlowed_parse_line (const char *aLine, PRInt32 length, MimeObject *obj)
{
  int status;
  PRBool quoting = ( obj->options
    && ( obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting ||
         obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting
       )           );  // see above
  PRBool plainHTML = quoting || (obj->options &&
       obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs);
       // see above

  struct MimeInlineTextPlainFlowedExData *exdata;
  exdata = MimeInlineTextPlainFlowedExDataList;
  while(exdata && (exdata->ownerobj != obj)) {
    exdata = exdata->next;
  }

  NS_ASSERTION(exdata, "The extra data has disappeared!");

  NS_ASSERTION(length > 0, "zero length");
  if (length <= 0) return 0;

  uint32 linequotelevel = 0;
  nsCAutoString real_line(aLine, length);
  char *line = real_line.BeginWriting();
  const char *linep = real_line.BeginReading();
  // Space stuffed?
  if(' ' == *linep) {
    linep++;
  } else {
    // count '>':s before the first non-'>'
    while('>' == *linep) {
      linep++;
      linequotelevel++;
    }
    // Space stuffed?
    if(' ' == *linep) {
      linep++;
    }
  }

  // Look if the last character (after stripping ending end
  // of lines and quoting stuff) is a SPACE. If it is, we are looking at a
  // flowed line. Normally we assume that the last two chars
  // are CR and LF as said in RFC822, but that doesn't seem to
  // be the case always.
  PRBool flowed = PR_FALSE;
  PRBool sigSeparator = PR_FALSE;
  PRInt32 index = length-1;
  while(index >= 0 && ('\r' == line[index] || '\n' == line[index])) {
    index--;
  }
  if (index > linep - line && ' ' == line[index])
       /* Ignore space stuffing, i.e. lines with just
          (quote marks and) a space count as empty */
  {
    flowed = PR_TRUE;
    sigSeparator = (index - (linep - line) + 1 == 3) && !strncmp(linep, "-- ", 3);
    if (((MimeInlineTextPlainFlowed *) obj)->delSp && ! sigSeparator)
       /* If line is flowed and DelSp=yes, logically
          delete trailing space. Line consisting of
          dash dash space ("-- "), commonly used as
          signature separator, gets special handling
          (RFC 3676) */
    {
      length--;
      line[index] = '\0';
    }
  }

  mozITXTToHTMLConv *conv = GetTextConverter(obj->options);

  PRBool skipConversion = !conv ||
                          (obj->options && obj->options->force_user_charset);

  nsAutoString lineSource;
  nsString lineResult;

  char *mailCharset = NULL;
  nsresult rv;

  if (!skipConversion)
  {
    // Convert only if the source string is not empty
    if (length - (linep - line) > 0)
    {
      PRBool whattodo = obj->options->whattodo;
      if (plainHTML)
      {
        if (quoting)
          whattodo = 0;
        else
          whattodo = whattodo & ~mozITXTToHTMLConv::kGlyphSubstitution;
                    /* Do recognition for the case, the result is viewed in
                        Mozilla, but not GlyphSubstitution, because other UAs
                        might not be able to display the glyphs. */
      }

      const nsDependentCSubstring& inputStr = Substring(linep, linep + (length - (linep - line)));

      // For 'SaveAs', |line| is in |mailCharset|.
      // convert |line| to UTF-16 before 'html'izing (calling ScanTXT())
      if (obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs)
      {
        // Get the mail charset of this message.
        MimeInlineText  *inlinetext = (MimeInlineText *) obj;
        if (!inlinetext->initializeCharset)
          ((MimeInlineTextClass*)&mimeInlineTextClass)->initialize_charset(obj);
        mailCharset = inlinetext->charset;
        if (mailCharset && *mailCharset) {
          rv = nsMsgI18NConvertToUnicode(mailCharset, PromiseFlatCString(inputStr), lineSource);
          NS_ENSURE_SUCCESS(rv, -1);
        }
        else // this probably never happens...
          CopyUTF8toUTF16(inputStr, lineSource);
      }
      else   // line is in UTF-8
        CopyUTF8toUTF16(inputStr, lineSource);

      // This is the main TXT to HTML conversion:
      // escaping (very important), eventually recognizing etc.
      rv = conv->ScanTXT(lineSource.get(), whattodo, getter_Copies(lineResult));
      NS_ENSURE_SUCCESS(rv, -1);
    }
  }
  else
  {
    CopyUTF8toUTF16(nsDependentCString(line, length), lineResult);
    status = NS_OK;
  }

  nsCAutoString preface;

  /* Correct number of blockquotes */
  int32 quoteleveldiff=linequotelevel - exdata->quotelevel;
  if((quoteleveldiff != 0) && flowed && exdata->inflow) {
    // From RFC 2646 4.5
    // The receiver SHOULD handle this error by using the 'quote-depth-wins' rule,
    // which is to ignore the flowed indicator and treat the line as fixed.  That
    // is, the change in quote depth ends the paragraph.

    // We get that behaviour by just going on.
  }
  while(quoteleveldiff>0) {
    quoteleveldiff--;
    preface += "<blockquote type=cite";
    // This is to have us observe the user pref settings for citations
    MimeInlineTextPlainFlowed *tObj = (MimeInlineTextPlainFlowed *) obj;

    nsCAutoString style;
    MimeTextBuildPrefixCSS(tObj->mQuotedSizeSetting, tObj->mQuotedStyleSetting,
                           tObj->mCitationColor, style);
    if (!plainHTML && !style.IsEmpty())
    {
      preface += " style=\"";
      preface += style;
      preface += '"';
    }
    preface += '>';
  }
  while(quoteleveldiff<0) {
    quoteleveldiff++;
    preface += "</blockquote>";
  }
  exdata->quotelevel = linequotelevel;

  nsAutoString lineResult2;

  if(flowed) {
    // Check RFC 2646 "4.3. Usenet Signature Convention": "-- "+CRLF is
    // not a flowed line
    if (sigSeparator)
    {
      if (linequotelevel > 0 || exdata->isSig)
      {
        preface += "--&nbsp;<br>";
      } else {
        exdata->isSig = PR_TRUE;
        preface += "<div class=\"moz-txt-sig\"><span class=\"moz-txt-tag\">"
                   "--&nbsp;<br></span>";
      }
    } else {
      Line_convert_whitespace(lineResult, PR_FALSE /* Allow wraps */,
                              lineResult2);
    }

    exdata->inflow=PR_TRUE;
  } else {
    // Fixed paragraph.
    Line_convert_whitespace(lineResult,
                            !plainHTML && !obj->options->wrap_long_lines_p
                              /* If wrap, convert all spaces but the last in
                                 a row into nbsp, otherwise all. */,
                            lineResult2);
    lineResult2.AppendLiteral("<br>");
    exdata->inflow = PR_FALSE;
  } // End Fixed line

  if (!(exdata->isSig && quoting))
  {
    status = MimeObject_write(obj, preface.get(), preface.Length(), PR_TRUE);
    if (status < 0) return status;
    nsCAutoString outString;
    if (obj->options->format_out != nsMimeOutput::nsMimeMessageSaveAs ||
        !mailCharset || !*mailCharset)
      CopyUTF16toUTF8(lineResult2, outString);
    else
    { // convert back to mailCharset before writing.
      rv = nsMsgI18NConvertFromUnicode(mailCharset, lineResult2, outString);
      NS_ENSURE_SUCCESS(rv, -1);
    }
    status = MimeObject_write(obj, outString.get(), outString.Length(), PR_TRUE);
    return status;
  }
  else
    return NS_OK;
}
示例#6
0
static int
MimeInlineTextPlain_parse_line (char *line, PRInt32 length, MimeObject *obj)
{
  int status;
  PRBool quoting = ( obj->options
    && ( obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting ||
         obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting
       )           );  // see above
  PRBool plainHTML = quoting || (obj->options &&
       obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs);
       // see above

  PRBool rawPlainText = obj->options &&
       (obj->options->format_out == nsMimeOutput::nsMimeMessageFilterSniffer
       || obj->options->format_out == nsMimeOutput::nsMimeMessageAttach);

  // this routine gets called for every line of data that comes through the
  // mime converter. It's important to make sure we are efficient with 
  // how we allocate memory in this routine. be careful if you go to add
  // more to this routine.

  NS_ASSERTION(length > 0, "zero length");
  if (length <= 0) return 0;

  mozITXTToHTMLConv *conv = GetTextConverter(obj->options);
  MimeInlineTextPlain *text = (MimeInlineTextPlain *) obj;

  PRBool skipConversion = !conv || rawPlainText ||
                          (obj->options && obj->options->force_user_charset);

  char *mailCharset = NULL;
  nsresult rv;

  // if this part has a name and it's not a message/rfc822, don't quote
  if (quoting && obj->headers && MimeHeaders_get_name(obj->headers, obj->options) 
      && PL_strcasecmp(obj->content_type, MESSAGE_RFC822))
    return 0;

  if (!skipConversion)
  {
    nsDependentCString inputStr(line, length);
    nsAutoString lineSourceStr;

    // For 'SaveAs', |line| is in |mailCharset|.
    // convert |line| to UTF-16 before 'html'izing (calling ScanTXT())
    if (obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs)
    { // Get the mail charset of this message.
      MimeInlineText  *inlinetext = (MimeInlineText *) obj;
      if (!inlinetext->initializeCharset)
         ((MimeInlineTextClass*)&mimeInlineTextClass)->initialize_charset(obj);
      mailCharset = inlinetext->charset;
      if (mailCharset && *mailCharset) {
        rv = nsMsgI18NConvertToUnicode(mailCharset, inputStr, lineSourceStr);
        NS_ENSURE_SUCCESS(rv, -1);
      }
      else // this probably never happens ...
        CopyUTF8toUTF16(inputStr, lineSourceStr);
    }
    else  // line is in UTF-8
      CopyUTF8toUTF16(inputStr, lineSourceStr);

    nsCAutoString prefaceResultStr;  // Quoting stuff before the real text

    // Recognize quotes
    PRUint32 oldCiteLevel = text->mCiteLevel;
    PRUint32 logicalLineStart = 0;
    rv = conv->CiteLevelTXT(lineSourceStr.get(),
                            &logicalLineStart, &(text->mCiteLevel));
    NS_ENSURE_SUCCESS(rv, -1);

    // Find out, which recognitions to do
    PRBool whattodo = obj->options->whattodo;
    if (plainHTML)
    {
      if (quoting)
        whattodo = 0;  // This is done on Send. Don't do it twice.
      else
        whattodo = whattodo & ~mozITXTToHTMLConv::kGlyphSubstitution;
                   /* Do recognition for the case, the result is viewed in
                      Mozilla, but not GlyphSubstitution, because other UAs
                      might not be able to display the glyphs. */
      if (!text->mBlockquoting)
        text->mCiteLevel = 0;
    }

    // Write blockquote
    if (text->mCiteLevel > oldCiteLevel)
    {
      prefaceResultStr += "</pre>";
      for (PRUint32 i = 0; i < text->mCiteLevel - oldCiteLevel; i++)
      {
        nsCAutoString style;
        MimeTextBuildPrefixCSS(text->mQuotedSizeSetting, text->mQuotedStyleSetting,
                               text->mCitationColor, style);
        if (!plainHTML && !style.IsEmpty())
        {
          prefaceResultStr += "<blockquote type=cite style=\"";
          prefaceResultStr += style;
          prefaceResultStr += "\">";
        }
        else
          prefaceResultStr += "<blockquote type=cite>";
      }
      prefaceResultStr += "<pre wrap>";
    }
    else if (text->mCiteLevel < oldCiteLevel)
    {
      prefaceResultStr += "</pre>";
      for (PRUint32 i = 0; i < oldCiteLevel - text->mCiteLevel; i++)
        prefaceResultStr += "</blockquote>";
      prefaceResultStr += "<pre wrap>";
      if (text->mCiteLevel == 0)
        prefaceResultStr += "<!---->";   /* Make sure, NGLayout puts out
                                            a linebreak */
    }

    // Write plain text quoting tags
    if (logicalLineStart != 0 && !(plainHTML && text->mBlockquoting))
    {
      if (!plainHTML)
        prefaceResultStr += "<span class=\"moz-txt-citetags\">";

      nsAutoString citeTagsSource;
      lineSourceStr.Mid(citeTagsSource, 0, logicalLineStart);

      // Convert to HTML
      nsXPIDLString citeTagsResultUnichar;
      rv = conv->ScanTXT(citeTagsSource.get(), 0 /* no recognition */,
                         getter_Copies(citeTagsResultUnichar));
      if (NS_FAILED(rv)) return -1;

      AppendUTF16toUTF8(citeTagsResultUnichar, prefaceResultStr);
      if (!plainHTML)
        prefaceResultStr += "</span>";
    }


    // recognize signature
    if ((lineSourceStr.Length() >= 4)
        && lineSourceStr.First() == '-'
        && Substring(lineSourceStr, 0, 3).EqualsLiteral("-- ")
        && (lineSourceStr[3] == '\r' || lineSourceStr[3] == '\n') )
    {
      text->mIsSig = PR_TRUE;
      if (!quoting)
        prefaceResultStr += "<div class=\"moz-txt-sig\">";
    }


    /* This is the main TXT to HTML conversion:
       escaping (very important), eventually recognizing etc. */
    nsXPIDLString lineResultUnichar;

    rv = conv->ScanTXT(lineSourceStr.get() + logicalLineStart,
                       whattodo, getter_Copies(lineResultUnichar));
    NS_ENSURE_SUCCESS(rv, -1);

    if (!(text->mIsSig && quoting))
    {
      status = MimeObject_write(obj, prefaceResultStr.get(), prefaceResultStr.Length(), PR_TRUE);
      if (status < 0) return status;
      nsCAutoString outString;
      if (obj->options->format_out != nsMimeOutput::nsMimeMessageSaveAs ||
          !mailCharset || !*mailCharset)
        CopyUTF16toUTF8(lineResultUnichar, outString);
      else
      { // convert back to mailCharset before writing.       
        rv = nsMsgI18NConvertFromUnicode(mailCharset, 
                                         lineResultUnichar, outString);
        NS_ENSURE_SUCCESS(rv, -1);
      }

      status = MimeObject_write(obj, outString.get(), outString.Length(), PR_TRUE);
    }
    else
    {
      status = NS_OK;
    }
  }
  else
  {
    status = MimeObject_write(obj, line, length, PR_TRUE);
  }

  return status;
}
示例#7
0
NS_IMETHODIMP ImportAddressImpl::GetSampleData(PRInt32 index, bool *pFound, PRUnichar **pStr)
{
  NS_PRECONDITION(pFound != nsnull, "null ptr");
  NS_PRECONDITION(pStr != nsnull, "null ptr");
  if (!pFound || !pStr)
    return NS_ERROR_NULL_POINTER;

  if (!m_fileLoc) {
    IMPORT_LOG0("*** Error, called GetSampleData before SetSampleLocation\n");
    return NS_ERROR_FAILURE;
  }

  nsresult rv;
  *pStr = nsnull;
  PRUnichar term = 0;

  if (!m_haveDelim) {
    rv = m_text.DetermineDelim(m_fileLoc);
    NS_ENSURE_SUCCESS(rv, rv);
    m_haveDelim = true;
    m_delim = m_text.GetDelim();
  }

  bool fileExists;
  rv = m_fileLoc->Exists(&fileExists);
  NS_ENSURE_SUCCESS(rv, rv);

  if (!fileExists) {
    *pFound = false;
    *pStr = NS_strdup(&term);
    return NS_OK;
  }

  nsCString line;
  rv = nsTextAddress::ReadRecordNumber(m_fileLoc, line, index);
  if (NS_SUCCEEDED(rv)) {
    nsString str;
    nsCString field;
    nsString uField;
    PRInt32 fNum = 0;
    while (nsTextAddress::GetField(line.get(), line.Length(), fNum, field, m_delim)) {
      if (fNum)
        str.Append(PRUnichar('\n'));
      SanitizeSampleData(field);
      rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
                                     field, uField);

      str.Append(uField);
      fNum++;
      field.Truncate();
    }

    *pStr = ToNewUnicode(str);
    *pFound = true;

    /* IMPORT_LOG1("Sample data: %S\n", str.get()); */
  }
  else {
    *pFound = false;
    *pStr = NS_strdup(&term);
  }

  return NS_OK;
}
示例#8
0
void OutlookSettings::SetIdentities(nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, HKEY hKey)
{
  // Get the relevant information for an identity
  char *pName = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Display Name");
  char *pServer = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Server");
  char *pEmail = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Email Address");
  char *pReply = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Reply To Email Address");
  nsCString userName;
  userName.Adopt((char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP User Name"));
  char *pOrgName = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Organization Name");

  nsresult rv;

  if (pEmail && pName && pServer) {
    // The default identity, nor any other identities matched,
    // create a new one and add it to the account.
    nsCOMPtr<nsIMsgIdentity>  id;
    rv = pMgr->CreateIdentity(getter_AddRefs(id));
    if (id) {
      nsAutoString name, organization;
      rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
        nsDependentCString(pName), name);
      if (NS_SUCCEEDED(rv))
      {
        id->SetFullName(name);
        id->SetIdentityName(name);
      }

      if (pOrgName) {
        rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
          nsDependentCString(pOrgName), organization);
        if (NS_SUCCEEDED(rv))
          id->SetOrganization(organization);
      }

      id->SetEmail(nsDependentCString(pEmail));
      if (pReply)
        id->SetReplyTo(nsDependentCString(pReply));
      pAcc->AddIdentity(id);

      IMPORT_LOG0("Created identity and added to the account\n");
      IMPORT_LOG1("\tname: %s\n", pName);
      IMPORT_LOG1("\temail: %s\n", pEmail);
    }
  }

  if (userName.IsEmpty()) {
    nsCOMPtr <nsIMsgIncomingServer>  incomingServer;
    rv = pAcc->GetIncomingServer(getter_AddRefs(incomingServer));
    if (NS_SUCCEEDED(rv) && incomingServer)
      rv = incomingServer->GetUsername(userName);
    NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to get UserName from incomingServer");
  }

  SetSmtpServer(pMgr, pAcc, pServer, userName);

  nsOutlookRegUtil::FreeValueBytes((BYTE *)pName);
  nsOutlookRegUtil::FreeValueBytes((BYTE *)pServer);
  nsOutlookRegUtil::FreeValueBytes((BYTE *)pEmail);
  nsOutlookRegUtil::FreeValueBytes((BYTE *)pReply);
}
示例#9
0
nsresult nsMsgFilterList::LoadTextFilters(nsIInputStream *aStream)
{
  nsresult  err = NS_OK;
  uint64_t bytesAvailable;

  nsCOMPtr<nsIInputStream> bufStream;
  err = NS_NewBufferedInputStream(getter_AddRefs(bufStream), aStream, 10240);
  NS_ENSURE_SUCCESS(err, err);

  nsMsgFilterFileAttribValue attrib;
  nsCOMPtr<nsIMsgRuleAction> currentFilterAction;
  // We'd really like to move lot's of these into the objects that they refer to.
  do
  {
    nsAutoCString value;
    nsresult intToStringResult;

    char curChar;
    curChar = LoadAttrib(attrib, bufStream);
    if (curChar == (char) -1)  //reached eof
      break;
    err = LoadValue(value, bufStream);
    if (NS_FAILED(err))
      break;

    switch(attrib)
    {
    case nsIMsgFilterList::attribNone:
      if (m_curFilter)
        m_curFilter->SetUnparseable(true);
      break;
    case nsIMsgFilterList::attribVersion:
      m_fileVersion = value.ToInteger(&intToStringResult);
      if (NS_FAILED(intToStringResult))
      {
        attrib = nsIMsgFilterList::attribNone;
        NS_ASSERTION(false, "error parsing filter file version");
      }
      break;
    case nsIMsgFilterList::attribLogging:
      m_loggingEnabled = StrToBool(value);
      m_unparsedFilterBuffer.Truncate(); //we are going to buffer each filter as we read them, make sure no garbage is there
      m_startWritingToBuffer = true; //filters begin now
      break;
    case nsIMsgFilterList::attribName:  //every filter starts w/ a name
      {
        if (m_curFilter)
        {
          int32_t nextFilterStartPos = m_unparsedFilterBuffer.RFind("name");

          nsAutoCString nextFilterPart;
          nextFilterPart = Substring(m_unparsedFilterBuffer, nextFilterStartPos, m_unparsedFilterBuffer.Length());
          m_unparsedFilterBuffer.SetLength(nextFilterStartPos);

          bool unparseableFilter;
          m_curFilter->GetUnparseable(&unparseableFilter);
          if (unparseableFilter)
          {
            m_curFilter->SetUnparsedBuffer(m_unparsedFilterBuffer);
            m_curFilter->SetEnabled(false); //disable the filter because we don't know how to apply it
          }
          m_unparsedFilterBuffer = nextFilterPart;
        }
        nsMsgFilter *filter = new nsMsgFilter;
        if (filter == nullptr)
        {
          err = NS_ERROR_OUT_OF_MEMORY;
          break;
        }
        filter->SetFilterList(static_cast<nsIMsgFilterList*>(this));
        if (m_fileVersion == k45Version)
        {
          nsAutoString unicodeStr;
          err = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
                                          value, unicodeStr);
          if (NS_FAILED(err))
              break;

          filter->SetFilterName(unicodeStr);
        }
        else
        {
          // ### fix me - this is silly.
          PRUnichar *unicodeString =
            nsTextFormatter::smprintf(unicodeFormatter, value.get());
          filter->SetFilterName(nsDependentString(unicodeString));
          nsTextFormatter::smprintf_free(unicodeString);
        }
        m_curFilter = filter;
        m_filters.AppendElement(filter);
      }
      break;
    case nsIMsgFilterList::attribEnabled:
      if (m_curFilter)
        m_curFilter->SetEnabled(StrToBool(value));
      break;
    case nsIMsgFilterList::attribDescription:
      if (m_curFilter)
        m_curFilter->SetFilterDesc(value);
      break;
    case nsIMsgFilterList::attribType:
      if (m_curFilter)
      {
        // Older versions of filters didn't have the ability to turn on/off the
        // manual filter context, so default manual to be on in that case
        int32_t filterType = value.ToInteger(&intToStringResult);
        if (m_fileVersion < kManualContextVersion)
          filterType |= nsMsgFilterType::Manual;
        m_curFilter->SetType((nsMsgFilterTypeType) filterType);
      }
      break;
    case nsIMsgFilterList::attribScriptFile:
      if (m_curFilter)
        m_curFilter->SetFilterScript(&value);
      break;
    case nsIMsgFilterList::attribAction:
      if (m_curFilter)
      {
        nsMsgRuleActionType actionType = nsMsgFilter::GetActionForFilingStr(value);
        if (actionType == nsMsgFilterAction::None)
          m_curFilter->SetUnparseable(true);
        else
        {
          err = m_curFilter->CreateAction(getter_AddRefs(currentFilterAction));
          NS_ENSURE_SUCCESS(err, err);
          currentFilterAction->SetType(actionType);
          m_curFilter->AppendAction(currentFilterAction);
        }
      }
      break;
    case nsIMsgFilterList::attribActionValue:
      if (m_curFilter && currentFilterAction)
      {
        nsMsgRuleActionType type;
        currentFilterAction->GetType(&type);
        if (type == nsMsgFilterAction::MoveToFolder ||
              type == nsMsgFilterAction::CopyToFolder)
          err = m_curFilter->ConvertMoveOrCopyToFolderValue(currentFilterAction, value);
        else if (type == nsMsgFilterAction::ChangePriority)
        {
          nsMsgPriorityValue outPriority;
          nsresult res = NS_MsgGetPriorityFromString(value.get(), outPriority);
          if (NS_SUCCEEDED(res))
            currentFilterAction->SetPriority(outPriority);
          else
            NS_ASSERTION(false, "invalid priority in filter file");
        }
        else if (type == nsMsgFilterAction::Label)
        {
          // upgrade label to corresponding tag/keyword
          nsresult res;
          int32_t labelInt = value.ToInteger(&res);
          if (NS_SUCCEEDED(res))
          {
            nsAutoCString keyword("$label");
            keyword.Append('0' + labelInt);
            currentFilterAction->SetType(nsMsgFilterAction::AddTag);
            currentFilterAction->SetStrValue(keyword);
          }
        }
        else if (type == nsMsgFilterAction::JunkScore)
        {
          nsresult res;
          int32_t junkScore = value.ToInteger(&res);
          if (NS_SUCCEEDED(res))
            currentFilterAction->SetJunkScore(junkScore);
        }
        else if (type == nsMsgFilterAction::Forward ||
                 type == nsMsgFilterAction::Reply ||
                 type == nsMsgFilterAction::AddTag ||
                 type == nsMsgFilterAction::Custom)
        {
          currentFilterAction->SetStrValue(value);
        }
      }
      break;
    case nsIMsgFilterList::attribCondition:
      if (m_curFilter)
      {
        if (m_fileVersion == k45Version)
        {
          nsAutoString unicodeStr;
          err = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
                                          value, unicodeStr);
          if (NS_FAILED(err))
              break;

          char *utf8 = ToNewUTF8String(unicodeStr);
          value.Assign(utf8);
          nsMemory::Free(utf8);
        }
        err = ParseCondition(m_curFilter, value.get());
        if (err == NS_ERROR_INVALID_ARG)
          err = m_curFilter->SetUnparseable(true);
        NS_ENSURE_SUCCESS(err, err);
      }
      break;
    case nsIMsgFilterList::attribCustomId:
      if (m_curFilter && currentFilterAction)
      {
        err = currentFilterAction->SetCustomId(value);
        NS_ENSURE_SUCCESS(err, err);
      }
      break;

    }
  } while (NS_SUCCEEDED(bufStream->Available(&bytesAvailable)));

  if (m_curFilter)
  {
    bool unparseableFilter;
    m_curFilter->GetUnparseable(&unparseableFilter);
    if (unparseableFilter)
    {
      m_curFilter->SetUnparsedBuffer(m_unparsedFilterBuffer);
      m_curFilter->SetEnabled(false);  //disable the filter because we don't know how to apply it
    }
  }

  return err;
}
示例#10
0
static int
MimeMessage_close_headers (MimeObject *obj)
{
  MimeMessage *msg = (MimeMessage *) obj;
  int status = 0;
  char *ct = 0;      /* Content-Type header */
  MimeObject *body;

  // Do a proper decoding of the munged subject.
  if (obj->headers && msg->hdrs && msg->grabSubject && obj->headers->munged_subject) {
    // nsMsgI18NConvertToUnicode wants nsAStrings...
    nsDependentCString orig(obj->headers->munged_subject);
    nsAutoString dest;
    // First, get the Content-Type, then extract the charset="whatever" part of
    // it.
    nsCString charset;
    nsCString contentType;
    contentType.Adopt(MimeHeaders_get(msg->hdrs, HEADER_CONTENT_TYPE, false, false));
    if (!contentType.IsEmpty())
      charset.Adopt(MimeHeaders_get_parameter(contentType.get(), "charset", nullptr, nullptr));

    // If we've got a charset, use nsMsgI18NConvertToUnicode to magically decode
    // the munged subject.
    if (!charset.IsEmpty()) {
      nsresult rv = nsMsgI18NConvertToUnicode(charset.get(), orig, dest);
      // If we managed to convert the string, replace munged_subject with the
      // UTF8 version of it, otherwise, just forget about it (maybe there was an
      // improperly encoded string in there).
      PR_Free(obj->headers->munged_subject);
      if (NS_SUCCEEDED(rv))
        obj->headers->munged_subject = ToNewUTF8String(dest);
      else
        obj->headers->munged_subject = nullptr;
    } else {
      PR_Free(obj->headers->munged_subject);
      obj->headers->munged_subject = nullptr;
    }
  }

  if (msg->hdrs)
  {
    bool outer_p = !obj->headers; /* is this the outermost message? */


#ifdef MIME_DRAFTS
    if (outer_p &&
      obj->options &&
          (obj->options->decompose_file_p || obj->options->caller_need_root_headers) &&
      obj->options->decompose_headers_info_fn)
    {
#ifdef ENABLE_SMIME
      if (obj->options->decrypt_p && !mime_crypto_object_p (msg->hdrs, false))
        obj->options->decrypt_p = false;
#endif /* ENABLE_SMIME */
      if (!obj->options->caller_need_root_headers || (obj == obj->options->state->root))
        status = obj->options->decompose_headers_info_fn (
                         obj->options->stream_closure,
                               msg->hdrs );
    }
#endif /* MIME_DRAFTS */


    /* If this is the outermost message, we need to run the
     `generate_header' callback.  This happens here instead of
     in `parse_begin', because it's only now that we've parsed
     our headers.  However, since this is the outermost message,
     we have yet to write any HTML, so that's fine.
     */
    if (outer_p &&
      obj->output_p &&
      obj->options &&
      obj->options->write_html_p &&
      obj->options->generate_header_html_fn)
    {
      int lstatus = 0;
      char *html = 0;

      /* The generate_header_html_fn might return HTML, so it's important
       that the output stream be set up with the proper type before we
       make the MimeObject_write() call below. */
      if (!obj->options->state->first_data_written_p)
      {
        lstatus = MimeObject_output_init (obj, TEXT_HTML);
        if (lstatus < 0) return lstatus;
        PR_ASSERT(obj->options->state->first_data_written_p);
      }

      html = obj->options->generate_header_html_fn(NULL,
                           obj->options->html_closure,
                             msg->hdrs);
      if (html)
      {
        lstatus = MimeObject_write(obj, html, strlen(html), false);
        PR_Free(html);
        if (lstatus < 0) return lstatus;
      }
    }


    /* Find the content-type of the body of this message.
     */
    {
    bool ok = true;
    char *mv = MimeHeaders_get (msg->hdrs, HEADER_MIME_VERSION,
                  true, false);

#ifdef REQUIRE_MIME_VERSION_HEADER
    /* If this is the outermost message, it must have a MIME-Version
       header with the value 1.0 for us to believe what might be in
       the Content-Type header.  If the MIME-Version header is not
       present, we must treat this message as untyped.
     */
    ok = (mv && !strcmp(mv, "1.0"));
#else
    /* #### actually, we didn't check this in Mozilla 2.0, and checking
       it now could cause some compatibility nonsense, so for now, let's
       just believe any Content-Type header we see.
     */
    ok = true;
#endif

    if (ok)
      {
      ct = MimeHeaders_get (msg->hdrs, HEADER_CONTENT_TYPE, true, false);

      /* If there is no Content-Type header, but there is a MIME-Version
         header, then assume that this *is* in fact a MIME message.
         (I've seen messages with

          MIME-Version: 1.0
          Content-Transfer-Encoding: quoted-printable

         and no Content-Type, and we should treat those as being of type
         MimeInlineTextPlain rather than MimeUntypedText.)
       */
      if (mv && !ct)
        ct = strdup(TEXT_PLAIN);
      }

    PR_FREEIF(mv);  /* done with this now. */
    }

    /* If this message has a body which is encrypted and we're going to
       decrypt it (whithout converting it to HTML, since decrypt_p and
       write_html_p are never true at the same time)
    */
    if (obj->output_p &&
        obj->options &&
        obj->options->decrypt_p
#ifdef ENABLE_SMIME
        && !mime_crypto_object_p (msg->hdrs, false)
#endif /* ENABLE_SMIME */
        )
    {
      /* The body of this message is not an encrypted object, so we need
         to turn off the decrypt_p flag (to prevent us from s#$%ing the
         body of the internal object up into one.) In this case,
         our output will end up being identical to our input.
      */
      obj->options->decrypt_p = false;
    }

    /* Emit the HTML for this message's headers.  Do this before
     creating the object representing the body.
     */
    if (obj->output_p &&
      obj->options &&
      obj->options->write_html_p)
    {
      /* If citation headers are on, and this is not the outermost message,
       turn them off. */
      if (obj->options->headers == MimeHeadersCitation && !outer_p)
      obj->options->headers = MimeHeadersSome;

      /* Emit a normal header block. */
      status = MimeMessage_write_headers_html(obj);
      if (status < 0) return status;
    }
    else if (obj->output_p)
    {
      /* Dump the headers, raw. */
      status = MimeObject_write(obj, "", 0, false);  /* initialize */
      if (status < 0) return status;
      status = MimeHeaders_write_raw_headers(msg->hdrs, obj->options,
                         obj->options->decrypt_p);
      if (status < 0) return status;
    }

#ifdef XP_UNIX
    if (outer_p && obj->output_p)
    /* Kludge from mimehdrs.c */
    MimeHeaders_do_unix_display_hook_hack(msg->hdrs);
#endif /* XP_UNIX */
  }

  /* Never put out a separator after a message header block. */
  if (obj->options && obj->options->state)
  obj->options->state->separator_suppressed_p = true;

#ifdef MIME_DRAFTS
  if ( !obj->headers &&    /* outer most message header */
     obj->options &&
     obj->options->decompose_file_p &&
     ct )
  obj->options->is_multipart_msg = PL_strcasestr(ct, "multipart/") != NULL;
#endif /* MIME_DRAFTS */


  body = mime_create(ct, msg->hdrs, obj->options);

  PR_FREEIF(ct);
  if (!body) return MIME_OUT_OF_MEMORY;
  status = ((MimeContainerClass *) obj->clazz)->add_child (obj, body);
  if (status < 0)
  {
    mime_free(body);
    return status;
  }

  // Only do this if this is a Text Object!
  if ( mime_typep(body, (MimeObjectClass *) &mimeInlineTextClass) )
  {
    ((MimeInlineText *) body)->needUpdateMsgWinCharset = true;
  }

  /* Now that we've added this new object to our list of children,
   start its parser going. */
  status = body->clazz->parse_begin(body);
  if (status < 0) return status;

  // Now notify the emitter if this is the outer most message, unless
  // it is a part that is not the head of the message. If it's a part,
  // we need to figure out the content type/charset of the part
  //
  bool outer_p = !obj->headers;  /* is this the outermost message? */

  if ( (outer_p || obj->options->notify_nested_bodies) &&
       (!obj->options->part_to_load || obj->options->format_out == nsMimeOutput::nsMimeMessageBodyDisplay))
  {
    // call SetMailCharacterSetToMsgWindow() to set a menu charset
    if (mime_typep(body, (MimeObjectClass *) &mimeInlineTextClass))
    {
      MimeInlineText  *text = (MimeInlineText *) body;
      if (text && text->charset && *text->charset)
        SetMailCharacterSetToMsgWindow(body, text->charset);
    }

    char  *msgID = MimeHeaders_get (msg->hdrs, HEADER_MESSAGE_ID,
                                    false, false);

    const char  *outCharset = NULL;
    if (!obj->options->force_user_charset)  /* Only convert if the user prefs is false */
      outCharset = "UTF-8";

    mimeEmitterStartBody(obj->options, (obj->options->headers == MimeHeadersNone), msgID, outCharset);
    PR_FREEIF(msgID);

  // setting up truncated message html fotter function
  char *xmoz = MimeHeaders_get(msg->hdrs, HEADER_X_MOZILLA_STATUS, false,
                 false);
  if (xmoz)
  {
    uint32_t flags = 0;
    char dummy = 0;
    if (sscanf(xmoz, " %x %c", &flags, &dummy) == 1 &&
      flags & nsMsgMessageFlags::Partial)
    {
      obj->options->html_closure = obj;
      obj->options->generate_footer_html_fn =
        MimeMessage_partial_message_html;
    }
    PR_FREEIF(xmoz);
  }
  }

  return 0;
}
示例#11
0
nsresult nsOutlookMail::ImportMailbox( PRUint32 *pDoneSoFar, PRBool *pAbort, PRInt32 index, const PRUnichar *pName, nsIFile *pDest, PRInt32 *pMsgCount)
{
  if ((index < 0) || (index >= m_folderList.GetSize())) {
    IMPORT_LOG0( "*** Bad mailbox identifier, unable to import\n");
    *pAbort = PR_TRUE;
    return( NS_ERROR_FAILURE);
  }

  PRInt32    dummyMsgCount = 0;
  if (pMsgCount)
    *pMsgCount = 0;
  else
    pMsgCount = &dummyMsgCount;

  CMapiFolder *pFolder = m_folderList.GetItem( index);
  OpenMessageStore( pFolder);
  if (!m_lpMdb) {
    IMPORT_LOG1( "*** Unable to obtain mapi message store for mailbox: %S\n", pName);
    return( NS_ERROR_FAILURE);
  }

  if (pFolder->IsStore())
    return( NS_OK);

  nsresult  rv;

  nsOutlookCompose    compose;
  SimpleBufferTonyRCopiedTwice      copy;

  copy.Allocate( kCopyBufferSize);

  // now what?
  CMapiFolderContents    contents( m_lpMdb, pFolder->GetCBEntryID(), pFolder->GetEntryID());

  BOOL    done = FALSE;
  ULONG    cbEid;
  LPENTRYID  lpEid;
  ULONG    oType;
  LPMESSAGE  lpMsg = nsnull;
  int      attachCount;
  ULONG    totalCount;
  PRFloat64  doneCalc;
  nsCString  fromLine;
  int      fromLen;
  PRBool    lostAttach = PR_FALSE;

  nsCOMPtr<nsIOutputStream> destOutputStream;
  rv = NS_NewLocalFileOutputStream(getter_AddRefs(destOutputStream), pDest, -1, 0600);
  NS_ENSURE_SUCCESS(rv, rv);

  while (!done) {
    if (!contents.GetNext( &cbEid, &lpEid, &oType, &done)) {
      IMPORT_LOG1( "*** Error iterating mailbox: %S\n", pName);
      return( NS_ERROR_FAILURE);
    }

    totalCount = contents.GetCount();
    doneCalc = *pMsgCount;
    doneCalc /= totalCount;
    doneCalc *= 1000;
    if (pDoneSoFar) {
      *pDoneSoFar = (PRUint32) doneCalc;
      if (*pDoneSoFar > 1000)
        *pDoneSoFar = 1000;
    }

    if (!done && (oType == MAPI_MESSAGE)) {
      if (!m_mapi.OpenMdbEntry( m_lpMdb, cbEid, lpEid, (LPUNKNOWN *) &lpMsg)) {
        IMPORT_LOG1( "*** Error opening messages in mailbox: %S\n", pName);
        return( NS_ERROR_FAILURE);
      }

      CMapiMessage  msg( lpMsg);

      BOOL bResult = msg.FetchHeaders();
      if (bResult)
        bResult = msg.FetchBody();
      if (bResult)
        fromLine = msg.GetFromLine( fromLen);

      attachCount = msg.CountAttachments();
      BuildAttachments( msg, attachCount);

      if (!bResult) {
        IMPORT_LOG1( "*** Error reading message from mailbox: %S\n", pName);
        return( NS_ERROR_FAILURE);
      }

      // --------------------------------------------------------------
      compose.SetBody( msg.GetBody());

      // Need to convert all headers to unicode (for i18n).
      // Init header here since 'composes' is used for all msgs.
      compose.SetHeaders("");

      nsAutoString newheader;
      nsCAutoString tempCStr(msg.GetHeaders(), msg.GetHeaderLen());

      rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(),
        tempCStr, newheader);
      NS_ASSERTION(NS_SUCCEEDED(rv), "failed to convert headers to utf8");
      if (NS_SUCCEEDED(rv))
        compose.SetHeaders(NS_ConvertUTF16toUTF8(newheader).get());

      compose.SetAttachments( &m_attachments);

      // See if it's a drafts folder. Outlook doesn't allow drafts
      // folder to be configured so it's ok to hard code it here.
      nsAutoString folderName(pName);
      nsMsgDeliverMode mode = nsIMsgSend::nsMsgDeliverNow;
      mode = nsIMsgSend::nsMsgSaveAsDraft;
      if ( folderName.LowerCaseEqualsLiteral("drafts") )
        mode = nsIMsgSend::nsMsgSaveAsDraft;

      /*
      If I can't get no headers,
      I can't get no satisfaction
      */
      if (msg.GetHeaderLen()) {
        nsCAutoString cType;
        SetDefaultContentType(msg, cType);
        nsCOMPtr<nsIFile> compositionFile;
        rv = compose.SendTheMessage(mode, cType, getter_AddRefs(compositionFile));
        if (NS_SUCCEEDED( rv)) {
          rv = compose.CopyComposedMessage( fromLine, compositionFile, destOutputStream, copy);
          DeleteFile( compositionFile);
          if (NS_FAILED( rv)) {
            IMPORT_LOG0( "*** Error copying composed message to destination mailbox\n");
            return( rv);
          }
          (*pMsgCount)++;
        }
      }
      else
        rv = NS_OK;

      // The following code to write msg to folder when compose.SendTheMessage() fails is commented
      // out for now because the code doesn't handle attachments and users will complain anyway so
      // until we fix the code to handle all kinds of msgs correctly we should not even make users
      // think that all msgs are imported ok. This will also help users to identify which msgs are
      // not imported and help to debug the problem.
#if 0
      if (NS_FAILED( rv)) {

        /* NS_PRECONDITION( FALSE, "Manual breakpoint"); */

        IMPORT_LOG1( "Message #%d failed.\n", (int) (*pMsgCount));
        DumpAttachments();

        // --------------------------------------------------------------

        // This is the OLD way of writing out the message which uses
        // all kinds of crufty old crap for attachments.
        // Since we now use Compose to send attachments,
        // this is only fallback error stuff.

        // Attachments get lost.

        if (attachCount) {
          lostAttach = PR_TRUE;
          attachCount = 0;
        }

        BOOL needsTerminate = FALSE;
        if (!WriteMessage( destOutputStream, &msg, attachCount, &needsTerminate)) {
          IMPORT_LOG0( "*** Error writing message\n");
          *pAbort = PR_TRUE;
          return( NS_ERROR_FAILURE);
        }

        if (needsTerminate) {
          if (!WriteMimeBoundary( destOutputStream, &msg, TRUE)) {
            IMPORT_LOG0( "*** Error writing message mime boundary\n");
            *pAbort = PR_TRUE;
            return( NS_ERROR_FAILURE);
          }
        }
      }
#endif

      // Just for YUCKS, let's try an extra endline
      WriteData( destOutputStream, "\x0D\x0A", 2);
    }
  }

  return( NS_OK);
}