diff --git a/mailnews/compose/build/nsMsgCompCID.h b/mailnews/compose/build/nsMsgCompCID.h
index 1b433d6a38c1..06f91c517406 100644
--- a/mailnews/compose/build/nsMsgCompCID.h
+++ b/mailnews/compose/build/nsMsgCompCID.h
@@ -38,6 +38,11 @@
0x935284e0, 0xc5d8, 0x11d2, \
{0x82, 0x97, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
+#define NS_MSGSENDLATER_CID \
+{ /* E15C83F1-1CF4-11d3-8EF0-00A024A7D144 */ \
+ 0xe15c83f1, 0x1cf4, 0x11d3, \
+ {0x8e, 0xf0, 0x0, 0xa0, 0x24, 0xa7, 0xd1, 0x44 }}
+
#define NS_MSGPOST_CID \
{ /* 80a368c0-f1bf-11d2-8921-004005263078 */ \
0x80a368c0, 0xf1bf, 0x11d2, \
diff --git a/mailnews/compose/build/nsMsgCompFactory.cpp b/mailnews/compose/build/nsMsgCompFactory.cpp
index e28ba3a4074a..f6433a24b9ab 100644
--- a/mailnews/compose/build/nsMsgCompFactory.cpp
+++ b/mailnews/compose/build/nsMsgCompFactory.cpp
@@ -31,6 +31,7 @@
#include "nsMsgComposeFact.h"
#include "nsMsgCompFieldsFact.h"
#include "nsMsgSendFact.h"
+#include "nsMsgSendLaterFact.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
@@ -40,6 +41,7 @@ static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kCMsgComposeCID, NS_MSGCOMPOSE_CID);
static NS_DEFINE_CID(kCMsgCompFieldsCID, NS_MSGCOMPFIELDS_CID);
static NS_DEFINE_CID(kCMsgSendCID, NS_MSGSEND_CID);
+static NS_DEFINE_CID(kCMsgSendLaterCID, NS_MSGSENDLATER_CID);
static NS_DEFINE_CID(kCSmtpServiceCID, NS_SMTPSERVICE_CID);
static NS_DEFINE_CID(kCComposeAppCoreCID, NS_COMPOSEAPPCORE_CID);
static NS_DEFINE_CID(kCComposerBootstrapCID, NS_COMPOSERBOOTSTRAP_CID);
@@ -150,10 +152,10 @@ nsresult nsMsgComposeFactory::CreateInstance(nsISupports *aOuter, const nsIID &a
return smtpService->QueryInterface(kISupportsIID, aResult);
}
// do they want a Message Compose interface ?
- else if (mClassID.Equals(kCMsgComposeCID))
- {
- return NS_NewMsgCompose(aIID, aResult);
- }
+ // RICHIE - not any more else if (mClassID.Equals(kCMsgComposeCID))
+ // RICHIE - not any more {
+ // RICHIE - not any more return NS_NewMsgCompose(aIID, aResult);
+ // RICHIE - not any more }
// do they want a Message Compose Fields interface ?
else if (mClassID.Equals(kCMsgCompFieldsCID))
@@ -166,6 +168,12 @@ nsresult nsMsgComposeFactory::CreateInstance(nsISupports *aOuter, const nsIID &a
{
return NS_NewMsgSend(aIID, aResult);
}
+ // do they want a Message Send Later interface ?
+ else if (mClassID.Equals(kCMsgSendLaterCID))
+ {
+ return NS_NewMsgSendLater(aIID, aResult);
+ }
+
// do they want a Compose AppCore interface ?
else if (mClassID.Equals(kCComposeAppCoreCID))
{
@@ -243,6 +251,11 @@ extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char*
nsnull, path, PR_TRUE, PR_TRUE);
if (NS_FAILED(rv)) finalResult = rv;
+ rv = compMgr->RegisterComponent(kCMsgSendLaterCID,
+ "Message Send Later",
+ nsnull, path, PR_TRUE, PR_TRUE);
+ if (NS_FAILED(rv)) finalResult = rv;
+
rv = compMgr->RegisterComponent(kCMsgComposeCID,
"Message Compose",
nsnull,
@@ -303,6 +316,9 @@ NSUnregisterSelf(nsISupports* aServMgr, const char* path)
rv = compMgr->UnregisterComponent(kCMsgSendCID, path);
if (NS_FAILED(rv)) finalResult = rv;
+ rv = compMgr->UnregisterComponent(kCMsgSendLaterCID, path);
+ if (NS_FAILED(rv)) finalResult = rv;
+
rv = compMgr->UnregisterComponent(kCMsgCompFieldsCID, path);
if (NS_FAILED(rv)) finalResult = rv;
diff --git a/mailnews/compose/public/nsMsgSendLaterFact.h b/mailnews/compose/public/nsMsgSendLaterFact.h
new file mode 100644
index 000000000000..ffb06e87f330
--- /dev/null
+++ b/mailnews/compose/public/nsMsgSendLaterFact.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+/********************************************************************************************************
+
+ Message Send Later Class Factory.
+
+*********************************************************************************************************/
+
+#ifndef _MsgSendLaterFact_H_
+#define _MsgSendLaterFact_H_
+
+#include "nsIMsgSendLater.h"
+
+extern nsresult NS_NewMsgSendLater(const nsIID &aIID, void ** aInstancePtrResult);
+
+
+#endif
+
diff --git a/mailnews/compose/src/Makefile.in b/mailnews/compose/src/Makefile.in
index cc1dd47029ad..759dd2c9bde1 100644
--- a/mailnews/compose/src/Makefile.in
+++ b/mailnews/compose/src/Makefile.in
@@ -31,11 +31,21 @@ EXPORTS = \
nsComposeAppCore.h \
nsComposer.h \
nsMsgCompPrefs.h \
+ nsMsgZapIt.h \
+ nsMsgCreate.h \
+ nsMsgCopy.h \
+ nsMsgSendLater.h \
+ nsMsgDeliveryListener.h \
+ nsMsgComposeStringBundle.h \
+ nsMsgEncoders.h \
+ nsMsgUtils.h \
+ nsMsgI18N.h \
+ nsMsgAttachmentHandler.h \
+ nsMsgPrompts.h \
$(NULL)
CPPSRCS = \
nsMsgCompFields.cpp \
- nsMsgCompose.cpp \
msgCompGlue.cpp \
nsSmtpUrl.cpp \
nsSmtpProtocol.cpp \
@@ -48,6 +58,17 @@ CPPSRCS = \
nsComposerNameSet.cpp \
nsMsgCompPrefs.cpp \
nsIComposer.cpp \
+ nsMsgZapIt.cpp \
+ nsMsgCreate.cpp \
+ nsMsgCopy.cpp \
+ nsMsgSendLater.cpp \
+ nsMsgDeliveryListener.cpp \
+ nsMsgComposeStringBundle.cpp \
+ nsMsgEncoders.cpp \
+ nsMsgUtils.cpp \
+ nsMsgI18N.cpp \
+ nsMsgAttachmentHandler.cpp \
+ nsMsgPrompts.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
diff --git a/mailnews/compose/src/makefile.win b/mailnews/compose/src/makefile.win
index 5d71970590a7..e5afc3999f51 100644
--- a/mailnews/compose/src/makefile.win
+++ b/mailnews/compose/src/makefile.win
@@ -27,10 +27,13 @@ include <$(DEPTH)\config\config.mak>
EXPORTS= nsSmtpUrl.h \
nsSmtpProtocol.h \
- nsSmtpService.h \
- nsComposeAppCore.h \
- nsComposer.h \
- nsMsgCompPrefs.h \
+ nsSmtpService.h \
+ nsComposeAppCore.h \
+ nsComposer.h \
+ nsMsgCompPrefs.h \
+ nsMsgZapIt.h \
+ nsMsgCreate.h \
+ nsMsgSendLater.h \
$(NULL)
################################################################################
@@ -44,18 +47,28 @@ LCFLAGS = \
$(NULL)
CPP_OBJS= .\$(OBJDIR)\nsMsgCompFields.obj \
- .\$(OBJDIR)\nsMsgCompose.obj \
.\$(OBJDIR)\nsSmtpUrl.obj \
.\$(OBJDIR)\MsgCompGlue.obj \
- .\$(OBJDIR)\nsSmtpProtocol.obj \
- .\$(OBJDIR)\nsMsgSend.obj \
- .\$(OBJDIR)\nsMsgSendPart.obj \
- .\$(OBJDIR)\nsSmtpService.obj \
- .\$(OBJDIR)\nsJSComposeAppCore.obj \
- .\$(OBJDIR)\nsComposeAppCore.obj \
- .\$(OBJDIR)\nsComposer.obj \
- .\$(OBJDIR)\nsComposerNameSet.obj \
- .\$(OBJDIR)\nsMsgCompPrefs.obj \
+ .\$(OBJDIR)\nsSmtpProtocol.obj \
+ .\$(OBJDIR)\nsMsgSend.obj \
+ .\$(OBJDIR)\nsMsgSendPart.obj \
+ .\$(OBJDIR)\nsSmtpService.obj \
+ .\$(OBJDIR)\nsJSComposeAppCore.obj \
+ .\$(OBJDIR)\nsComposeAppCore.obj \
+ .\$(OBJDIR)\nsComposer.obj \
+ .\$(OBJDIR)\nsComposerNameSet.obj \
+ .\$(OBJDIR)\nsMsgCompPrefs.obj \
+ .\$(OBJDIR)\nsMsgZapIt.obj \
+ .\$(OBJDIR)\nsMsgCreate.obj \
+ .\$(OBJDIR)\nsMsgCopy.obj \
+ .\$(OBJDIR)\nsMsgSendLater.obj \
+ .\$(OBJDIR)\nsMsgDeliveryListener.obj \
+ .\$(OBJDIR)\nsMsgComposeStringBundle.obj \
+ .\$(OBJDIR)\nsMsgEncoders.obj \
+ .\$(OBJDIR)\nsMsgUtils.obj \
+ .\$(OBJDIR)\nsMsgI18N.obj \
+ .\$(OBJDIR)\nsMsgAttachmentHandler.obj \
+ .\$(OBJDIR)\nsMsgPrompts.obj \
$(NULL)
diff --git a/mailnews/compose/src/nsMsgAttachmentHandler.cpp b/mailnews/compose/src/nsMsgAttachmentHandler.cpp
new file mode 100644
index 000000000000..59085ba145ae
--- /dev/null
+++ b/mailnews/compose/src/nsMsgAttachmentHandler.cpp
@@ -0,0 +1,756 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsMsgCopy.h"
+#include "nsIPref.h"
+#include "nsMsgCompPrefs.h"
+#include "nsMsgAttachmentHandler.h"
+#include "nsMsgSend.h"
+#include "nsMsgUtils.h"
+#include "nsIPref.h"
+#include "nsMsgCompose.h"
+#include "nsMsgEncoders.h"
+#include "nsMsgI18N.h"
+
+static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
+
+nsMsgAttachmentHandler::nsMsgAttachmentHandler()
+{
+ m_url_string = NULL;
+ m_url = NULL;
+ m_done = PR_FALSE;
+ m_type = NULL;
+ m_charset = NULL;
+ m_override_type = NULL;
+ m_override_encoding = NULL;
+ m_desired_type = NULL;
+ m_description = NULL;
+ m_x_mac_type = NULL;
+ m_x_mac_creator = NULL;
+ m_encoding = NULL;
+ m_real_name = NULL;
+ m_mime_delivery_state = NULL;
+ m_encoding = NULL;
+ m_already_encoded_p = PR_FALSE;
+ m_file_name = NULL;
+ m_file = 0;
+#ifdef XP_MAC
+ m_ap_filename = NULL;
+#endif
+ m_decrypted_p = PR_FALSE;
+ m_size = 0;
+ m_unprintable_count = 0;
+ m_highbit_count = 0;
+ m_ctl_count = 0;
+ m_null_count = 0;
+ m_current_column = 0;
+ m_max_column = 0;
+ m_lines = 0;
+
+ m_encoder_data = NULL;
+
+ m_graph_progress_started = PR_FALSE;
+}
+
+nsMsgAttachmentHandler::~nsMsgAttachmentHandler()
+{
+}
+
+
+PRBool nsMsgAttachmentHandler::UseUUEncode_p(void)
+{
+printf("RICHIE: commenting out GetCompBoolHeader() call for now...\n");
+ PRBool returnVal = (m_mime_delivery_state) &&
+ (m_mime_delivery_state->m_pane)
+ &&
+ PR_FALSE;
+
+// ((nsMsgCompose*)(m_mime_delivery_state->m_pane))->
+// GetCompBoolHeader(MSG_UUENCODE_BINARY_BOOL_HEADER_MASK);
+
+ return returnVal;
+}
+
+static void
+msg_escape_file_name (URL_Struct *m_url)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+ (void)prefs;
+
+ NS_ASSERTION (m_url->address && !PL_strncasecmp(m_url->address, "file:", 5), "Invalid URL type");
+ if (!m_url->address || PL_strncasecmp(m_url->address, "file:", 5))
+ return;
+
+ char * new_address = nsEscape(PL_strchr(m_url->address, ':') + 1, url_Path);
+ NS_ASSERTION(new_address, "null ptr");
+ if (!new_address)
+ return;
+
+ PR_FREEIF(m_url->address);
+ m_url->address = PR_smprintf("file:%s", new_address);
+ PR_FREEIF(new_address);
+}
+
+PRInt32
+nsMsgAttachmentHandler::SnarfAttachment ()
+{
+ PRInt32 status = 0;
+ NS_ASSERTION (! m_done, "Already done");
+
+ m_file_name = nsMsgCreateTempFileName("nsmail.tmp");
+ if (! m_file_name)
+ return (MK_OUT_OF_MEMORY);
+
+ m_file = PR_Open (m_file_name, PR_CREATE_FILE | PR_RDWR, 493);
+ if (! m_file)
+ return MK_UNABLE_TO_OPEN_TMP_FILE; /* #### how do we pass file name? */
+
+ m_url->fe_data = this;
+
+ /* #### m_type is still unknown at this point.
+ We *really* need to find a way to make the textfe not blow
+ up on documents that are not text/html!!
+ */
+
+#ifdef XP_MAC
+ if (NET_IsLocalFileURL(m_url->address) && // do we need to add IMAP: to this list? NET_IsLocalFileURL returns PR_FALSE always for IMAP - DMB
+ (PL_strncasecmp(m_url->address, "mailbox:", 8) != 0))
+ {
+ /* convert the apple file to AppleDouble first, and then patch the
+ address in the url.
+ */
+ char* src_filename = NET_GetLocalFileFromURL (m_url->address);
+
+ // ### mwelch Only use appledouble if we aren't uuencoding.
+ if(/*JFD isMacFile(src_filename) && */ (! UseUUEncode_p()))
+ {
+
+ char *separator, tmp[128];
+ NET_StreamClass *ad_encode_stream;
+
+ separator = mime_make_separator("ad");
+ if (!separator)
+ return MK_OUT_OF_MEMORY;
+
+ m_ap_filename = nsMsgCreateTempFileName("nsmail.tmp");
+ ad_encode_stream = (NET_StreamClass *) /* need a prototype */
+NULL; /* JFD fe_MakeAppleDoubleEncodeStream (FO_CACHE_AND_MAIL_TO,
+ (void*)NULL,
+ m_url,
+ m_mime_delivery_state->GetContext(),
+ src_filename,
+ m_ap_filename,
+ separator,
+ m_real_name);
+JFD */
+
+ if (ad_encode_stream == NULL)
+ {
+ PR_FREEIF(separator);
+ return MK_OUT_OF_MEMORY;
+ }
+
+ do {
+ status = (*ad_encode_stream->put_block)
+ ((NET_StreamClass *)ad_encode_stream->data_object, NULL, 1024);
+ } while (status == noErr);
+
+ if (status >= 0)
+ ad_encode_stream->complete ((NET_StreamClass *)ad_encode_stream->data_object);
+ else
+ ad_encode_stream->abort ((NET_StreamClass *)ad_encode_stream->data_object, status);
+
+ PR_Free(ad_encode_stream);
+
+ if (status < 0)
+ {
+ PR_FREEIF(separator);
+ return status;
+ }
+
+ PR_Free(m_url->address);
+ {
+ char * temp = WH_FileName(m_ap_filename, xpFileToPost );
+ m_url->address = XP_PlatformFileToURL(temp); // jrm 97/02/08
+ if (temp)
+ PR_Free(temp);
+ }
+ /* and also patch the types.
+ */
+
+ PR_snprintf(tmp, sizeof(tmp),, MULTIPART_APPLEDOUBLE ";\r\n boundary=\"%s\"",
+ separator);
+
+ PR_FREEIF(separator);
+
+ PR_FREEIF (m_type);
+ m_type = PL_strdup(tmp);
+ }
+ else
+ {
+//JFD if (isMacFile(src_filename))
+ {
+ // The only time we want to send just the data fork of a two-fork
+ // Mac file is if uuencoding has been requested.
+ NS_ASSERTION(UseUUEncode_p(), "not UseUUEncode_p");
+ if (!((nsMsgCompose *) m_mime_delivery_state->m_pane)->m_confirmed_uuencode_p)
+ {
+#ifdef UNREADY_CODE
+ PRBool confirmed = FE_Confirm(m_mime_delivery_state->m_pane->GetContext(),
+ XP_GetString(MK_MSG_MAC_PROMPT_UUENCODE));
+#else
+ PRBool confirmed = PR_TRUE;
+#endif
+
+ // only want to do this once
+ ((nsMsgCompose *) m_mime_delivery_state->m_pane)->m_confirmed_uuencode_p = PR_TRUE;
+
+ if (! confirmed) // cancelled
+ return MK_INTERRUPTED;
+ }
+ }
+ /* make sure the file type and create are set. */
+ char filetype[32];
+ FSSpec fsSpec;
+ FInfo info;
+ Bool useDefault;
+ char *macType, *macEncoding;
+
+/*JFD
+ my_FSSpecFromPathname(src_filename, &fsSpec);
+*/
+ if (FSpGetFInfo (&fsSpec, &info) == noErr)
+ {
+ PR_snprintf(filetype, sizeof(filetype), "%X", info.fdType);
+ PR_FREEIF(m_x_mac_type);
+ m_x_mac_type = PL_strdup(filetype);
+
+ PR_snprintf(filetype, sizeof(filetype), "%X", info.fdCreator);
+ PR_FREEIF(m_x_mac_creator);
+ m_x_mac_creator = PL_strdup(filetype);
+ if (m_type == NULL ||
+ !PL_strcasecmp (m_type, TEXT_PLAIN))
+ {
+# define TEXT_TYPE 0x54455854 /* the characters 'T' 'E' 'X' 'T' */
+# define text_TYPE 0x74657874 /* the characters 't' 'e' 'x' 't' */
+
+ if (info.fdType != TEXT_TYPE && info.fdType != text_TYPE)
+ {
+/*JFD
+ FE_FileType(m_url->address, &useDefault,
+ &macType, &macEncoding);
+*/
+
+ PR_FREEIF(m_type);
+ m_type = macType;
+ }
+ }
+ }
+
+ /* don't bother to set the types if we failed in getting the file
+ info. */
+ }
+ PR_FREEIF(src_filename);
+ src_filename = 0;
+ }
+#else
+
+ /* if we are attaching a local file make sure the file name are escaped
+ * properly
+ */
+ if (NET_IsLocalFileURL(m_url->address) &&
+ PL_strncasecmp (m_url->address, "file:", 5) == 0)
+ {
+ msg_escape_file_name(m_url);
+ }
+
+#endif /* XP_MAC */
+
+ if (m_desired_type &&
+ !PL_strcasecmp (m_desired_type, TEXT_PLAIN) )
+ {
+ /* Conversion to plain text desired.
+ */
+/*JFD
+ m_print_setup.url = m_url;
+ m_print_setup.carg = this;
+ m_print_setup.completion = mime_text_attachment_url_exit;
+ m_print_setup.filename = NULL;
+ m_print_setup.out = m_file;
+ m_print_setup.eol = CRLF;
+JFD */
+ PRInt32 width = 72;
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->GetIntPref("mailnews.wraplength", &width);
+ if (width == 0) width = 72;
+ else if (width < 10) width = 10;
+ else if (width > 30000) width = 30000;
+
+ if (m_mime_delivery_state->m_pane->GetPaneType() == MSG_COMPOSITIONPANE)
+ {
+ int lineWidth = ((nsMsgCompose *) m_mime_delivery_state->m_pane)
+ ->GetLineWidth();
+ if (lineWidth > width)
+ width = lineWidth;
+ }
+/*JFD
+ m_print_setup.width = width;
+
+ m_url->savedData.FormList = 0;
+#ifdef _USRDLL
+ if (! NDLLXL_TranslateText (m_mime_delivery_state->GetContext(), m_url,
+ &m_print_setup))
+ return MK_ATTACHMENT_LOAD_FAILED;
+#else
+ if (! XL_TranslateText (m_mime_delivery_state->GetContext(), m_url,
+ &m_print_setup))
+ return MK_ATTACHMENT_LOAD_FAILED;
+#endif
+JFD */
+ if (m_type) PR_Free (m_type);
+ m_type = m_desired_type;
+ m_desired_type = 0;
+ if (m_encoding) PR_Free (m_encoding);
+ m_encoding = 0;
+ }
+/* this used to be XP_UNIX? */
+#if 0
+ else if (m_desired_type &&
+ !PL_strcasecmp (m_desired_type, APPLICATION_POSTSCRIPT) )
+ {
+ SHIST_SavedData saved_data;
+
+ /* Make sure layout saves the current state of form elements. */
+ LO_SaveFormData(m_mime_delivery_state->GetContext());
+
+ /* Hold on to the saved data. */
+ memcpy(&saved_data, &m_url->savedData, sizeof(SHIST_SavedData));
+
+ /* Conversion to postscript desired.
+ */
+/*JFD
+ XFE_InitializePrintSetup (&m_print_setup);
+ m_print_setup.url = m_url;
+ m_print_setup.carg = this;
+ m_print_setup.completion = mime_text_attachment_url_exit;
+ m_print_setup.filename = NULL;
+ m_print_setup.out = m_file;
+ m_print_setup.eol = CRLF;
+ memset (&m_url->savedData, 0, sizeof (SHIST_SavedData));
+ XL_TranslatePostscript (m_mime_delivery_state->GetContext(),
+ m_url, &saved_data,
+ &m_print_setup);
+JFD*/
+ if (m_type) PR_Free (m_type);
+ m_type = m_desired_type;
+ m_desired_type = 0;
+ if (m_encoding) PR_Free (m_encoding);
+ m_encoding = 0;
+ }
+#endif /* XP_UNIX */
+ else
+ {
+ m_url->allow_content_change = PR_FALSE; // don't use modified content
+
+ if (NET_URL_Type (m_url->address) == NEWS_TYPE_URL && !m_url->msg_pane)
+ m_url->msg_pane = m_mime_delivery_state->m_pane;
+
+/*JFD
+ MSG_UrlQueue::AddUrlToPane(m_url, mime_attachment_url_exit,
+ m_mime_delivery_state->m_pane, PR_TRUE,
+ FO_CACHE_AND_MAIL_TO);
+JFD*/
+ return 0;
+ }
+ return status;
+}
+
+void nsMsgAttachmentHandler::UrlExit(URL_Struct *url, int status,
+ MWContext *context)
+{
+ char *error_msg = url->error_msg;
+ url->error_msg = 0;
+ url->fe_data = 0;
+
+ NS_ASSERTION(m_mime_delivery_state != NULL, "not-null m_mime_delivery_state");
+ NS_ASSERTION(m_mime_delivery_state->GetContext() != NULL, "not-null context");
+ NS_ASSERTION(m_url != NULL, "not-null m_url");
+
+ if (m_graph_progress_started)
+ {
+ m_graph_progress_started = PR_FALSE;
+ FE_GraphProgressDestroy (m_mime_delivery_state->GetContext(), m_url,
+ m_url->content_length, m_size);
+ }
+
+ if (status < 0)
+ /* If any of the attachment URLs fail, kill them all. */
+ NET_InterruptWindow (context);
+
+ /* Close the file, but don't delete it (or the file name.) */
+ PR_Close (m_file);
+ m_file = 0;
+ NET_FreeURLStruct (m_url);
+ /* I'm pretty sure m_url == url */
+ m_url = 0;
+ url = 0;
+
+
+
+ if (status < 0) {
+ if (m_mime_delivery_state->m_status >= 0)
+ m_mime_delivery_state->m_status = status;
+ PR_Delete(m_file_name);
+ PR_FREEIF(m_file_name);
+ }
+
+ m_done = PR_TRUE;
+
+ NS_ASSERTION (m_mime_delivery_state->m_attachment_pending_count > 0, "no more pending attachment");
+ m_mime_delivery_state->m_attachment_pending_count--;
+
+ if (status >= 0 && m_mime_delivery_state->m_be_synchronous_p)
+ {
+ /* Find the next attachment which has not yet been loaded,
+ if any, and start it going.
+ */
+ PRInt32 i;
+ nsMsgAttachmentHandler *next = 0;
+ for (i = 0; i < m_mime_delivery_state->m_attachment_count; i++)
+ if (!m_mime_delivery_state->m_attachments[i].m_done)
+ {
+ next = &m_mime_delivery_state->m_attachments[i];
+ break;
+ }
+ if (next)
+ {
+ int status = next->SnarfAttachment ();
+ if (status < 0)
+ {
+ m_mime_delivery_state->Fail(status, 0);
+ return;
+ }
+ }
+ }
+
+ if (m_mime_delivery_state->m_attachment_pending_count == 0)
+ {
+ /* If this is the last attachment, then either complete the
+ delivery (if successful) or report the error by calling
+ the exit routine and terminating the delivery.
+ */
+ if (status < 0)
+ {
+ m_mime_delivery_state->Fail(status, error_msg);
+ error_msg = 0;
+ }
+ else
+ {
+ m_mime_delivery_state->GatherMimeAttachments ();
+ }
+ }
+ else
+ {
+ /* If this is not the last attachment, but it got an error,
+ then report that error and continue (we won't actually
+ abort the delivery until all the other pending URLs have
+ caught up with the NET_InterruptWindow() we did up above.)
+ if (status < 0 && error_msg)
+ FE_Alert (context, error_msg);
+ */
+
+ if (status < 0)
+ {
+ m_mime_delivery_state->Fail(status, error_msg);
+ error_msg = 0;
+ }
+ }
+ PR_FREEIF (error_msg);
+}
+
+void
+nsMsgAttachmentHandler::AnalyzeDataChunk(const char *chunk, PRInt32 length)
+{
+ unsigned char *s = (unsigned char *) chunk;
+ unsigned char *end = s + length;
+ for (; s < end; s++)
+ {
+ if (*s > 126)
+ {
+ m_highbit_count++;
+ m_unprintable_count++;
+ }
+ else if (*s < ' ' && *s != '\t' && *s != CR && *s != LF)
+ {
+ m_unprintable_count++;
+ m_ctl_count++;
+ if (*s == 0)
+ m_null_count++;
+ }
+
+ if (*s == CR || *s == LF)
+ {
+ if (s+1 < end && s[0] == CR && s[1] == LF)
+ s++;
+ if (m_max_column < m_current_column)
+ m_max_column = m_current_column;
+ m_current_column = 0;
+ m_lines++;
+ }
+ else
+ {
+ m_current_column++;
+ }
+ }
+}
+
+void
+nsMsgAttachmentHandler::AnalyzeSnarfedFile(void)
+{
+ char chunk[256];
+ PRFileDesc *fileHdl = NULL;
+ PRInt32 numRead = 0;
+
+ if (m_file_name && *m_file_name)
+ {
+ fileHdl = PR_Open(m_file_name, PR_RDONLY, 0);
+ if (fileHdl)
+ {
+ do
+ {
+ numRead = PR_Read(fileHdl, chunk, 256);
+ if (numRead > 0)
+ AnalyzeDataChunk(chunk, numRead);
+ }
+ while (numRead > 0);
+ PR_Close(fileHdl);
+ }
+ }
+}
+
+/* Given a content-type and some info about the contents of the document,
+ decide what encoding it should have.
+ */
+int
+nsMsgAttachmentHandler::PickEncoding (const char *charset)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ // use the boolean so we only have to test for uuencode vs base64 once
+ PRBool needsB64 = PR_FALSE;
+ PRBool forceB64 = PR_FALSE;
+
+ if (m_already_encoded_p)
+ goto DONE;
+
+ /* Allow users to override our percentage-wise guess on whether
+ the file is text or binary */
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->GetBoolPref ("mail.file_attach_binary", &forceB64);
+
+ if (forceB64 || mime_type_requires_b64_p (m_type))
+ {
+ /* If the content-type is "image/" or something else known to be binary,
+ always use base64 (so that we don't get confused by newline
+ conversions.)
+ */
+ needsB64 = PR_TRUE;
+ }
+ else
+ {
+ /* Otherwise, we need to pick an encoding based on the contents of
+ the document.
+ */
+
+ PRBool encode_p;
+
+ if (m_max_column > 900)
+ encode_p = PR_TRUE;
+ else if (UseQuotedPrintable() && m_unprintable_count)
+ encode_p = PR_TRUE;
+
+ else if (m_null_count) /* If there are nulls, we must always encode,
+ because sendmail will blow up. */
+ encode_p = PR_TRUE;
+#if 0
+ else if (m_ctl_count) /* Should we encode if random other control
+ characters are present? Probably... */
+ encode_p = PR_TRUE;
+#endif
+ else
+ encode_p = PR_FALSE;
+
+ /* MIME requires a special case that these types never be encoded.
+ */
+ if (!PL_strncasecmp (m_type, "message", 7) ||
+ !PL_strncasecmp (m_type, "multipart", 9))
+ {
+ encode_p = PR_FALSE;
+ if (m_desired_type && !PL_strcasecmp (m_desired_type, TEXT_PLAIN))
+ {
+ PR_Free (m_desired_type);
+ m_desired_type = 0;
+ }
+ }
+ /* If the Mail charset is ISO_2022_JP we force it to use Base64 for attachments (bug#104255).
+ Use 7 bit for other STATFUL charsets ( e.g. ISO_2022_KR). */
+ if ((PL_strcasecmp(charset, "iso-2022-jp") == 0) &&
+ (PL_strcasecmp(m_type, TEXT_HTML) == 0))
+ needsB64 = PR_TRUE;
+ else if((nsMsgI18Nstateful_charset(charset)) &&
+ ((PL_strcasecmp(m_type, TEXT_HTML) == 0) ||
+ (PL_strcasecmp(m_type, TEXT_MDL) == 0) ||
+ (PL_strcasecmp(m_type, TEXT_PLAIN) == 0) ||
+ (PL_strcasecmp(m_type, TEXT_RICHTEXT) == 0) ||
+ (PL_strcasecmp(m_type, TEXT_ENRICHED) == 0) ||
+ (PL_strcasecmp(m_type, TEXT_VCARD) == 0) ||
+ (PL_strcasecmp(m_type, APPLICATION_DIRECTORY) == 0) || /* text/x-vcard synonym */
+ (PL_strcasecmp(m_type, TEXT_CSS) == 0) ||
+ (PL_strcasecmp(m_type, TEXT_JSSS) == 0) ||
+ (PL_strcasecmp(m_type, MESSAGE_RFC822) == 0) ||
+ (PL_strcasecmp(m_type, MESSAGE_NEWS) == 0)))
+ {
+ PR_FREEIF(m_encoding);
+ m_encoding = PL_strdup (ENCODING_7BIT);
+ }
+ else if (encode_p &&
+ m_size > 500 &&
+ m_unprintable_count > (m_size / 10))
+ /* If the document contains more than 10% unprintable characters,
+ then that seems like a good candidate for base64 instead of
+ quoted-printable.
+ */
+ needsB64 = PR_TRUE;
+ else if (encode_p) {
+ PR_FREEIF(m_encoding);
+ m_encoding = PL_strdup (ENCODING_QUOTED_PRINTABLE);
+ }
+ else if (m_highbit_count > 0) {
+ PR_FREEIF(m_encoding);
+ m_encoding = PL_strdup (ENCODING_8BIT);
+ }
+ else {
+ PR_FREEIF(m_encoding);
+ m_encoding = PL_strdup (ENCODING_7BIT);
+ }
+ }
+
+ if (needsB64)
+ {
+ /*
+ ### mwelch We might have to uuencode instead of
+ base64 the binary data.
+ */
+ PR_FREEIF(m_encoding);
+ if (UseUUEncode_p())
+ m_encoding = PL_strdup (ENCODING_UUENCODE);
+ else
+ m_encoding = PL_strdup (ENCODING_BASE64);
+ }
+
+ /* Now that we've picked an encoding, initialize the filter.
+ */
+ NS_ASSERTION(!m_encoder_data, "not-null m_encoder_data");
+ if (!PL_strcasecmp(m_encoding, ENCODING_BASE64))
+ {
+ m_encoder_data = MIME_B64EncoderInit(mime_encoder_output_fn,
+ m_mime_delivery_state);
+ if (!m_encoder_data) return MK_OUT_OF_MEMORY;
+ }
+ else if (!PL_strcasecmp(m_encoding, ENCODING_UUENCODE))
+ {
+ char *tailName = NULL;
+
+ if (m_url_string)
+ {
+ tailName = PL_strrchr(m_url_string, '/');
+ if (tailName) {
+ char * tmp = tailName;
+ tailName = PL_strdup(tailName+1);
+ PR_FREEIF(tmp);
+ }
+ }
+
+ if (m_url && !tailName)
+ {
+ tailName = PL_strrchr(m_url->address, '/');
+ if (tailName) {
+ char * tmp = tailName;
+ tailName = PL_strdup(tailName+1);
+ PR_FREEIF(tmp);
+ }
+ }
+
+ m_encoder_data = MIME_UUEncoderInit((char *)(tailName ? tailName : ""),
+ mime_encoder_output_fn,
+ m_mime_delivery_state);
+ PR_FREEIF(tailName);
+ if (!m_encoder_data) return MK_OUT_OF_MEMORY;
+ }
+ else if (!PL_strcasecmp(m_encoding, ENCODING_QUOTED_PRINTABLE))
+ {
+ m_encoder_data = MIME_QPEncoderInit(mime_encoder_output_fn,
+ m_mime_delivery_state);
+ if (!m_encoder_data) return MK_OUT_OF_MEMORY;
+ }
+ else
+ {
+ m_encoder_data = 0;
+ }
+
+
+ /* Do some cleanup for documents with unknown content type.
+
+ There are two issues: how they look to MIME users, and how they look to
+ non-MIME users.
+
+ If the user attaches a "README" file, which has unknown type because it
+ has no extension, we still need to send it with no encoding, so that it
+ is readable to non-MIME users.
+
+ But if the user attaches some random binary file, then base64 encoding
+ will have been chosen for it (above), and in this case, it won't be
+ immediately readable by non-MIME users. However, if we type it as
+ text/plain instead of application/octet-stream, it will show up inline
+ in a MIME viewer, which will probably be ugly, and may possibly have
+ bad charset things happen as well.
+
+ So, the heuristic we use is, if the type is unknown, then the type is
+ set to application/octet-stream for data which needs base64 (binary data)
+ and is set to text/plain for data which didn't need base64 (unencoded or
+ lightly encoded data.)
+ */
+ DONE:
+ if (!m_type || !*m_type || !PL_strcasecmp(m_type, UNKNOWN_CONTENT_TYPE))
+ {
+ PR_FREEIF(m_type);
+ if (m_already_encoded_p)
+ m_type = PL_strdup (APPLICATION_OCTET_STREAM);
+ else if (m_encoding &&
+ (!PL_strcasecmp(m_encoding, ENCODING_BASE64) ||
+ !PL_strcasecmp(m_encoding, ENCODING_UUENCODE)))
+ m_type = PL_strdup (APPLICATION_OCTET_STREAM);
+ else
+ m_type = PL_strdup (TEXT_PLAIN);
+ }
+ return 0;
+}
+
diff --git a/mailnews/compose/src/nsMsgAttachmentHandler.h b/mailnews/compose/src/nsMsgAttachmentHandler.h
new file mode 100644
index 000000000000..046745567b8a
--- /dev/null
+++ b/mailnews/compose/src/nsMsgAttachmentHandler.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgAttachment_H_
+#define _nsMsgAttachment_H_
+
+#include "net.h"
+#include "nsIMimeConverter.h"
+
+
+class nsMsgComposeAndSend;
+
+class nsMsgAttachmentHandler
+{
+public:
+
+ nsMsgAttachmentHandler();
+ ~nsMsgAttachmentHandler();
+
+ void UrlExit(URL_Struct *url, int status, MWContext *context);
+ PRInt32 SnarfAttachment ();
+ void AnalyzeDataChunk (const char *chunk, PRInt32 chunkSize);
+ void AnalyzeSnarfedFile (); /* Analyze a previously-snarfed file.
+ (Currently only used for plaintext
+ converted from HTML.) */
+ int PickEncoding (const char *charset);
+
+ PRBool UseUUEncode_p(void);
+
+ char *m_url_string;
+ URL_Struct *m_url;
+ PRBool m_done;
+
+ nsMsgComposeAndSend *m_mime_delivery_state;
+
+ char *m_charset; /* charset name */
+ char *m_type; /* The real type, once we know it. */
+ char *m_override_type; /* The type we should assume it to be
+ or 0, if we should get it from the
+ URL_Struct (from the server) */
+ char *m_override_encoding; /* Goes along with override_type */
+
+ char *m_desired_type; /* The type it should be converted to. */
+ char *m_description; /* For Content-Description header */
+ char *m_x_mac_type, *m_x_mac_creator; /* Mac file type/creator. */
+ char *m_real_name; /* The name for the headers, if different
+ from the URL. */
+ char *m_encoding; /* The encoding, once we've decided. */
+ PRBool m_already_encoded_p; /* If we attach a document that is already
+ encoded, we just pass it through. */
+
+ char *m_file_name; /* The temp file to which we save it */
+ PRFileDesc *m_file;
+
+#ifdef XP_MAC
+ char *m_ap_filename; /* The temp file holds the appledouble
+ encoding of the file we want to post. */
+#endif
+
+ PRBool m_decrypted_p; /* S/MIME -- when attaching a message that was
+ encrypted, it's necessary to decrypt it first
+ (since nobody but the original recipient can
+ read it -- if you forward it to someone in the
+ raw, it will be useless to them.) This flag
+ indicates whether decryption occurred, so that
+ libmsg can issue appropriate warnings about
+ doing a cleartext forward of a message that was
+ originally encrypted.
+ */
+ PRUint32 m_size; /* Some state used while filtering it */
+ PRUint32 m_unprintable_count;
+ PRUint32 m_highbit_count;
+ PRUint32 m_ctl_count;
+ PRUint32 m_null_count;
+ PRUint32 m_current_column;
+ PRUint32 m_max_column;
+ PRUint32 m_lines;
+
+ MimeEncoderData *m_encoder_data; /* Opaque state for base64/qp encoder. */
+
+ PRBool m_graph_progress_started;
+};
+
+
+#endif /* _nsMsgAttachment_H_ */
diff --git a/mailnews/compose/src/nsMsgComposeStringBundle.cpp b/mailnews/compose/src/nsMsgComposeStringBundle.cpp
new file mode 100644
index 000000000000..81bdda946611
--- /dev/null
+++ b/mailnews/compose/src/nsMsgComposeStringBundle.cpp
@@ -0,0 +1,154 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "prprf.h"
+#include "prmem.h"
+#include "nsCOMPtr.h"
+#include "nsINetService.h"
+#include "nsIStringBundle.h"
+#include "nsMsgComposeStringBundle.h"
+#include "nsIServiceManager.h"
+#include "nsIPref.h"
+
+/* This is the next generation string retrieval call */
+static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
+static NS_DEFINE_CID(kNetServiceCID, NS_NETSERVICE_CID);
+static NS_DEFINE_IID(kIPrefIID, NS_IPREF_IID);
+static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
+
+#define COMPOSE_BE_URL "resource:/res/mailnews/messenger/compose_be.properties"
+
+extern "C"
+char *
+ComposeBEGetStringByIDREAL(PRInt32 stringID)
+{
+ nsresult res;
+ char* propertyURL = NULL;
+
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &res);
+ if (NS_SUCCEEDED(res) && prefs)
+ res = prefs->CopyCharPref("mail.strings.compose_be", &propertyURL);
+
+ if (!NS_SUCCEEDED(res) || !prefs)
+ propertyURL = COMPOSE_BE_URL;
+
+ NS_WITH_SERVICE(nsINetService, pNetService, kNetServiceCID, &res);
+ if (!NS_SUCCEEDED(res) || (nsnull == pNetService))
+ {
+ return PL_strdup("???"); // Don't I18N this string...failsafe return value
+ }
+
+ NS_WITH_SERVICE(nsIStringBundleService, sBundleService, kStringBundleServiceCID, &res);
+ if (NS_SUCCEEDED(res) && (nsnull != sBundleService))
+ {
+ nsIURL *url = nsnull;
+ nsILocale *locale = nsnull;
+
+ res = pNetService->CreateURL(&url, nsString(propertyURL), nsnull, nsnull, nsnull);
+ // cleanup...if necessary
+ if (propertyURL != COMPOSE_BE_URL)
+ PR_FREEIF(propertyURL);
+
+ // Cleanup property URL
+ PR_FREEIF(propertyURL);
+
+ if (NS_FAILED(res))
+ {
+ return PL_strdup("???"); // Don't I18N this string...failsafe return value
+ }
+
+ nsIStringBundle* sBundle = nsnull;
+ res = sBundleService->CreateBundle(url, locale, &sBundle);
+ if (NS_FAILED(res))
+ {
+ return PL_strdup("???"); // Don't I18N this string...failsafe return value
+ }
+
+ nsAutoString v("");
+ res = sBundle->GetStringFromID(stringID, v);
+ if (NS_FAILED(res))
+ {
+ char buf[128];
+
+ PR_snprintf(buf, sizeof(buf), "[StringID %d?]", stringID);
+ return PL_strdup(buf);
+ }
+
+ // Here we need to return a new copy of the string
+ char *returnBuffer = NULL;
+ PRInt32 bufferLen = v.Length() + 1;
+
+ returnBuffer = (char *)PR_MALLOC(bufferLen);
+ if (returnBuffer)
+ {
+ v.ToCString(returnBuffer, bufferLen);
+ return returnBuffer;
+ }
+ }
+
+ return PL_strdup("???"); // Don't I18N this string...failsafe return value
+}
+
+extern "C"
+char *
+ComposeBEGetStringByID(PRInt32 stringID)
+{
+ if (-1000 == stringID) return PL_strdup("Application is out of memory.");
+ if (-1001 == stringID) return PL_strdup("Unable to open the temporary file\n.\n%s\nCheck your `Temporary Directory' setting and try again.");
+ if (-1002 == stringID) return PL_strdup("Error writing temporary file.");
+ if (1000 == stringID) return PL_strdup("Subject");
+ if (1001 == stringID) return PL_strdup("Resent-Comments");
+ if (1002 == stringID) return PL_strdup("Resent-Date");
+ if (1003 == stringID) return PL_strdup("Resent-Sender");
+ if (1004 == stringID) return PL_strdup("Resent-From");
+ if (1005 == stringID) return PL_strdup("Resent-To");
+ if (1006 == stringID) return PL_strdup("Resent-CC");
+ if (1007 == stringID) return PL_strdup("Date");
+ if (1008 == stringID) return PL_strdup("Sender");
+ if (1009 == stringID) return PL_strdup("From");
+ if (1010 == stringID) return PL_strdup("Reply-To");
+ if (1011 == stringID) return PL_strdup("Organization");
+ if (1012 == stringID) return PL_strdup("To");
+ if (1013 == stringID) return PL_strdup("CC");
+ if (1014 == stringID) return PL_strdup("Newsgroups");
+ if (1015 == stringID) return PL_strdup("Followup-To");
+ if (1016 == stringID) return PL_strdup("References");
+ if (1017 == stringID) return PL_strdup("Name");
+ if (1018 == stringID) return PL_strdup("Type");
+ if (1019 == stringID) return PL_strdup("Encoding");
+ if (1020 == stringID) return PL_strdup("Description");
+ if (1021 == stringID) return PL_strdup("Message-ID");
+ if (1022 == stringID) return PL_strdup("Resent-Message-ID");
+ if (1023 == stringID) return PL_strdup("BCC");
+ if (1024 == stringID) return PL_strdup("Download Status");
+ if (1025 == stringID) return PL_strdup("Not Downloaded Inline");
+ if (1026 == stringID) return PL_strdup("Link to Document");
+ if (1027 == stringID) return PL_strdup("Document Info:");
+ if (1028 == stringID) return PL_strdup("Attachment");
+ if (1029 == stringID) return PL_strdup("forward.msg");
+ if (1030 == stringID) return PL_strdup("Add %s to your Address Book");
+ if (1031 == stringID) return PL_strdup(" Internal");
+ if (1032 == stringID) return PL_strdup("In message wrote:
");
+ if (1033 == stringID) return PL_strdup(" wrote:
");
+ if (1034 == stringID) return PL_strdup("(no headers)");
+ if (1035 == stringID) return PL_strdup("Toggle Attachment Pane");
+
+ char buf[128];
+
+ PR_snprintf(buf, sizeof(buf), "[StringID %d?]", stringID);
+ return PL_strdup(buf);
+}
diff --git a/mailnews/compose/src/nsMsgComposeStringBundle.h b/mailnews/compose/src/nsMsgComposeStringBundle.h
new file mode 100644
index 000000000000..e3a03eba2de1
--- /dev/null
+++ b/mailnews/compose/src/nsMsgComposeStringBundle.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgComposeStringBundle_H_
+#define _nsMsgComposeStringBundle_H_
+
+#include "nscore.h"
+
+NS_BEGIN_EXTERN_C
+
+char *ComposeBEGetStringByID(PRInt32 stringID);
+
+NS_END_EXTERN_C
+
+#endif /* _nsMsgComposeStringBundle_H_ */
diff --git a/mailnews/compose/src/nsMsgCopy.cpp b/mailnews/compose/src/nsMsgCopy.cpp
new file mode 100644
index 000000000000..54c93dc701a0
--- /dev/null
+++ b/mailnews/compose/src/nsMsgCopy.cpp
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsMsgCopy.h"
+#include "nsIPref.h"
+#include "nsMsgCompPrefs.h"
+#include "nsMsgCopy.h"
+
+//#include "nsCopyMessageStreamListener.h"
+#include "nsICopyMessageListener.h"
+
+static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
+
+/***
+nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ nsMsgCompPrefs pCompPrefs;
+ char* result = NULL;
+ PRBool useBcc, mailBccSelf, newsBccSelf = PR_FALSE;
+
+ if (newsBcc)
+ {
+ if (NS_SUCCEEDED(rv) && prefs)
+ {
+ prefs->GetBoolPref("news.use_default_cc", &useBcc);
+ }
+****/
+
+/*************
+
+nsresult
+CopyFileToFolder()
+{
+ NS_IMETHODIMP
+nsMsgAppCore::CopyMessages(nsIDOMXULElement *srcFolderElement, nsIDOMXULElement *dstFolderElement,
+ nsIDOMNodeList *nodeList, PRBool isMove)
+ nsresult rv;
+
+ if(!srcFolderElement || !dstFolderElement || !nodeList)
+ return NS_ERROR_NULL_POINTER;
+
+ nsIRDFResource *srcResource, *dstResource;
+ nsICopyMessageListener *dstFolder;
+ nsIMsgFolder *srcFolder;
+ nsISupportsArray *resourceArray;
+
+ if(NS_FAILED(rv = dstFolderElement->GetResource(&dstResource)))
+ return rv;
+
+ if(NS_FAILED(rv = dstResource->QueryInterface(nsICopyMessageListener::GetIID(), (void**)&dstFolder)))
+ return rv;
+
+ if(NS_FAILED(rv = srcFolderElement->GetResource(&srcResource)))
+ return rv;
+
+ if(NS_FAILED(rv = srcResource->QueryInterface(nsIMsgFolder::GetIID(), (void**)&srcFolder)))
+ return rv;
+
+ if(NS_FAILED(rv =ConvertDOMListToResourceArray(nodeList, &resourceArray)))
+ return rv;
+
+ //Call the mailbox service to copy first message. In the future we should call CopyMessages.
+ //And even more in the future we need to distinguish between the different types of URI's, i.e.
+ //local, imap, and news, and call the appropriate copy function.
+
+ PRUint32 cnt;
+ rv = resourceArray->Count(&cnt);
+ if (NS_SUCCEEDED(rv) && cnt > 0)
+ {
+ nsIRDFResource * firstMessage = (nsIRDFResource*)resourceArray->ElementAt(0);
+ char *uri;
+ firstMessage->GetValue(&uri);
+ nsCopyMessageStreamListener* copyStreamListener = new nsCopyMessageStreamListener(srcFolder, dstFolder, nsnull);
+
+ nsIMsgMessageService * messageService = nsnull;
+ rv = GetMessageServiceFromURI(uri, &messageService);
+
+ if (NS_SUCCEEDED(rv) && messageService)
+ {
+ nsIURL * url = nsnull;
+ messageService->CopyMessage(uri, copyStreamListener, isMove, nsnull, &url);
+ ReleaseMessageServiceFromURI(uri, messageService);
+ }
+
+ }
+
+ NS_RELEASE(srcResource);
+ NS_RELEASE(srcFolder);
+ NS_RELEASE(dstResource);
+ NS_RELEASE(dstFolder);
+ NS_RELEASE(resourceArray);
+ return rv;
+}
+
+FindFolderWithFlag
+nsIMsgHeader
+
+identity
+server (nsIMsgIncommingServer)
+folder (nsIMsgFolder)
+GetFolderWithFlags() - nsMsgFolderFlags.h (public)
+
+GetMessages() on folder
+
+nsIMessages returned
+get URI, key, header (nsIMsgHdr - )
+get message key
+
+nsMsg
+
+get POP service - extract from Berkely mail folder
+
+nsIPop3Service
+
+
+smtptest.cpp - setup as a url listener
+
+********/
diff --git a/mailnews/compose/src/nsMsgCopy.h b/mailnews/compose/src/nsMsgCopy.h
new file mode 100644
index 000000000000..69e645d8fba9
--- /dev/null
+++ b/mailnews/compose/src/nsMsgCopy.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgCopy_H_
+#define _nsMsgCopy_H_
+
+
+
+
+#endif /* _nsMsgCopy_H_ */
diff --git a/mailnews/compose/src/nsMsgCreate.cpp b/mailnews/compose/src/nsMsgCreate.cpp
new file mode 100644
index 000000000000..488c96508043
--- /dev/null
+++ b/mailnews/compose/src/nsMsgCreate.cpp
@@ -0,0 +1,746 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "rosetta_mailnews.h"
+#include "nsMsgSend.h"
+#include "nsMsgSendPart.h"
+#include "nsIPref.h"
+#include "nsMsgCompPrefs.h"
+#include "nsMsgCreate.h"
+
+static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
+
+
+static void
+msg_delete_attached_files(struct nsMsgAttachedFile *attachments)
+{
+ struct nsMsgAttachedFile *tmp;
+ if (!attachments) return;
+ for (tmp = attachments; tmp->orig_url; tmp++) {
+ PR_FREEIF(tmp->orig_url);
+ PR_FREEIF(tmp->type);
+ PR_FREEIF(tmp->real_name);
+ PR_FREEIF(tmp->encoding);
+ PR_FREEIF(tmp->description);
+ PR_FREEIF(tmp->x_mac_type);
+ PR_FREEIF(tmp->x_mac_creator);
+ if (tmp->file_name) {
+ PR_Delete(tmp->file_name);
+ PR_Free(tmp->file_name);
+ }
+ }
+ PR_FREEIF(attachments);
+}
+
+/**************
+
+PRInt32
+CreateVcardAttachment()
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ nsMsgCompPrefs pCompPrefs;
+ char* name;
+ int status = 0;
+
+ if (!m_haveAttachedVcard && AB_UserHasVCard() ) // don't attach a vcard if the user does not have a vcard
+ {
+
+ char * vCard = NULL;
+ char * filename = NULL;
+ AB_LoadIdentityVCard(&vCard);
+ if (vCard)
+ {
+ AB_ExportVCardToTempFile (vCard, &filename);
+ if (vCard)
+ PR_Free(vCard); // free our allocated VCardString...
+ char buf [ 2 * kMaxFullNameLength ];
+ if (pCompPrefs.GetUserFullName())
+ name = PL_strdup (pCompPrefs.GetUserFullName());
+ // write out a content description string
+#ifdef UNREADY_CODE
+ PR_snprintf(buf, sizeof(buf), XP_GetString (MK_ADDR_BOOK_CARD), name);
+#endif
+ PR_FREEIF(name);
+
+
+ char* temp = WH_FileName(filename, xpFileToPost);
+ char * fileurl = NULL;
+ if (temp)
+ {
+ fileurl = XP_PlatformFileToURL (temp);
+ PR_Free(temp);
+ }
+ else
+ return -1;
+
+ // Send the vCard out with a filename which distinguishes this user. e.g. jsmith.vcf
+ // The main reason to do this is for interop with Eudora, which saves off
+ // the attachments separately from the message body
+ char *vCardFileName = NULL;
+ char *mailIdentityUserEmail = NULL;
+ char *atSign = NULL;
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->CopyCharPref("mail.identity.useremail", &mailIdentityUserEmail);
+ if (mailIdentityUserEmail)
+ {
+ atSign = PL_strchr(mailIdentityUserEmail, '@');
+ if (atSign) *atSign = 0;
+ vCardFileName = PR_smprintf ("%s.vcf", mailIdentityUserEmail);
+ PR_Free(mailIdentityUserEmail);
+ }
+ if (!vCardFileName)
+ {
+ vCardFileName = PL_strdup("vcard.vcf");
+ if (!vCardFileName)
+ return MK_OUT_OF_MEMORY;
+ }
+
+ char * origurl = XP_PlatformFileToURL (vCardFileName);
+ int datacount = 0, filecount = 0;
+ for (nsMsgAttachmentData *tmp1 = m_attachData; tmp1 && tmp1->url; tmp1++) datacount++;
+ for (nsMsgAttachedFile *tmp = m_attachedFiles; tmp && tmp->orig_url; tmp++) filecount++;
+
+ nsMsgAttachmentData *alist;
+ if (datacount) {
+ alist = (nsMsgAttachmentData *)
+ PR_REALLOC(m_attachData, (datacount + 2) * sizeof(nsMsgAttachmentData));
+ }
+ else {
+ alist = (nsMsgAttachmentData *)
+ PR_Malloc((datacount + 2) * sizeof(nsMsgAttachmentData));
+ }
+ if (!alist)
+ return MK_OUT_OF_MEMORY;
+ m_attachData = alist;
+ memset (m_attachData + datacount, 0, 2 * sizeof (nsMsgAttachmentData));
+ m_attachData[datacount].url = fileurl;
+ m_attachData[datacount].real_type = PL_strdup(vCardMimeFormat);
+ m_attachData[datacount].description = PL_strdup (buf);
+ m_attachData[datacount].real_name = PL_strdup (vCardFileName);
+ m_attachData[datacount + 1].url = NULL;
+
+ nsMsgAttachedFile *aflist;
+ if (filecount) {
+ aflist = (struct nsMsgAttachedFile *)
+ PR_REALLOC(m_attachedFiles, (filecount + 2) * sizeof(nsMsgAttachedFile));
+ }
+ else {
+ aflist = (struct nsMsgAttachedFile *)
+ PR_Malloc((filecount + 2) * sizeof(nsMsgAttachedFile));
+ }
+
+ if (!aflist)
+ return MK_OUT_OF_MEMORY;
+
+ m_attachedFiles = aflist;
+ memset (m_attachedFiles + filecount, 0, 2 * sizeof (nsMsgAttachedFile));
+ m_attachedFiles[filecount].orig_url = origurl;
+ m_attachedFiles[filecount].file_name = filename;
+ m_attachedFiles[filecount].type = PL_strdup(vCardMimeFormat);
+ m_attachedFiles[filecount].description = PL_strdup (buf);
+ m_attachedFiles[filecount].real_name = PL_strdup (vCardFileName);
+ m_attachedFiles[filecount + 1].orig_url = NULL;
+
+ m_haveAttachedVcard = PR_TRUE;
+
+ PR_Free(vCardFileName);
+ }
+ }
+ return status;
+}
+
+
+
+char*
+FigureBcc(PRBool newsBcc)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ nsMsgCompPrefs pCompPrefs;
+ char* result = NULL;
+ PRBool useBcc, mailBccSelf, newsBccSelf = PR_FALSE;
+
+ if (newsBcc)
+ {
+ if (NS_SUCCEEDED(rv) && prefs)
+ {
+ prefs->GetBoolPref("news.use_default_cc", &useBcc);
+ }
+ }
+ else
+ {
+ if (NS_SUCCEEDED(rv) && prefs)
+ {
+ prefs->GetBoolPref("mail.use_default_cc", &useBcc);
+ }
+ }
+
+ prefs->GetBoolPref("mail.cc_self", &mailBccSelf);
+ prefs->GetBoolPref("news.cc_self", &newsBccSelf);
+
+ if (useBcc || mailBccSelf || newsBccSelf )
+ {
+ const char* tmp = useBcc ?
+ GetPrefs()->GetDefaultHeaderContents(
+ newsBcc ? MSG_NEWS_BCC_HEADER_MASK : MSG_BCC_HEADER_MASK) : NULL;
+
+ if (! (mailBccSelf || newsBccSelf) )
+ {
+ result = PL_strdup(tmp ? tmp : "");
+ }
+ else if (!tmp || !*tmp)
+ {
+ result = PL_strdup(pCompPrefs.GetUserEmail());
+ }
+ else
+ {
+ result = PR_smprintf("%s, %s", pCompPrefs.GetUserEmail(), tmp);
+ }
+ }
+ return result;
+}
+
+void
+InitializeHeaders(MWContext* old_context, const nsIMsgCompFields* fields)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+ nsMsgCompPrefs pCompPrefs;
+
+ PR_ASSERT(m_fields == NULL);
+ PR_ASSERT(m_initfields == NULL);
+
+ const char *real_addr = pCompPrefs.GetUserEmail();
+ char *real_return_address;
+ const char* sig;
+ PRBool forward_quoted;
+ forward_quoted = PR_FALSE;
+
+ m_fields = new nsMsgCompFields;
+ if (!m_fields)
+ return;
+ m_fields->AddRef();
+ if (fields)
+ m_fields->Copy((nsIMsgCompFields*)fields);
+ m_fields->SetOwner(this);
+
+ m_oldContext = old_context;
+ // hack for forward quoted. Checks the attachment field for a cookie
+ // string indicating that this is a forward quoted operation. If a cookie
+ // is found, the attachment string is slid back down over the cookie. This
+ // will put the original string back in tact.
+
+ const char* attachment = m_fields->GetAttachments();
+
+ if (attachment && *attachment) {
+ if (!PL_strncmp(attachment, MSG_FORWARD_COOKIE,
+ PL_strlen(MSG_FORWARD_COOKIE))) {
+ attachment += PL_strlen(MSG_FORWARD_COOKIE);
+ forward_quoted = PR_TRUE; // set forward with quote flag
+ m_fields->SetAttachments((char *)attachment, NULL);
+ attachment = m_fields->GetAttachments();
+ }
+ }
+
+ m_status = -1;
+
+ if (MISC_ValidateReturnAddress(old_context, real_addr) < 0) {
+ return;
+ }
+
+//JFD
+// real_return_address = MIME_MakeFromField(old_context->win_csid);
+// real_return_address = (char *)pCompPrefs.GetUserEmail();
+
+ PR_ASSERT (m_context->type == MWContextMessageComposition);
+ PR_ASSERT (XP_FindContextOfType(0, MWContextMessageComposition));
+ PR_ASSERT (!m_context->msg_cframe);
+
+
+ PRInt32 count = m_fields->GetNumForwardURL();
+ if (count > 0) {
+ // if forwarding one or more messages
+ PR_ASSERT(*attachment == '\0');
+ nsMsgAttachmentData *alist = (struct nsMsgAttachmentData *)
+ PR_Malloc((count + 1) * sizeof(nsMsgAttachmentData));
+ if (alist) {
+ memset(alist, 0, (count + 1) * sizeof(*alist));
+ for (count--; count >= 0; count--) {
+ alist[count].url = (char*) m_fields->GetForwardURL(count);
+ alist[count].real_name = (char*) m_fields->GetForwardURL(count);
+ }
+ SetAttachmentList(alist);
+ // Don't call msg_free_attachment_list because we are not duplicating
+ // url & real_name
+ PR_Free(alist);;
+ }
+ } else if (*attachment) {
+ // forwarding a single url
+ // typically a web page
+ nsMsgAttachmentData *alist;
+ count = 1;
+ alist = (struct nsMsgAttachmentData *)
+ PR_Malloc((count + 1) * sizeof(nsMsgAttachmentData));
+ if (alist) {
+ memset(alist, 0, (count + 1) * sizeof(*alist));
+ alist[0].url = (char *)attachment;
+ alist[0].real_name = (char *)attachment;
+ SetAttachmentList(alist);
+ // Don't call msg_free_attachment_list because we are not duplicating
+ // url & real_name
+ PR_Free(alist);
+ }
+ } // else if (*attachment)
+
+ if (*attachment) {
+ if (*attachment != '(') {
+ m_defaultUrl = PL_strdup(attachment);
+ }
+ }
+ else if (old_context) {
+ History_entry *h = SHIST_GetCurrent(&old_context->hist);
+ if (h && h->address) {
+ m_defaultUrl = PL_strdup(h->address);
+ }
+ if (m_defaultUrl)
+ {
+ MSG_Pane *msg_pane = MSG_FindPane(old_context,
+ MSG_MESSAGEPANE);
+ if (msg_pane)
+ m_fields->SetHTMLPart((char *)msg_pane->GetHTMLPart(), NULL);
+ }
+ }
+
+ if (!*m_fields->GetFrom()) {
+ m_fields->SetFrom(real_return_address, NULL);
+ }
+
+ // Guess what kind of reply this is based on the headers we passed in.
+
+
+ const char* newsgroups = m_fields->GetNewsgroups();
+ const char* to = m_fields->GetTo();
+ const char* cc = m_fields->GetCc();
+ const char* references = m_fields->GetReferences();
+
+ if (count > 0 || *attachment) {
+ // if an attachment exists and the forward_quoted flag is set, this
+ is a forward quoted operation.
+ if (forward_quoted) {
+ m_replyType = MSG_ForwardMessageQuoted;
+ // clear out the attachment list for forward quoted messages.
+ SetAttachmentList(NULL);
+ m_pendingAttachmentsCount = 0;
+ } else {
+ m_replyType = MSG_ForwardMessageAttachment;
+ }
+ } else if (*references && *newsgroups && (*to || *cc)) {
+ m_replyType = MSG_PostAndMailReply;
+ } else if (*references && *newsgroups) {
+ m_replyType = MSG_PostReply;
+ } else if (*references && *cc) {
+ m_replyType = MSG_ReplyToAll;
+ } else if (*references && *to) {
+ m_replyType = MSG_ReplyToSender;
+ } else if (*newsgroups) {
+ m_replyType = MSG_PostNew;
+ } else {
+ m_replyType = MSG_MailNew;
+ }
+
+
+#ifdef UNREADY_CODE
+ HJ77855
+#endif
+
+ if (!*m_fields->GetOrganization()) {
+ m_fields->SetOrganization((char *)pCompPrefs.GetOrganization(), NULL);
+ }
+
+ if (!*m_fields->GetReplyTo()) {
+ m_fields->
+ SetReplyTo((char *)GetPrefs()->
+ GetDefaultHeaderContents(MSG_REPLY_TO_HEADER_MASK), NULL);
+ }
+ if (!*m_fields->GetFcc())
+ {
+ PRBool useDefaultFcc = PR_TRUE;
+ // int prefError =
+ if (NS_SUCCEEDED(rv) && prefs)
+ {
+ prefs->GetBoolPref(*newsgroups ? "news.use_fcc" : "mail.use_fcc",
+ &useDefaultFcc);
+ }
+
+ if (useDefaultFcc)
+ {
+ m_fields->SetFcc((char *)GetPrefs()->
+ GetDefaultHeaderContents(*newsgroups ?
+ MSG_NEWS_FCC_HEADER_MASK : MSG_FCC_HEADER_MASK), NULL);
+ }
+ }
+ if (!*m_fields->GetBcc()) {
+ char* bcc = FigureBcc(*newsgroups);
+ m_fields->SetBcc(bcc, NULL);
+ PR_FREEIF(bcc);
+ }
+
+ m_fields->SetFcc((char *)CheckForLosingFcc(m_fields->GetFcc()), NULL);
+
+ {
+ const char *body = m_fields->GetDefaultBody();
+ if (body && *body)
+ {
+ m_fields->AppendBody((char *)body);
+ m_fields->AppendBody(MSG_LINEBREAK);
+ // m_bodyEdited = PR_TRUE;
+ }
+ }
+
+ sig = FE_UsersSignature ();
+ if (sig && *sig) {
+ m_fields->AppendBody(MSG_LINEBREAK);
+ //If the sig doesn't begin with "--" followed by whitespace or a
+ // newline, insert "-- \n" (the pseudo-standard sig delimiter.)
+ if (sig[0] != '-' || sig[1] != '-' ||
+ (sig[2] != ' ' && sig[2] != CR && sig[2] != LF)) {
+ m_fields->AppendBody("-- " MSG_LINEBREAK);
+ }
+ m_fields->AppendBody((char *)sig);
+ }
+
+ PR_FREEIF (real_return_address);
+
+
+ if (m_context)
+ FE_SetDocTitle(m_context, (char*) GetWindowTitle());
+
+
+ m_initfields = new nsMsgCompFields;
+ if (m_initfields) {
+ m_initfields->AddRef();
+ m_fields->Copy((nsIMsgCompFields*)m_fields);
+ m_initfields->SetOwner(this);
+ }
+}
+
+PRBool
+ShouldAutoQuote() {
+ if (m_haveQuoted) return PR_FALSE;
+ if (m_replyType == MSG_ForwardMessageQuoted ||
+ GetPrefs()->GetAutoQuoteReply()) {
+ switch (m_replyType) {
+ case MSG_ForwardMessageQuoted:
+ case MSG_PostAndMailReply:
+ case MSG_PostReply:
+ case MSG_ReplyToAll:
+ case MSG_ReplyToSender:
+ return PR_TRUE;
+
+ default:
+ break;
+ }
+ }
+ return PR_FALSE;
+}
+
+
+PRBool nsMsgCompose::SanityCheckNewsgroups (const char *newsgroups)
+{
+ // This function just does minor syntax checking on the names of newsgroup
+ // to make sure they conform to Son Of 1036:
+ // http://www.stud.ifi.uio.no/~larsi/notes/son-of-rfc1036.txt
+ //
+ // It isn't really possible to tell whether the group actually exists,
+ // so we're not going to try.
+ //
+ // According to the URL given above, uppercase characters A-Z are not
+ // allowed in newsgroup names, but when we tried to enforce that, we got
+ // bug reports from people who were trying to post to groups with capital letters
+
+ PRBool valid = PR_TRUE;
+ if (newsgroups)
+ {
+ while (*newsgroups && valid)
+ {
+ if (!(*newsgroups >= 'a' && *newsgroups <= 'z') && !(*newsgroups >= 'A' && *newsgroups <= 'Z'))
+ {
+ if (!(*newsgroups >= '0' && *newsgroups <= '9'))
+ {
+ switch (*newsgroups)
+ {
+ case '+':
+ case '-':
+ case '/':
+ case '_':
+ case '=':
+ case '?':
+ case '.':
+ break; // valid char
+ case ' ':
+ case ',':
+ break; // ok to separate names in list
+ default:
+ valid = PR_FALSE;
+ }
+ }
+ }
+ newsgroups++;
+ }
+ }
+ return valid;
+}
+
+int
+MungeThroughRecipients(PRBool* someNonHTML,
+ PRBool* groupNonHTML)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ PRBool foo;
+ if (!someNonHTML) someNonHTML = &foo;
+ if (!groupNonHTML) groupNonHTML = &foo;
+ *someNonHTML = PR_FALSE;
+ *groupNonHTML = PR_FALSE;
+ int status = 0;
+ char* names = NULL;
+ char* addresses = NULL;
+ const char* groups;
+ char* name = NULL;
+ char* end;
+ PRBool match = PR_FALSE;
+ m_host = NULL; // Pure paranoia, in case we some day actually
+ // have a UI that lets people change this.
+
+ static PRInt32 masks[] = {
+ MSG_TO_HEADER_MASK,
+ MSG_CC_HEADER_MASK,
+ MSG_BCC_HEADER_MASK
+ };
+ char* domainlist = NULL;
+
+ delete m_htmlrecip;
+ m_htmlrecip = new nsMsgHTMLRecipients();
+ if (!m_htmlrecip) return MK_OUT_OF_MEMORY;
+
+ PRUint32 i;
+ for (i=0 ; i < sizeof(masks) / sizeof(masks[0]) ; i++) {
+ const char* orig = m_fields->GetHeader(masks[i]);
+ if (!orig || !*orig) continue;
+ char* value = NULL;
+ value = PL_strdup(orig);
+ if (!value) {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ int num = 0 // JFD = MSG_ParseRFC822Addresses(value, &names, &addresses);
+ PR_Free(value);
+ value = NULL;
+ char* addr = NULL;
+ for (int j=0 ; jAddOne(tmp, addr, Address, match);
+ if (status < 0) goto FAIL;
+ PR_Free(tmp);
+ tmp = NULL;
+
+ if (!at) {
+ // ###tw We got to decide what to do in these cases. But
+ // for now, I'm just gonna ignore them. Which is probably
+ // exactly the wrong thing. Fortunately, these cases are
+ // now very rare, as we have code that inserts a default
+ // domain.
+ continue;
+ }
+ if (!domainlist) {
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->CopyCharPref("mail.htmldomains", &domainlist);
+ }
+ char* domain = at + 1;
+ for (;;) {
+ char* dot = PL_strchr(domain, '.');
+ if (!dot) break;
+ PRInt32 domainlength = PL_strlen(domain);
+ char* ptr;
+ char* endptr = NULL;
+ PRBool found = PR_FALSE;
+ for (ptr = domainlist ; ptr && *ptr ; ptr = endptr) {
+ endptr = PL_strchr(ptr, ',');
+ int length;
+ if (endptr) {
+ length = endptr - ptr;
+ endptr++;
+ } else {
+ length = PL_strlen(ptr);
+ }
+ if (length == domainlength) {
+ if (PL_strncasecmp(domain, ptr, length) == 0) {
+ found = PR_TRUE;
+ match = PR_TRUE;
+ break;
+ }
+ }
+ }
+#ifdef UNREADY_CODE
+ char* tmp = PR_smprintf("%s@%s",
+ XP_GetString(MK_MSG_EVERYONE),
+ domain);
+#endif
+ if (!tmp) return MK_OUT_OF_MEMORY;
+ status = m_htmlrecip->AddOne(domain, tmp, Domain, found);
+ PR_Free(tmp);
+ if (status < 0) goto FAIL;
+ domain = dot + 1;
+ }
+ if (!match) *someNonHTML = PR_TRUE;
+ }
+ }
+
+ groups = m_fields->GetHeader(MSG_NEWSGROUPS_HEADER_MASK);
+ if (groups && *groups && !m_host)
+ {
+ m_host = InferNewsHost (groups);
+ if (!m_host)
+ goto FAIL;
+ }
+
+ end = NULL;
+ for ( ; groups && *groups ; groups = end) {
+ end = PL_strchr(groups, ',');
+ if (end) *end = '\0';
+ name = PL_strdup(groups);
+ if (end) *end++ = ',';
+ if (!name) {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+ char* group = XP_StripLine(name);
+ match = m_host->IsHTMLOKGroup(group);
+
+ status = m_htmlrecip->AddOne(group, group, Newsgroup, match);
+ if (status < 0) goto FAIL;
+ char* tmp = PL_strdup(group);
+ if (!tmp) {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ for (;;) {
+ PRBool found = m_host->IsHTMLOKTree(tmp);
+
+ char* desc = PR_smprintf("%s.*", tmp);
+ if (!desc) {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+ status = m_htmlrecip->AddOne(tmp, desc, GroupHierarchy, found);
+
+ PR_Free(desc);
+ if (status < 0) {
+ PR_Free(tmp);
+ tmp = NULL;
+ goto FAIL;
+ }
+ if (found) match = PR_TRUE;
+
+ char* p = PL_strrchr(tmp, '.');
+ if (p) *p = '\0';
+ else break;
+ }
+ PR_Free(tmp);
+ tmp = NULL;
+ if (!match) {
+ *someNonHTML = PR_TRUE;
+ *groupNonHTML = PR_TRUE;
+ }
+ }
+
+ FAIL:
+ PR_FREEIF(names);
+ PR_FREEIF(domainlist);
+ PR_FREEIF(addresses);
+ PR_FREEIF(name);
+ return status;
+}
+
+
+
+MSG_HTMLComposeAction
+DetermineHTMLAction()
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ PRBool someNonHTML, groupNonHTML;
+ int status;
+
+ MSG_HTMLComposeAction result = GetHTMLAction();
+
+
+ if (result == MSG_HTMLAskUser) {
+ // Well, before we ask, see if we can figure out what to do for
+ // ourselves.
+
+ status = MungeThroughRecipients(&someNonHTML, &groupNonHTML);
+ if (status < 0) return MSG_HTMLAskUser; // ###
+ if (!someNonHTML) return MSG_HTMLSendAsHTML;
+ if (HasNoMarkup()) {
+ // No point in sending this message as HTML; send it plain.
+ return MSG_HTMLConvertToPlaintext;
+ }
+ // See if a preference has been set to tell us what to do. Note that
+ // we do not honor that preference for newsgroups, only for e-mail
+ // addresses.
+ if (!groupNonHTML) {
+ PRInt32 value = 0;
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->GetIntPref("mail.default_html_action", &value);
+ if (value >= 0) {
+ switch (value) {
+ case 1: // Force plaintext.
+ return MSG_HTMLConvertToPlaintext;
+ case 2: // Force HTML.
+ return MSG_HTMLSendAsHTML;
+ case 3: // Force multipart/alternative.
+ return MSG_HTMLUseMultipartAlternative;
+ }
+ }
+ }
+ }
+ return result;
+}
+**/
+
diff --git a/mailnews/compose/src/nsMsgCreate.h b/mailnews/compose/src/nsMsgCreate.h
new file mode 100644
index 000000000000..a221bb39b592
--- /dev/null
+++ b/mailnews/compose/src/nsMsgCreate.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgCreate_H_
+#define _nsMsgCreate_H_
+
+
+
+
+#endif /* _nsMsgCreate_H_ */
diff --git a/mailnews/compose/src/nsMsgDeliveryListener.cpp b/mailnews/compose/src/nsMsgDeliveryListener.cpp
new file mode 100644
index 000000000000..308434ae4886
--- /dev/null
+++ b/mailnews/compose/src/nsMsgDeliveryListener.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "prprf.h"
+#include "nsCOMPtr.h"
+#include "nsMsgDeliveryListener.h"
+#include "nsIMsgMailNewsUrl.h"
+#include "nsMsgPrompts.h"
+
+NS_IMPL_ISUPPORTS(nsMsgDeliveryListener, nsIUrlListener::GetIID())
+
+nsresult
+nsMsgDeliveryListener::OnStartRunningUrl(nsIURL * aUrl)
+{
+#ifdef NS_DEBUG
+ printf("Starting to run the delivery operation\n");
+#endif
+
+ return NS_OK;
+}
+
+nsresult
+nsMsgDeliveryListener::OnStopRunningUrl(nsIURL * aUrl, nsresult aExitCode)
+{
+ nsresult rv;
+#ifdef NS_DEBUG
+ printf("\nOnStopRunningUrl() called!\n");
+#endif
+
+ // First, stop being a listener since we are done.
+ if (aUrl)
+ {
+ // query it for a mailnews interface for now....
+ nsCOMPtr mailUrl = do_QueryInterface(aUrl);
+ if (mailUrl)
+ mailUrl->UnRegisterListener(this);
+ }
+
+ //
+ // Now, important, if there was a callback registered, call the
+ // creators exit routine.
+ //
+ if (mCompletionCallback)
+ rv = (*mCompletionCallback) (aUrl, aExitCode, mTagData);
+
+ return rv;
+}
+
+nsMsgDeliveryListener::nsMsgDeliveryListener(nsMsgDeliveryCompletionCallback callback,
+ nsMsgDeliveryType delivType, void *tagData)
+{
+ mTempFileSpec = nsnull;
+ mDeliveryType = delivType;
+ mTagData = tagData;
+ mCompletionCallback = callback;
+}
+
+nsMsgDeliveryListener::~nsMsgDeliveryListener()
+{
+ delete mTempFileSpec;
+}
+
diff --git a/mailnews/compose/src/nsMsgDeliveryListener.h b/mailnews/compose/src/nsMsgDeliveryListener.h
new file mode 100644
index 000000000000..46b7579285d1
--- /dev/null
+++ b/mailnews/compose/src/nsMsgDeliveryListener.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgDeliveryListener_H_
+#define _nsMsgDeliveryListener_H_
+
+#include "nsIUrlListener.h"
+#include "nsFileSpec.h"
+
+// For various delivery types
+enum nsMsgDeliveryType
+{
+ nsMailDelivery,
+ nsNewsDelivery,
+ nsLocalFCCDelivery,
+ nsImapFCCDelivery,
+ nsFileSaveDelivery,
+ nsExternalDelivery
+};
+
+//
+// This is the generic callback that will be called when the URL processing operation
+// is complete. The tagData is what was passed in by the caller at creation time.
+//
+typedef nsresult (*nsMsgDeliveryCompletionCallback) (nsIURL *aUrl, nsresult aExitCode, void *tagData);
+
+class nsMsgDeliveryListener: public nsIUrlListener
+{
+public:
+ nsMsgDeliveryListener(nsMsgDeliveryCompletionCallback callback,
+ nsMsgDeliveryType delivType,
+ void *tagData);
+ virtual ~nsMsgDeliveryListener();
+
+ NS_DECL_ISUPPORTS
+
+ // nsIUrlListener support
+ NS_IMETHOD OnStartRunningUrl(nsIURL * aUrl);
+ NS_IMETHOD OnStopRunningUrl(nsIURL * aUrl, nsresult aExitCode);
+
+private:
+ // Private Information
+ void *mTagData;
+ nsFileSpec *mTempFileSpec;
+ nsMsgDeliveryType mDeliveryType;
+ nsMsgDeliveryCompletionCallback mCompletionCallback;
+};
+
+
+#endif /* _nsMsgDeliveryListener_H_ */
diff --git a/mailnews/compose/src/nsMsgEncoders.cpp b/mailnews/compose/src/nsMsgEncoders.cpp
new file mode 100644
index 000000000000..901b25dcf1e1
--- /dev/null
+++ b/mailnews/compose/src/nsMsgEncoders.cpp
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "prprf.h"
+#include "prmem.h"
+#include "nsCOMPtr.h"
+#include "nsINetService.h"
+#include "nsIStringBundle.h"
+#include "nsMsgComposeStringBundle.h"
+#include "nsIServiceManager.h"
+#include "nsIMimeConverter.h"
+
+/* This is the next generation string retrieval call */
+static NS_DEFINE_CID(kCMimeConverterCID, NS_MIME_CONVERTER_CID);
+
+extern "C" MimeEncoderData *
+MIME_B64EncoderInit(int (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure)
+{
+ MimeEncoderData *returnEncoderData = nsnull;
+ nsIMimeConverter *converter;
+ nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
+ nsIMimeConverter::GetIID(), (void **)&converter);
+ if (NS_SUCCEEDED(res) && nsnull != converter)
+ {
+ res = converter->B64EncoderInit(output_fn, closure, &returnEncoderData);
+ NS_RELEASE(converter);
+ }
+ return NS_SUCCEEDED(res) ? returnEncoderData : nsnull;
+}
+
+extern "C" MimeEncoderData *
+MIME_QPEncoderInit(int (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure)
+{
+ MimeEncoderData *returnEncoderData = nsnull;
+ nsIMimeConverter *converter;
+ nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
+ nsIMimeConverter::GetIID(), (void **)&converter);
+ if (NS_SUCCEEDED(res) && nsnull != converter)
+ {
+ res = converter->QPEncoderInit(output_fn, closure, &returnEncoderData);
+ NS_RELEASE(converter);
+ }
+ return NS_SUCCEEDED(res) ? returnEncoderData : nsnull;
+}
+
+extern "C" MimeEncoderData *
+MIME_UUEncoderInit(char *filename, int (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure)
+{
+ MimeEncoderData *returnEncoderData = nsnull;
+ nsIMimeConverter *converter;
+ nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
+ nsIMimeConverter::GetIID(), (void **)&converter);
+ if (NS_SUCCEEDED(res) && nsnull != converter)
+ {
+ res = converter->UUEncoderInit(filename, output_fn, closure, &returnEncoderData);
+ NS_RELEASE(converter);
+ }
+ return NS_SUCCEEDED(res) ? returnEncoderData : nsnull;
+}
+
+extern "C" nsresult
+MIME_EncoderDestroy(MimeEncoderData *data, PRBool abort_p)
+{
+ MimeEncoderData *returnEncoderData = nsnull;
+ nsIMimeConverter *converter;
+ nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
+ nsIMimeConverter::GetIID(), (void **)&converter);
+ if (NS_SUCCEEDED(res) && nsnull != converter)
+ {
+ res = converter->EncoderDestroy(data, abort_p);
+ NS_RELEASE(converter);
+ }
+
+ return NS_SUCCEEDED(res) ? 0 : -1;
+}
diff --git a/mailnews/compose/src/nsMsgEncoders.h b/mailnews/compose/src/nsMsgEncoders.h
new file mode 100644
index 000000000000..efcf8e2519c8
--- /dev/null
+++ b/mailnews/compose/src/nsMsgEncoders.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgEncoders_H_
+#define _nsMsgEncoders_H_
+
+extern "C" MimeEncoderData *
+MIME_B64EncoderInit(int (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure);
+
+extern "C" MimeEncoderData *
+MIME_QPEncoderInit(int (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure);
+
+extern "C" MimeEncoderData *
+MIME_UUEncoderInit(char *filename, int (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure);
+
+extern "C" nsresult
+MIME_EncoderDestroy(MimeEncoderData *data, PRBool abort_p);
+
+
+#endif /* _nsMsgEncoders_H_ */
diff --git a/mailnews/compose/src/nsMsgI18N.cpp b/mailnews/compose/src/nsMsgI18N.cpp
new file mode 100644
index 000000000000..4ce4a29c477d
--- /dev/null
+++ b/mailnews/compose/src/nsMsgI18N.cpp
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsISupports.h"
+#include "nsIServiceManager.h"
+#include "nsICharsetConverterManager.h"
+#include "nsIPref.h"
+#include "nsIMimeConverter.h"
+#include "msgCore.h"
+#include "rosetta_mailnews.h"
+#include "nsMsgCompose.h"
+#include "nsMsgI18N.h"
+
+static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
+static NS_DEFINE_CID(kCMimeConverterCID, NS_MIME_CONVERTER_CID);
+
+//
+// International functions necessary for composition
+//
+
+// Convert an unicode string to a C string with a given charset.
+nsresult ConvertFromUnicode(const nsString& aCharset,
+ const nsString& inString,
+ char** outCString)
+{
+ nsresult res;
+
+ NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
+
+ if(NS_SUCCEEDED(res) && (nsnull != ccm)) {
+ nsIUnicodeEncoder* encoder = nsnull;
+ nsString convCharset;
+
+ // map to converter charset
+ if (aCharset.EqualsIgnoreCase("us-ascii")) {
+ convCharset.SetString("iso-8859-1");
+ }
+ else {
+ convCharset = aCharset;
+ }
+
+ // get an unicode converter
+ res = ccm->GetUnicodeEncoder(&convCharset, &encoder);
+ if(NS_SUCCEEDED(res) && (nsnull != encoder)) {
+ const PRUnichar *unichars = inString.GetUnicode();
+ PRInt32 unicharLength = inString.Length();
+ PRInt32 dstLength;
+ res = encoder->GetMaxLength(unichars, unicharLength, &dstLength);
+ // allocale an output buffer
+ *outCString = (char *) PR_Malloc(dstLength + 1);
+ if (*outCString != nsnull) {
+ PRInt32 originalLength = unicharLength;
+ // convert from unicode
+ res = encoder->Convert(unichars, &unicharLength, *outCString, &dstLength);
+ // estimation of GetMaxLength was incorrect
+ if (unicharLength < originalLength) {
+ PR_Free(*outCString);
+ res = NS_ERROR_FAILURE;
+ }
+ else {
+ (*outCString)[dstLength] = '\0';
+ }
+ }
+ else {
+ res = NS_ERROR_OUT_OF_MEMORY;
+ }
+ NS_IF_RELEASE(encoder);
+ }
+ }
+ return res;
+}
+
+// Convert a C string to an unicode string.
+nsresult ConvertToUnicode(const nsString& aCharset,
+ const char* inCString,
+ nsString& outString)
+{
+ nsresult res;
+ NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
+
+ if(NS_SUCCEEDED(res) && (nsnull != ccm)) {
+ nsIUnicodeDecoder* decoder = nsnull;
+ PRUnichar *unichars;
+ PRInt32 unicharLength;
+ nsString convCharset;
+
+ // map to converter charset
+ if (aCharset.EqualsIgnoreCase("us-ascii")) {
+ convCharset.SetString("iso-8859-1");
+ }
+ else {
+ convCharset = aCharset;
+ }
+ // get an unicode converter
+ res = ccm->GetUnicodeDecoder(&convCharset, &decoder);
+ if(NS_SUCCEEDED(res) && (nsnull != decoder)) {
+ PRInt32 srcLen = PL_strlen(inCString);
+ res = decoder->Length(inCString, 0, srcLen, &unicharLength);
+ // allocale an output buffer
+ unichars = (PRUnichar *) PR_Malloc(unicharLength * sizeof(PRUnichar));
+ if (unichars != nsnull) {
+ // convert to unicode
+ res = decoder->Convert(unichars, 0, &unicharLength, inCString, 0, &srcLen);
+ outString.SetString(unichars, unicharLength);
+ PR_Free(unichars);
+ }
+ else {
+ res = NS_ERROR_OUT_OF_MEMORY;
+ }
+ NS_IF_RELEASE(decoder);
+ }
+ }
+ return res;
+}
+
+// Charset to be used for the internatl processing.
+const char *msgCompHeaderInternalCharset()
+{
+ // UTF-8 is a super set of us-ascii.
+ // We can use the same string manipulation methods as us-ascii without breaking non us-ascii characters.
+ return "UTF-8";
+}
+
+// MIME encoder, output string should be freed by PR_FREE
+char * nsMsgI18NEncodeMimePartIIStr(const char *header, const char *charset, PRBool bUseMime)
+{
+ // No MIME, just duplicate the string.
+ if (PR_FALSE == bUseMime) {
+ return PL_strdup(header);
+ }
+
+ char *encodedString = nsnull;
+ nsIMimeConverter *converter;
+ nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
+ nsIMimeConverter::GetIID(), (void **)&converter);
+ if (NS_SUCCEEDED(res) && nsnull != converter) {
+ res = converter->EncodeMimePartIIStr_UTF8(header, charset, kMIME_ENCODED_WORD_SIZE, &encodedString);
+ NS_RELEASE(converter);
+ }
+ return NS_SUCCEEDED(res) ? encodedString : nsnull;
+}
+
+// MIME decoder
+nsresult nsMsgI18NDecodeMimePartIIStr(const nsString& header, nsString& charset, nsString& decodedString)
+{
+ nsIMimeConverter *converter;
+ nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
+ nsIMimeConverter::GetIID(), (void **)&converter);
+ if (NS_SUCCEEDED(res) && nsnull != converter) {
+ res = converter->DecodeMimePartIIStr(header, charset, decodedString);
+ NS_RELEASE(converter);
+ }
+ return res;
+}
+
+// Get a default mail character set.
+char * nsMsgI18NGetDefaultMailCharset()
+{
+ nsresult res = NS_OK;
+ char * retVal = nsnull;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &res);
+ if (nsnull != prefs && NS_SUCCEEDED(res))
+ {
+ char *prefValue;
+ res = prefs->CopyCharPref("intl.character_set_name", &prefValue);
+
+ if (NS_SUCCEEDED(res))
+ {
+ //TODO: map to mail charset (e.g. Shift_JIS -> ISO-2022-JP) bug#3941.
+ retVal = prefValue;
+ }
+ else
+ retVal = PL_strdup("us-ascii");
+ }
+
+ return (nsnull != retVal) ? retVal : PL_strdup("us-ascii");
+}
+
+// Return True if a charset is stateful (e.g. JIS).
+PRBool nsMsgI18Nstateful_charset(const char *charset)
+{
+ //TODO: use charset manager's service
+ return (PL_strcasecmp(charset, "iso-2022-jp") == 0);
+}
+
+// Check 7bit in a given buffer.
+// This is expensive (both memory and performance).
+// The check would be very simple if applied to an unicode text (e.g. nsString or utf-8).
+// Possible optimazaion is to search ESC(0x1B) in case of iso-2022-jp and iso-2022-kr.
+// Or convert and check line by line.
+PRBool nsMsgI18N7bit_data_part(const char *charset, const char *inString, const PRUint32 size)
+{
+ char *aCString;
+ nsString aCharset(charset);
+ nsString outString;
+ nsresult res;
+
+ aCString = (char *) PR_Malloc(size + 1);
+ if (nsnull != aCString) {
+ PL_strncpy(aCString, inString, size); // make a C string
+ res = ConvertToUnicode(aCharset, aCString, outString);
+ PR_Free(aCString);
+ if (NS_SUCCEEDED(res)) {
+ for (PRInt32 i = 0; i < outString.Length(); i++) {
+ if (outString.CharAt(i) > 127) {
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ return PR_TRUE; // all 7 bit
+}
+
+// RICHIE - not sure about this one?? need to see what it did in the old
+// world.
+char *
+nsMsgI18NGetAcceptLanguage(void)
+{
+ return "en";
+}
+
+///////////////////////////////////////////////////////
+// RICHIE -MAKE THESE GO AWAY!!!!
+///////////////////////////////////////////////////////
+void nsMsgI18NDestroyCharCodeConverter(CCCDataObject) {return;}
+unsigned char * nsMsgI18NCallCharCodeConverter(CCCDataObject,const unsigned char *,int32) {return NULL;}
+int nsMsgI18NGetCharCodeConverter(int16 ,int16 ,CCCDataObject) {return nsnull;}
+CCCDataObject nsMsgI18NCreateCharCodeConverter() {return NULL;}
+int16 nsMsgI18NGetCSIWinCSID(INTL_CharSetInfo) {return 2;}
+INTL_CharSetInfo LO_GetDocumentCharacterSetInfo(MWContext *) {return NULL;}
+int16 nsMsgI18NGetCSIDocCSID(INTL_CharSetInfo obj) {return 2;}
+int16 nsMsgI18NDefaultWinCharSetID(MWContext *) {return 2;}
+int16 nsMsgI18NDefaultMailCharSetID(int16 csid) {return 2;}
+int16 nsMsgI18NDefaultNewsCharSetID(int16 csid) {return 2;}
+void nsMsgI18NMessageSendToNews(XP_Bool toNews) {return;}
+CCCDataObject nsMsgI18NCreateDocToMailConverter(iDocumentContext context, XP_Bool isHTML, unsigned char *buffer,
+ uint32 buffer_size) {return NULL;}
diff --git a/mailnews/compose/src/nsMsgI18N.h b/mailnews/compose/src/nsMsgI18N.h
new file mode 100644
index 000000000000..d8830d5daac1
--- /dev/null
+++ b/mailnews/compose/src/nsMsgI18N.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgI18N_H_
+#define _nsMsgI18N_H_
+
+NS_BEGIN_EXTERN_C
+
+char *nsMsgI18NEncodeMimePartIIStr(const char *header, const char *charset, PRBool bUseMime);
+PRBool nsMsgI18Nstateful_charset(const char *charset);
+PRBool nsMsgI18N7bit_data_part(const char *charset, const char *string, const PRUint32 size);
+char *nsMsgI18NGetAcceptLanguage(void);
+
+
+//
+// THIS IS BAD STUFF...MAKE IT GO AWAY!!!
+//
+void nsMsgI18NDestroyCharCodeConverter(CCCDataObject);
+unsigned char * nsMsgI18NCallCharCodeConverter(CCCDataObject,const unsigned char *,int32);
+int nsMsgI18NGetCharCodeConverter(int16 ,int16 ,CCCDataObject);
+CCCDataObject nsMsgI18NCreateCharCodeConverter();
+int16 nsMsgI18NGetCSIWinCSID(INTL_CharSetInfo);
+INTL_CharSetInfo LO_GetDocumentCharacterSetInfo(MWContext *);
+int16 nsMsgI18NGetCSIDocCSID(INTL_CharSetInfo obj);
+int16 nsMsgI18NDefaultWinCharSetID(MWContext *);
+int16 nsMsgI18NDefaultMailCharSetID(int16 csid);
+int16 nsMsgI18NDefaultNewsCharSetID(int16 csid);
+void nsMsgI18NMessageSendToNews(XP_Bool toNews);
+CCCDataObject nsMsgI18NCreateDocToMailConverter(iDocumentContext context, XP_Bool isHTML, unsigned char *buffer,
+ uint32 buffer_size);
+
+
+NS_END_EXTERN_C
+
+#endif /* _nsMsgI18N_H_ */
diff --git a/mailnews/compose/src/nsMsgPrompts.cpp b/mailnews/compose/src/nsMsgPrompts.cpp
new file mode 100644
index 000000000000..a4eae3049817
--- /dev/null
+++ b/mailnews/compose/src/nsMsgPrompts.cpp
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsMsgCopy.h"
+#include "nsIPref.h"
+#include "nsMsgCompPrefs.h"
+#include "nsMsgPrompts.h"
+#include "nsINetSupportDialogService.h"
+#include "nsMsgComposeStringBundle.h"
+
+static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID);
+
+nsresult
+nsMsgDisplayMessageByID(PRInt32 msgID)
+{
+ nsresult rv;
+
+ char *msg = ComposeBEGetStringByID(msgID);
+ if (!msg)
+ return NS_ERROR_FAILURE;
+
+ NS_WITH_SERVICE(nsINetSupportDialogService, dialog, kNetSupportDialogCID, &rv);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ nsAutoString alertText(msg);
+ if (dialog)
+ {
+ rv = dialog->Alert(alertText);
+ }
+
+ PR_FREEIF(msg);
+ return NS_OK;
+}
+
+nsresult
+nsMsgDisplayMessageByString(char *msg)
+{
+ nsresult rv;
+
+ if ((!msg) || (!*msg))
+ return NS_ERROR_FAILURE;
+
+ NS_WITH_SERVICE(nsINetSupportDialogService, dialog, kNetSupportDialogCID, &rv);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ nsAutoString alertText(msg);
+ if (dialog)
+ {
+ rv = dialog->Alert(alertText);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsMsgAskBooleanQuestionByID(PRInt32 msgID, PRBool *answer)
+{
+ nsresult rv;
+ PRInt32 result;
+
+ char *msg = ComposeBEGetStringByID(msgID);
+ if (!msg)
+ return NS_ERROR_FAILURE;
+
+ NS_WITH_SERVICE(nsINetSupportDialogService, dialog, kNetSupportDialogCID, &rv);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ nsAutoString confirmText(msg);
+ if (dialog)
+ {
+ rv = dialog->Confirm(confirmText, &result);
+ if (result == 1)
+ {
+ *answer = PR_TRUE;
+ }
+ else
+ {
+ *answer = PR_FALSE;
+ }
+ }
+
+ PR_FREEIF(msg);
+ return NS_OK;
+}
+
+nsresult
+nsMsgAskBooleanQuestionByID(char *msg, PRBool *answer)
+{
+ nsresult rv;
+ PRInt32 result;
+
+ if ((!msg) || (!*msg))
+ return NS_ERROR_FAILURE;
+
+ NS_WITH_SERVICE(nsINetSupportDialogService, dialog, kNetSupportDialogCID, &rv);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ nsAutoString confirmText(msg);
+ if (dialog)
+ {
+ rv = dialog->Confirm(confirmText, &result);
+ if (result == 1)
+ {
+ *answer = PR_TRUE;
+ }
+ else
+ {
+ *answer = PR_FALSE;
+ }
+ }
+
+ PR_FREEIF(msg);
+ return NS_OK;
+}
diff --git a/mailnews/compose/src/nsMsgPrompts.h b/mailnews/compose/src/nsMsgPrompts.h
new file mode 100644
index 000000000000..86f24df5fd4c
--- /dev/null
+++ b/mailnews/compose/src/nsMsgPrompts.h
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgPrompts_H_
+#define _nsMsgPrompts_H_
+
+nsresult nsMsgDisplayMessageByID(PRInt32 msgID);
+nsresult nsMsgDisplayMessageByString(char *msg);
+nsresult nsMsgAskBooleanQuestionByID(PRInt32 msgID, PRBool *answer);
+nsresult nsMsgAskBooleanQuestionByID(char *msg, PRBool *answer);
+
+#endif /* _nsMsgPrompts_H_ */
diff --git a/mailnews/compose/src/nsMsgSendLater.cpp b/mailnews/compose/src/nsMsgSendLater.cpp
new file mode 100644
index 000000000000..5a2ed95a559b
--- /dev/null
+++ b/mailnews/compose/src/nsMsgSendLater.cpp
@@ -0,0 +1,434 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsCOMPtr.h"
+#include "nsMsgCopy.h"
+#include "nsIPref.h"
+#include "nsMsgCompPrefs.h"
+#include "nsMsgSendLater.h"
+#include "nsIEnumerator.h"
+#include "nsIFileSpec.h"
+#include "nsISmtpService.h"
+#include "nsIMsgMailNewsUrl.h"
+#include "nsMsgDeliveryListener.h"
+#include "nsIMsgIncomingServer.h"
+#include "nsICopyMessageListener.h"
+#include "nsIMsgMessageService.h"
+
+#include "nsIMsgMailSession.h"
+#include "nsMsgBaseCID.h"
+
+
+static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
+static NS_DEFINE_CID(kCMsgMailSessionCID, NS_MSGMAILSESSION_CID);
+
+#include "nsIMsgAccountManager.h"
+
+nsIMsgFolder *
+GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity)
+{
+ nsresult rv = NS_OK;
+ nsIMsgFolder *msgFolder= nsnull;
+
+ //******************************************************************
+ // This should really be passed in, but for now, we are going
+ // to use this hack call...should go away!
+ //******************************************************************
+ // get the current identity from the mail session....
+/*****
+ NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kCMsgMailSessionCID, &rv);
+ if (NS_SUCCEEDED(rv) && mailSession)
+ rv = mailSession->GetCurrentIdentity(getter_AddRefs(identity));
+ if (NS_FAILED(rv))
+ return nsnull;
+ //******************************************************************
+ // This should really be passed in, but for now, we are going
+ // to use this hack call...should go away!
+ //******************************************************************
+
+ nsCOMPtr accountManager;
+ rv = mailSession->GetAccountManager(getter_AddRefs(accountManager));
+ if (NS_FAILED(rv))
+ return nsnull;
+
+ nsISupportsArray *retval;
+ accountManager->GetServersForIdentity(identity, &retval);
+
+ if (retval->ElementAt(0) != nsnull)
+ (retval->ElementAt(0))->QueryInterface(nsIMsgFolder::GetIID(), (void **)&msgFolder);
+**/
+ nsCOMPtr identity = nsnull;
+
+ NS_WITH_SERVICE(nsIMsgMailSession, session, kCMsgMailSessionCID, &rv);
+ if (NS_FAILED(rv)) return nsnull;
+ nsCOMPtr accountManager;
+ rv = session->GetAccountManager(getter_AddRefs(accountManager));
+ if (NS_FAILED(rv)) return nsnull;
+ rv = session->GetCurrentIdentity(getter_AddRefs(identity));
+ if (NS_FAILED(rv)) return nsnull;
+
+ nsISupportsArray *retval;
+ accountManager->GetServersForIdentity(identity, &retval);
+
+/**
+
+ nsIMsgIncomingServer * incomingServer = nsnull;
+ rv = mailSession->GetCurrentServer(&incomingServer);
+ if (NS_SUCCEEDED(rv) && incomingServer)
+ {
+ char * value = nsnull;
+ incomingServer->GetPrettyName(&value);
+ printf("Server pretty name: %s\n", value ? value : "");
+ incomingServer->GetUsername(&value);
+ printf("User Name: %s\n", value ? value : "");
+ incomingServer->GetHostName(&value);
+ printf("Pop Server: %s\n", value ? value : "");
+ incomingServer->GetPassword(&value);
+ printf("Pop Password: %s\n", value ? value : "");
+
+ nsIFolder *folder;
+ nsIFolder *aRootFolder;
+
+ incomingServer->GetRootFolder(&aRootFolder);
+ if (aRootFolder)
+ aRootFolder->FindSubFolder("Inbox", &folder);
+
+ NS_RELEASE(incomingServer);
+ }
+
+**/
+
+ return msgFolder;
+}
+
+static NS_DEFINE_CID(kSmtpServiceCID, NS_SMTPSERVICE_CID);
+
+nsresult
+SendIndividualMailFile()
+{
+ nsFileSpec fileSpec;
+ nsresult rv;
+
+// nsIFileSpec fileSpec (m_msg_file_name ? m_msg_file_name : ""); //need to convert to unix path
+// nsFilePath filePath (fileSpec);
+
+ NS_WITH_SERVICE(nsISmtpService, smtpService, kSmtpServiceCID, &rv);
+ if (NS_FAILED(rv) || !smtpService)
+ return NS_ERROR_FAILURE;
+
+// rv = smtpService->SaveMessageToDisk(filePath, buf, nsnull, nsnull);
+// SaveMessageToDisk(const char *aMessageURI, nsIFileSpec *aFile, PR_FALSE,
+ // nsIUrlListener *aUrlListener, nsnull);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ char *buf = "rhp@netscape.com";
+ nsFilePath filePath ("c:\\temp\\nsmail01.txt");
+ rv = smtpService->SendMailMessage(filePath, buf, nsnull, nsnull);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ return NS_OK;
+}
+
+//
+// If you pass in the user identity, then the "Outbox" will be
+// sent at this time.
+//
+nsresult
+SendUnsentMessages(nsIMsgIdentity *userIdentity)
+{
+ nsresult ret;
+ nsIMsgFolder *outboxFolder;
+ nsIEnumerator *enumerator = nsnull;
+
+ outboxFolder = GetUnsentMessagesFolder(userIdentity);
+ if (!outboxFolder)
+ return NS_ERROR_FAILURE;
+
+ //
+ // Now, enumerate over the messages and send each via
+ // SMTP...
+ //
+ ret = outboxFolder->GetMessages(&enumerator);
+ if (NS_SUCCEEDED(ret) && (enumerator))
+ {
+ for (enumerator->First(); enumerator->IsDone() != NS_OK; enumerator->Next())
+ {
+ nsIMsgDBHdr *pMessage = nsnull;
+ ret = enumerator->CurrentItem((nsISupports**)&pMessage);
+
+ NS_ASSERTION(NS_SUCCEEDED(ret), "nsMsgDBEnumerator broken");
+ if (NS_FAILED(ret))
+ break;
+
+ if (pMessage)
+ {
+ nsMsgKey key;
+ nsString subject;
+
+ (void)pMessage->GetMessageKey(&key);
+ pMessage->GetSubject(subject);
+
+ printf("message in thread %u %s\n", key, (const char *) &nsAutoString(subject));
+ }
+
+ pMessage = nsnull;
+ }
+
+ NS_RELEASE(enumerator);
+ }
+
+ return NS_OK;
+
+
+
+/*
+*/
+
+
+
+
+ /****
+ identity
+server (nsIMsgIncomingServer)
+folder (nsIMsgFolder)
+GetFolderWithFlags() - nsMsgFolderFlags.h (public)
+
+GetMessages() on folder
+
+nsIMessages returned
+get URI, key, header (nsIMsgHdr - )
+get message key
+
+nsMsg
+
+get POP service - extract from Berkely mail folder
+
+nsIPop3Service
+
+
+smtptest.cpp - setup as a url listener
+
+
+
+
+
+
+nsresult OnIdentityCheck()
+{
+ NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kCMsgMailSessionCID, &result);
+ if (NS_SUCCEEDED(result) && mailSession)
+ {
+ // mscott: we really don't check an identity, we check
+ // for an outgoing
+ result = mailSession->GetCurrentServer(&incomingServer);
+ if (NS_SUCCEEDED(result) && incomingServer)
+ {
+ char * value = nsnull;
+ incomingServer->GetPrettyName(&value);
+ printf("Server pretty name: %s\n", value ? value : "");
+ incomingServer->GetUsername(&value);
+ printf("User Name: %s\n", value ? value : "");
+ incomingServer->GetHostName(&value);
+ printf("Pop Server: %s\n", value ? value : "");
+ incomingServer->GetPassword(&value);
+ printf("Pop Password: %s\n", value ? value : "");
+
+ NS_RELEASE(incomingServer);
+ }
+ else
+ printf("Unable to retrieve the outgoing server interface....\n");
+ }
+ else
+ printf("Unable to retrieve the mail session service....\n");
+
+ return result;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NS_IMETHODIMP
+nsMsgAppCore::CopyMessages(nsIDOMXULElement *srcFolderElement, nsIDOMXULElement *dstFolderElement,
+ nsIDOMNodeList *nodeList, PRBool isMove)
+ nsresult rv;
+
+ if(!srcFolderElement || !dstFolderElement || !nodeList)
+ return NS_ERROR_NULL_POINTER;
+
+ nsIRDFResource *srcResource, *dstResource;
+ nsICopyMessageListener *dstFolder;
+ nsIMsgFolder *srcFolder;
+ nsISupportsArray *resourceArray;
+
+ if(NS_FAILED(rv = dstFolderElement->GetResource(&dstResource)))
+ return rv;
+
+ if(NS_FAILED(rv = dstResource->QueryInterface(nsICopyMessageListener::GetIID(), (void**)&dstFolder)))
+ return rv;
+
+ if(NS_FAILED(rv = srcFolderElement->GetResource(&srcResource)))
+ return rv;
+
+ if(NS_FAILED(rv = srcResource->QueryInterface(nsIMsgFolder::GetIID(), (void**)&srcFolder)))
+ return rv;
+
+ if(NS_FAILED(rv =ConvertDOMListToResourceArray(nodeList, &resourceArray)))
+ return rv;
+
+ //Call the mailbox service to copy first message. In the future we should call CopyMessages.
+ //And even more in the future we need to distinguish between the different types of URI's, i.e.
+ //local, imap, and news, and call the appropriate copy function.
+
+ PRUint32 cnt;
+ rv = resourceArray->Count(&cnt);
+ if (NS_SUCCEEDED(rv) && cnt > 0)
+ {
+ nsIRDFResource * firstMessage = (nsIRDFResource*)resourceArray->ElementAt(0);
+ char *uri;
+ firstMessage->GetValue(&uri);
+ nsCopyMessageStreamListener* copyStreamListener = new nsCopyMessageStreamListener(srcFolder, dstFolder, nsnull);
+
+ nsIMsgMessageService * messageService = nsnull;
+ rv = GetMessageServiceFromURI(uri, &messageService);
+
+ if (NS_SUCCEEDED(rv) && messageService)
+ {
+ nsIURL * url = nsnull;
+ messageService->CopyMessage(uri, copyStreamListener, isMove, nsnull, &url);
+ ReleaseMessageServiceFromURI(uri, messageService);
+ }
+
+ }
+
+ NS_RELEASE(srcResource);
+ NS_RELEASE(srcFolder);
+ NS_RELEASE(dstResource);
+ NS_RELEASE(dstFolder);
+ NS_RELEASE(resourceArray);
+ return rv;
+ **********/
+return NS_OK;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static NS_DEFINE_IID(kIMsgSendLater, NS_IMSGSENDLATER_IID);
+
+//
+// This function will be used by the factory to generate the
+// nsMsgComposeAndSend Object....
+//
+nsresult NS_NewMsgSendLater(const nsIID &aIID, void ** aInstancePtrResult)
+{
+ /* note this new macro for assertions...they can take a string describing the assertion */
+ NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr");
+ if (nsnull != aInstancePtrResult)
+ {
+ nsMsgSendLater *pSendLater = new nsMsgSendLater();
+ if (pSendLater)
+ return pSendLater->QueryInterface(kIMsgSendLater, aInstancePtrResult);
+ else
+ return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
+ }
+ else
+ return NS_ERROR_NULL_POINTER; /* aInstancePtrResult was NULL....*/
+}
+
+NS_IMPL_ISUPPORTS(nsMsgSendLater, nsIMsgSendLater::GetIID())
+
+nsMsgSendLater::nsMsgSendLater()
+{
+ mIdentity = nsnull;
+ mSmtpServer = nsnull;
+
+ NS_INIT_REFCNT();
+}
+
+nsMsgSendLater::~nsMsgSendLater()
+{
+ PR_FREEIF(mSmtpServer);
+}
+
+nsresult
+nsMsgSendLater::SendUnsentMessages(nsIMsgIdentity *identity, char *unsentFolder,
+ char *smtpServer)
+{
+ if ( (!identity) || (!smtpServer) || (!*smtpServer))
+ return NS_ERROR_FAILURE;
+
+ mIdentity = identity;
+ mSmtpServer = PL_strdup(smtpServer);
+ if (!mSmtpServer)
+ return NS_ERROR_FAILURE;
+
+ return NS_OK;
+}
+
diff --git a/mailnews/compose/src/nsMsgSendLater.h b/mailnews/compose/src/nsMsgSendLater.h
new file mode 100644
index 000000000000..0cfc992a6567
--- /dev/null
+++ b/mailnews/compose/src/nsMsgSendLater.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgSendLater_H_
+#define _nsMsgSendLater_H_
+
+#include "nsIMsgIdentity.h"
+#include "nsIMsgSendLater.h"
+
+class nsMsgSendLater: public nsIMsgSendLater
+{
+public:
+ nsMsgSendLater();
+ virtual ~nsMsgSendLater();
+
+ NS_DECL_ISUPPORTS
+
+ // nsIMsgSendLater support
+ NS_IMETHOD SendUnsentMessages(nsIMsgIdentity *identity, char *unsentFolder, char *smtpServer);
+
+private:
+ // Private Information
+ nsIMsgIdentity *mIdentity;
+ char *mSmtpServer;
+};
+
+
+#endif /* _nsMsgSendLater_H_ */
diff --git a/mailnews/compose/src/nsMsgUtils.cpp b/mailnews/compose/src/nsMsgUtils.cpp
new file mode 100644
index 000000000000..e110cbee3bb8
--- /dev/null
+++ b/mailnews/compose/src/nsMsgUtils.cpp
@@ -0,0 +1,1915 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsCOMPtr.h"
+#include "nsMsgUtils.h"
+#include "nsIPref.h"
+#include "prmem.h"
+#include "nsMsgSend.h"
+#include "nsINetService.h"
+#include "nsMsgCompose.h"
+#include "nsMailHeaders.h"
+#include "nsMsgI18N.h"
+#include "xp_time.h"
+#include "nsMsgCompPrefs.h"
+#include "nsIMsgHeaderParser.h"
+
+static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
+static NS_DEFINE_CID(kNetServiceCID, NS_NETSERVICE_CID);
+static NS_DEFINE_CID(kMsgHeaderParserCID, NS_MSGHEADERPARSER_CID);
+
+//
+// Hopefully, someone will write and XP call like this eventually!
+//
+#define TPATH_LEN 1024
+
+#ifdef WIN32
+#include "windows.h"
+#endif
+
+static char *
+GetTheTempDirectoryOnTheSystem(void)
+{
+ char *retPath = (char *)PR_Malloc(TPATH_LEN);
+ if (!retPath)
+ return nsnull;
+
+ retPath[0] = '\0';
+#ifdef WIN32
+ if (getenv("TEMP"))
+ PL_strncpy(retPath, getenv("TEMP"), TPATH_LEN); // environment variable
+ else if (getenv("TMP"))
+ PL_strncpy(retPath, getenv("TMP"), TPATH_LEN); // How about this environment variable?
+ else
+ GetWindowsDirectory(retPath, TPATH_LEN);
+#endif
+
+#ifdef XP_UNIX
+ PL_strncpy(retPath, "/tmp/", TPATH_LEN);
+#endif
+
+#ifdef XP_MAC
+ PL_strncpy(retPath, "", TPATH_LEN);
+#endif
+
+ return retPath;
+}
+
+//
+// Create a file spec for the a unique temp file
+// on the local machine. Caller must free memory
+//
+nsFileSpec *
+nsMsgCreateTempFileSpec(char *tFileName)
+{
+ if ((!tFileName) || (!*tFileName))
+ tFileName = "nsmail.tmp";
+
+ // Age old question, where to store temp files....ugh!
+ char *tDir = GetTheTempDirectoryOnTheSystem();
+ if (!tDir)
+ return (new nsFileSpec("mozmail.tmp")); // No need to I18N
+
+ nsFileSpec *tmpSpec = new nsFileSpec(tDir);
+ if (!tmpSpec)
+ {
+ PR_FREEIF(tDir);
+ return (new nsFileSpec("mozmail.tmp")); // No need to I18N
+ }
+
+ *tmpSpec += tFileName;
+ tmpSpec->MakeUnique();
+
+ PR_FREEIF(tDir);
+ return tmpSpec;
+}
+
+//
+// Create a file spec for the a unique temp file
+// on the local machine. Caller must free memory
+// returned
+//
+char *
+nsMsgCreateTempFileName(char *tFileName)
+{
+ if ((!tFileName) || (!*tFileName))
+ tFileName = "nsmail.tmp";
+
+ // Age old question, where to store temp files....ugh!
+ char *tDir = GetTheTempDirectoryOnTheSystem();
+ if (!tDir)
+ return "mozmail.tmp"; // No need to I18N
+
+ nsFileSpec tmpSpec(tDir);
+ tmpSpec += tFileName;
+ tmpSpec.MakeUnique();
+
+ PR_FREEIF(tDir);
+ char *tString = (char *)PL_strdup(tmpSpec.GetNativePathCString());
+ if (!tString)
+ return PL_strdup("mozmail.tmp"); // No need to I18N
+ else
+ return tString;
+}
+
+static PRBool mime_headers_use_quoted_printable_p = PR_FALSE;
+
+PRBool
+nsMsgMIMEGetConformToStandard (void)
+{
+ return mime_headers_use_quoted_printable_p;
+}
+
+void
+nsMsgMIMESetConformToStandard (PRBool conform_p)
+{
+ /*
+ * If we are conforming to mime standard no matter what we set
+ * for the headers preference when generating mime headers we should
+ * also conform to the standard. Otherwise, depends the preference
+ * we set. For now, the headers preference is not accessible from UI.
+ */
+ if (conform_p)
+ mime_headers_use_quoted_printable_p = PR_TRUE;
+ else {
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+ if (NS_SUCCEEDED(rv) && prefs) {
+ rv = prefs->GetBoolPref("mail.strictly_mime_headers", &mime_headers_use_quoted_printable_p);
+ }
+ }
+}
+
+int mime_sanity_check_fields (
+ const char *from,
+ const char *reply_to,
+ const char *to,
+ const char *cc,
+ const char *bcc,
+ const char *fcc,
+ const char *newsgroups,
+ const char *followup_to,
+ const char * /*subject*/,
+ const char * /*references*/,
+ const char * /*organization*/,
+ const char * /*other_random_headers*/)
+{
+ if (from)
+ while (IS_SPACE (*from))
+ from++;
+ if (reply_to)
+ while (IS_SPACE (*reply_to))
+ reply_to++;
+ if (to)
+ while (IS_SPACE (*to))
+ to++;
+ if (cc)
+ while (IS_SPACE (*cc))
+ cc++;
+ if (bcc)
+ while (IS_SPACE (*bcc))
+ bcc++;
+ if (fcc)
+ while (IS_SPACE (*fcc))
+ fcc++;
+ if (newsgroups)
+ while (IS_SPACE (*newsgroups))
+ newsgroups++;
+ if (followup_to)
+ while (IS_SPACE (*followup_to))
+ followup_to++;
+
+ /* #### sanity check other_random_headers for newline conventions */
+ if (!from || !*from)
+ return MK_MIME_NO_SENDER;
+ else
+ if ((!to || !*to) && (!cc || !*cc) &&
+ (!bcc || !*bcc) && (!newsgroups || !*newsgroups))
+ return MK_MIME_NO_RECIPIENTS;
+ else
+ return 0;
+}
+
+static char *
+nsMsgStripLine (char * string)
+{
+ char * ptr;
+
+ /* remove leading blanks */
+ while(*string=='\t' || *string==' ' || *string=='\r' || *string=='\n')
+ string++;
+
+ for(ptr=string; *ptr; ptr++)
+ ; /* NULL BODY; Find end of string */
+
+ /* remove trailing blanks */
+ for(ptr--; ptr >= string; ptr--)
+ {
+ if(*ptr=='\t' || *ptr==' ' || *ptr=='\r' || *ptr=='\n')
+ *ptr = '\0';
+ else
+ break;
+ }
+
+ return string;
+}
+
+char *
+mime_generate_headers (nsMsgCompFields *fields,
+ const char *charset,
+ nsMsgDeliverMode deliver_mode)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ int size = 0;
+ char *buffer = 0, *buffer_tail = 0;
+ PRBool isDraft = deliver_mode == nsMsgSaveAsDraft ||
+ deliver_mode == nsMsgSaveAsTemplate ||
+ deliver_mode == nsMsgQueueForLater;
+
+ const char* pFrom;
+ const char* pTo;
+ const char* pCc;
+ const char* pMessageID;
+ const char* pReplyTo;
+ const char* pOrg;
+ const char* pNewsGrp;
+ const char* pFollow;
+ const char* pSubject;
+ const char* pPriority;
+ const char* pReference;
+ const char* pOtherHdr;
+
+ NS_ASSERTION (fields, "null fields");
+ if (!fields)
+ return NULL;
+
+ /* Multiply by 3 here to make enough room for MimePartII conversion */
+ pFrom = fields->GetFrom(); if (pFrom) size += 3 * PL_strlen (pFrom);
+ pReplyTo =fields->GetReplyTo(); if (pReplyTo) size += 3 * PL_strlen (pReplyTo);
+ pTo = fields->GetTo(); if (pTo) size += 3 * PL_strlen (pTo);
+ pCc = fields->GetCc(); if (pCc) size += 3 * PL_strlen (pCc);
+ pNewsGrp = fields->GetNewsgroups(); if (pNewsGrp) size += 3 * PL_strlen (pNewsGrp);
+ pFollow= fields->GetFollowupTo(); if (pFollow) size += 3 * PL_strlen (pFollow);
+ pSubject = fields->GetSubject(); if (pSubject) size += 3 * PL_strlen (pSubject);
+ pReference = fields->GetReferences(); if (pReference) size += 3 * PL_strlen (pReference);
+ pOrg= fields->GetOrganization(); if (pOrg) size += 3 * PL_strlen (pOrg);
+ pOtherHdr= fields->GetOtherRandomHeaders(); if (pOtherHdr) size += 3 * PL_strlen (pOtherHdr);
+ pPriority = fields->GetPriority(); if (pPriority) size += 3 * PL_strlen (pPriority);
+#ifdef GENERATE_MESSAGE_ID
+ pMessageID = fields->GetMessageId(); if (pMessageID) size += PL_strlen (pMessageID);
+#endif /* GENERATE_MESSAGE_ID */
+
+ /* Add a bunch of slop for the static parts of the headers. */
+ /* size += 2048; */
+ size += 2560;
+
+ buffer = (char *) PR_Malloc (size);
+ if (!buffer)
+ return 0; /* MK_OUT_OF_MEMORY */
+
+ buffer_tail = buffer;
+
+#ifdef GENERATE_MESSAGE_ID
+ if (pMessageID && *pMessageID) {
+ char *convbuf = NULL;
+ PUSH_STRING ("Message-ID: ");
+ PUSH_STRING (pMessageID);
+ PUSH_NEWLINE ();
+ /* MDN request header requires to have MessageID header presented
+ * in the message in order to
+ * coorelate the MDN reports to the original message. Here will be
+ * the right place
+ */
+ if (fields->GetReturnReceipt() &&
+ (fields->GetReturnReceiptType() == 2 ||
+ fields->GetReturnReceiptType() == 3) &&
+ (deliver_mode != nsMsgSaveAsDraft &&
+ deliver_mode != nsMsgSaveAsTemplate))
+ {
+ PRInt32 receipt_header_type = 0;
+
+ if (prefs)
+ prefs->GetIntPref("mail.receipt.request_header_type", &receipt_header_type);
+
+ // 0 = MDN Disposition-Notification-To: ; 1 = Return-Receipt-To: ; 2 =
+ // both MDN DNT & RRT headers
+ if (receipt_header_type == 1) {
+ RRT_HEADER:
+ PUSH_STRING ("Return-Receipt-To: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pFrom, charset, nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_FREEIF(convbuf);
+ }
+ else
+ PUSH_STRING (pFrom);
+ PUSH_NEWLINE ();
+ }
+ else {
+ PUSH_STRING ("Disposition-Notification-To: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pFrom, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_FREEIF(convbuf);
+ }
+ else
+ PUSH_STRING (pFrom);
+ PUSH_NEWLINE ();
+ if (receipt_header_type == 2)
+ goto RRT_HEADER;
+ }
+ }
+#ifdef SUPPORT_X_TEMPLATE_NAME
+ if (deliver_mode == MSG_SaveAsTemplate) {
+ PUSH_STRING ("X-Template: ");
+ char * pStr = fields->GetTemplateName();
+ if (pStr) {
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)
+ pStr,
+ charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) {
+ PUSH_STRING (convbuf);
+ PR_FREEIF(convbuf);
+ }
+ else
+ PUSH_STRING(pStr);
+ }
+ PUSH_NEWLINE ();
+ }
+#endif /* SUPPORT_X_TEMPLATE_NAME */
+ }
+#endif /* GENERATE_MESSAGE_ID */
+
+ PRExplodedTime now;
+ PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);
+ int gmtoffset = now.tm_params.tp_gmt_offset / 60; /*We need the offset in minute and not in second! */
+
+ /* Use PR_FormatTimeUSEnglish() to format the date in US English format,
+ then figure out what our local GMT offset is, and append it (since
+ PR_FormatTimeUSEnglish() can't do that.) Generate four digit years as
+ per RFC 1123 (superceding RFC 822.)
+ */
+ PR_FormatTimeUSEnglish(buffer_tail, 100,
+ "Date: %a, %d %b %Y %H:%M:%S ",
+ &now);
+
+ buffer_tail += PL_strlen (buffer_tail);
+ PR_snprintf(buffer_tail, buffer + size - buffer_tail,
+ "%c%02d%02d" CRLF,
+ (gmtoffset >= 0 ? '+' : '-'),
+ ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) / 60),
+ ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) % 60));
+ buffer_tail += PL_strlen (buffer_tail);
+
+ if (pFrom && *pFrom) {
+ char *convbuf;
+ PUSH_STRING ("From: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pFrom, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (pFrom);
+ PUSH_NEWLINE ();
+ }
+
+ if (pReplyTo && *pReplyTo)
+ {
+ char *convbuf;
+ PUSH_STRING ("Reply-To: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pReplyTo, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (pReplyTo);
+ PUSH_NEWLINE ();
+ }
+
+ if (pOrg && *pOrg)
+ {
+ char *convbuf;
+ PUSH_STRING ("Organization: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pOrg, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (pOrg);
+ PUSH_NEWLINE ();
+ }
+
+ // X-Sender tag
+ if (fields->GetOwner())
+ {
+ PRBool bUseXSender = PR_FALSE;
+
+ if (prefs)
+ prefs->GetBoolPref("mail.use_x_sender", &bUseXSender);
+
+ if (bUseXSender) {
+ char *convbuf;
+ char *tmpBuffer=nsnull;
+
+ PUSH_STRING ("X-Sender: ");
+
+ PUSH_STRING("\"");
+
+ if (prefs)
+ prefs->CopyCharPref("mail.identity.username", &tmpBuffer);
+ convbuf = nsMsgI18NEncodeMimePartIIStr(tmpBuffer, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (tmpBuffer);
+ if (tmpBuffer) PL_strfree(tmpBuffer);
+ tmpBuffer=nsnull;
+
+ PUSH_STRING("\" <");
+
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->CopyCharPref("mail.smtp_name", &tmpBuffer);
+ convbuf = nsMsgI18NEncodeMimePartIIStr(tmpBuffer, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (tmpBuffer);
+ if (tmpBuffer) PL_strfree(tmpBuffer);
+ tmpBuffer=nsnull;
+
+ PUSH_STRING ("@");
+
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->CopyCharPref("network.hosts.smtp_server", &tmpBuffer);
+ convbuf = nsMsgI18NEncodeMimePartIIStr(tmpBuffer, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (tmpBuffer);
+
+ PUSH_STRING(">");
+
+ convbuf = nsMsgI18NEncodeMimePartIIStr(tmpBuffer, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (tmpBuffer) PL_strfree(tmpBuffer);
+ tmpBuffer=nsnull;
+
+ if (!fields->GetOwner()->GetMaster()->IsUserAuthenticated())
+ PUSH_STRING (" (Unverified)");
+ PUSH_NEWLINE ();
+ }
+ }
+
+ // X-Mozilla-Draft-Info
+ if (isDraft) {
+ char *htmlAction = 0;
+ char *lineWidth = 0; // force plain text hard line break info
+
+ PUSH_STRING(HEADER_X_MOZILLA_DRAFT_INFO);
+ PUSH_STRING(": internal/draft; ");
+ if (fields->GetAttachVCard())
+ PUSH_STRING("vcard=1");
+ else
+ PUSH_STRING("vcard=0");
+ PUSH_STRING("; ");
+ if (fields->GetReturnReceipt()) {
+ char *type = PR_smprintf("%d", (int) fields->GetReturnReceiptType());
+ if (type)
+ {
+ PUSH_STRING("receipt=");
+ PUSH_STRING(type);
+ PR_FREEIF(type);
+ }
+ }
+ else
+ PUSH_STRING("receipt=0");
+ PUSH_STRING("; ");
+ if (fields->GetBoolHeader(MSG_UUENCODE_BINARY_BOOL_HEADER_MASK))
+ PUSH_STRING("uuencode=1");
+ else
+ PUSH_STRING("uuencode=0");
+
+ htmlAction = PR_smprintf("html=%d",
+ ((nsMsgCompose*)fields->GetOwner())->GetHTMLAction());
+ if (htmlAction) {
+ PUSH_STRING("; ");
+ PUSH_STRING(htmlAction);
+ PR_FREEIF(htmlAction);
+ }
+
+ lineWidth = PR_smprintf("; linewidth=%d",
+ ((nsMsgCompose*)fields->GetOwner())->GetLineWidth());
+ if (lineWidth) {
+ PUSH_STRING(lineWidth);
+ PR_FREEIF(lineWidth);
+ }
+ PUSH_NEWLINE ();
+ }
+
+
+ NS_WITH_SERVICE(nsINetService, pNetService, kNetServiceCID, &rv);
+ if (NS_SUCCEEDED(rv) && pNetService)
+ {
+ nsString aNSStr;
+ char* sCStr;
+
+ pNetService->GetAppCodeName(aNSStr);
+ sCStr = aNSStr.ToNewCString();
+ if (sCStr) {
+ PUSH_STRING ("X-Mailer: ");
+ PUSH_STRING(sCStr);
+ delete [] sCStr;
+
+ pNetService->GetAppVersion(aNSStr);
+ sCStr = aNSStr.ToNewCString();
+ if (sCStr) {
+ PUSH_STRING (" ");
+ PUSH_STRING(sCStr);
+ delete [] sCStr;
+ }
+ PUSH_NEWLINE ();
+ }
+ }
+
+ /* for Netscape Server, Accept-Language data sent in Mail header */
+ char *acceptlang = nsMsgI18NGetAcceptLanguage();
+ if( (acceptlang != NULL) && ( *acceptlang != '\0') ){
+ PUSH_STRING( "X-Accept-Language: " );
+ PUSH_STRING( acceptlang );
+ PUSH_NEWLINE();
+ }
+
+ PUSH_STRING ("MIME-Version: 1.0" CRLF);
+
+ if (pNewsGrp && *pNewsGrp) {
+ /* turn whitespace into a comma list
+ */
+ char *ptr, *ptr2;
+ char *n2;
+ char *convbuf;
+
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pNewsGrp, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf)
+ n2 = nsMsgStripLine (convbuf);
+ else {
+ ptr = PL_strdup(pNewsGrp);
+ if (!ptr) {
+ PR_FREEIF(buffer);
+ return 0; /* MK_OUT_OF_MEMORY */
+ }
+ n2 = nsMsgStripLine(ptr);
+ NS_ASSERTION(n2 == ptr, "n2 != ptr"); /* Otherwise, the PR_Free below is
+ gonna choke badly. */
+ }
+
+ for(ptr=n2; *ptr != '\0'; ptr++) {
+ /* find first non white space */
+ while(!IS_SPACE(*ptr) && *ptr != ',' && *ptr != '\0')
+ ptr++;
+
+ if(*ptr == '\0')
+ break;
+
+ if(*ptr != ',')
+ *ptr = ',';
+
+ /* find next non white space */
+ ptr2 = ptr+1;
+ while(IS_SPACE(*ptr2))
+ ptr2++;
+
+ if(ptr2 != ptr+1)
+ PL_strcpy(ptr+1, ptr2);
+ }
+
+ PUSH_STRING ("Newsgroups: ");
+ PUSH_STRING (n2);
+ PR_Free (n2);
+ PUSH_NEWLINE ();
+ }
+
+ /* #### shamelessly duplicated from above */
+ if (pFollow && *pFollow) {
+ /* turn whitespace into a comma list
+ */
+ char *ptr, *ptr2;
+ char *n2;
+ char *convbuf;
+
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pFollow, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf)
+ n2 = nsMsgStripLine (convbuf);
+ else {
+ ptr = PL_strdup(pFollow);
+ if (!ptr) {
+ PR_FREEIF(buffer);
+ return 0; /* MK_OUT_OF_MEMORY */
+ }
+ n2 = nsMsgStripLine (ptr);
+ NS_ASSERTION(n2 == ptr, "n2 != ptr"); /* Otherwise, the PR_Free below is
+ gonna choke badly. */
+ }
+
+ for (ptr=n2; *ptr != '\0'; ptr++) {
+ /* find first non white space */
+ while(!IS_SPACE(*ptr) && *ptr != ',' && *ptr != '\0')
+ ptr++;
+
+ if(*ptr == '\0')
+ break;
+
+ if(*ptr != ',')
+ *ptr = ',';
+
+ /* find next non white space */
+ ptr2 = ptr+1;
+ while(IS_SPACE(*ptr2))
+ ptr2++;
+
+ if(ptr2 != ptr+1)
+ PL_strcpy(ptr+1, ptr2);
+ }
+
+ PUSH_STRING ("Followup-To: ");
+ PUSH_STRING (n2);
+ PR_Free (n2);
+ PUSH_NEWLINE ();
+ }
+
+ if (pTo && *pTo) {
+ char *convbuf;
+ PUSH_STRING ("To: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pTo, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (pTo);
+
+ PUSH_NEWLINE ();
+ }
+
+ if (pCc && *pCc) {
+ char *convbuf;
+ PUSH_STRING ("CC: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pCc, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (pCc);
+ PUSH_NEWLINE ();
+ }
+
+ if (pSubject && *pSubject) {
+ char *convbuf;
+ PUSH_STRING ("Subject: ");
+ convbuf = nsMsgI18NEncodeMimePartIIStr((char *)pSubject, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (convbuf) { /* MIME-PartII conversion */
+ PUSH_STRING (convbuf);
+ PR_Free(convbuf);
+ }
+ else
+ PUSH_STRING (pSubject);
+ PUSH_NEWLINE ();
+ }
+
+ if (pPriority && *pPriority)
+ if (!PL_strcasestr(pPriority, "normal")) {
+ PUSH_STRING ("X-Priority: ");
+ /* Important: do not change the order of the
+ * following if statements
+ */
+ if (PL_strcasestr (pPriority, "highest"))
+ PUSH_STRING("1 (");
+ else if (PL_strcasestr(pPriority, "high"))
+ PUSH_STRING("2 (");
+ else if (PL_strcasestr(pPriority, "lowest"))
+ PUSH_STRING("5 (");
+ else if (PL_strcasestr(pPriority, "low"))
+ PUSH_STRING("4 (");
+
+ PUSH_STRING (pPriority);
+ PUSH_STRING(")");
+ PUSH_NEWLINE ();
+ }
+
+ if (pReference && *pReference) {
+ PUSH_STRING ("References: ");
+ if (PL_strlen(pReference) >= 986) {
+ char *references = PL_strdup(pReference);
+ char *trimAt = PL_strchr(references+1, '<');
+ char *ptr;
+ // per sfraser, RFC 1036 - a message header line should not exceed
+ // 998 characters including the header identifier
+ // retiring the earliest reference one after the other
+ // but keep the first one for proper threading
+ while (references && PL_strlen(references) >= 986 && trimAt) {
+ ptr = PL_strchr(trimAt+1, '<');
+ if (ptr)
+ XP_MEMMOVE(trimAt, ptr, PL_strlen(ptr)+1); // including the
+ else
+ break;
+ }
+ NS_ASSERTION(references, "null references");
+ if (references) {
+ PUSH_STRING (references);
+ PR_Free(references);
+ }
+ }
+ else
+ PUSH_STRING (pReference);
+ PUSH_NEWLINE ();
+ }
+
+ if (pOtherHdr && *pOtherHdr) {
+ /* Assume they already have the right newlines and continuations
+ and so on. */
+ PUSH_STRING (pOtherHdr);
+ }
+
+ if (buffer_tail > buffer + size - 1)
+ abort ();
+
+ /* realloc it smaller... */
+ buffer = (char*)PR_REALLOC (buffer, buffer_tail - buffer + 1);
+
+ return buffer;
+}
+
+static void
+GenerateGlobalRandomBytes(unsigned char *buf, PRInt32 len)
+{
+ PRBool firstTime = PR_TRUE;
+
+ if (firstTime)
+ {
+ /* Seed the random-number generator with current time so that
+ * the numbers will be different every time we run. */
+ srand( (unsigned)time( NULL ) );
+ firstTime = PR_FALSE;
+ }
+
+ for( PRInt32 i = 0; i < len; i++ )
+ buf[i] = rand() % 10;
+}
+
+char
+*mime_make_separator(const char *prefix)
+{
+ unsigned char rand_buf[13];
+ GenerateGlobalRandomBytes(rand_buf, 12);
+
+ return PR_smprintf("------------%s"
+ "%02X%02X%02X%02X"
+ "%02X%02X%02X%02X"
+ "%02X%02X%02X%02X",
+ prefix,
+ rand_buf[0], rand_buf[1], rand_buf[2], rand_buf[3],
+ rand_buf[4], rand_buf[5], rand_buf[6], rand_buf[7],
+ rand_buf[8], rand_buf[9], rand_buf[10], rand_buf[11]);
+}
+
+char *
+mime_generate_attachment_headers (const char *type, const char *encoding,
+ const char *description,
+ const char *x_mac_type,
+ const char *x_mac_creator,
+ const char *real_name,
+ const char *base_url,
+ PRBool /*digest_p*/,
+ nsMsgAttachmentHandler * /*ma*/,
+ const char *charset)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+
+ PRInt32 buffer_size = 2048 + (base_url ? 2*PL_strlen(base_url) : 0);
+ char *buffer = (char *) PR_Malloc (buffer_size);
+ char *buffer_tail = buffer;
+
+ if (! buffer)
+ return 0; /* MK_OUT_OF_MEMORY */
+
+ NS_ASSERTION (encoding, "null encoding");
+
+ PUSH_STRING ("Content-Type: ");
+ PUSH_STRING (type);
+
+ if (mime_type_needs_charset (type)) {
+
+ char charset_label[65]; // Content-Type: charset
+ PL_strcpy(charset_label, charset);
+
+ /* If the characters are all 7bit, then it's better (and true) to
+ claim the charset to be US- rather than Latin1. Should we
+ do this all the time, for all charsets? I'm not sure. But we
+ should definitely do it for Latin1. */
+ if (encoding &&
+ !PL_strcasecmp (encoding, "7bit") &&
+ !PL_strcasecmp (charset, "iso-8859-1"))
+ PL_strcpy (charset_label, "us-ascii");
+
+ // If charset is JIS and and type is HTML
+ // then no charset to be specified (apply base64 instead)
+ // in order to avoid mismatch META_TAG (bug#104255).
+ if ((PL_strcasecmp(charset, "iso-2022-jp") != 0) ||
+ (PL_strcasecmp(type, TEXT_HTML) != 0) ||
+ (PL_strcasecmp(encoding, ENCODING_BASE64) != 0)) {
+ PUSH_STRING ("; charset=");
+ PUSH_STRING (charset_label);
+ }
+ }
+
+ if (x_mac_type && *x_mac_type) {
+ PUSH_STRING ("; x-mac-type=\"");
+ PUSH_STRING (x_mac_type);
+ PUSH_STRING ("\"");
+ }
+
+ if (x_mac_creator && *x_mac_creator) {
+ PUSH_STRING ("; x-mac-creator=\"");
+ PUSH_STRING (x_mac_creator);
+ PUSH_STRING ("\"");
+ }
+
+ PRInt32 parmFolding = 0;
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->GetIntPref("mail.strictly_mime.parm_folding", &parmFolding);
+
+#ifdef EMIT_NAME_IN_CONTENT_TYPE
+ if (real_name && *real_name) {
+ if (parmFolding == 0 || parmFolding == 1) {
+ PUSH_STRING (";\r\n name=\"");
+ PUSH_STRING (real_name);
+ PUSH_STRING ("\"");
+ }
+ else // if (parmFolding == 2)
+ {
+ char *rfc2231Parm = RFC2231ParmFolding("name", charset,
+ nsMsgI18NGetAcceptLanguage(), real_name);
+ if (rfc2231Parm) {
+ PUSH_STRING(";\r\n ");
+ PUSH_STRING(rfc2231Parm);
+ PR_Free(rfc2231Parm);
+ }
+ }
+ }
+#endif /* EMIT_NAME_IN_CONTENT_TYPE */
+
+ PUSH_NEWLINE ();
+
+ PUSH_STRING ("Content-Transfer-Encoding: ");
+ PUSH_STRING (encoding);
+ PUSH_NEWLINE ();
+
+ if (description && *description) {
+ char *s = mime_fix_header (description);
+ if (s) {
+ PUSH_STRING ("Content-Description: ");
+ PUSH_STRING (s);
+ PUSH_NEWLINE ();
+ PR_Free(s);
+ }
+ }
+
+ if (real_name && *real_name) {
+ char *period = PL_strrchr(real_name, '.');
+ PRInt32 pref_content_disposition = 0;
+
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->GetIntPref("mail.content_disposition_type", &pref_content_disposition);
+ PUSH_STRING ("Content-Disposition: ");
+
+ if (pref_content_disposition == 1)
+ PUSH_STRING ("attachment");
+ else
+ if (pref_content_disposition == 2 &&
+ (!PL_strcasecmp(type, TEXT_PLAIN) ||
+ (period && !PL_strcasecmp(period, ".txt"))))
+ PUSH_STRING("attachment");
+
+ /* If this document is an anonymous binary file or a vcard,
+ then always show it as an attachment, never inline. */
+ else
+ if (!PL_strcasecmp(type, APPLICATION_OCTET_STREAM) ||
+ !PL_strcasecmp(type, TEXT_VCARD) ||
+ !PL_strcasecmp(type, APPLICATION_DIRECTORY)) /* text/x-vcard synonym */
+ PUSH_STRING ("attachment");
+ else
+ PUSH_STRING ("inline");
+
+ if (parmFolding == 0 || parmFolding == 1) {
+ PUSH_STRING (";\r\n filename=\"");
+ PUSH_STRING (real_name);
+ PUSH_STRING ("\"" CRLF);
+ }
+ else // if (parmFolding == 2)
+ {
+ char *rfc2231Parm = RFC2231ParmFolding("filename", charset,
+ nsMsgI18NGetAcceptLanguage(), real_name);
+ if (rfc2231Parm) {
+ PUSH_STRING(";\r\n ");
+ PUSH_STRING(rfc2231Parm);
+ PUSH_NEWLINE ();
+ PR_Free(rfc2231Parm);
+ }
+ }
+ }
+ else
+ if (type &&
+ (!PL_strcasecmp (type, MESSAGE_RFC822) ||
+ !PL_strcasecmp (type, MESSAGE_NEWS)))
+ PUSH_STRING ("Content-Disposition: inline" CRLF);
+
+#ifdef GENERATE_CONTENT_BASE
+ /* If this is an HTML document, and we know the URL it originally
+ came from, write out a Content-Base header. */
+ if (type &&
+ (!PL_strcasecmp (type, TEXT_HTML) ||
+ !PL_strcasecmp (type, TEXT_MDL)) &&
+ base_url && *base_url)
+ {
+ PRInt32 col = 0;
+ const char *s = base_url;
+ const char *colon = PL_strchr (s, ':');
+ PRBool useContentLocation = PR_FALSE; /* rhp - add this */
+
+ if (!colon)
+ goto GIVE_UP_ON_CONTENT_BASE; /* malformed URL? */
+
+ /* Don't emit a content-base that points to (or into) a news or
+ mail message. */
+ if (!PL_strncasecmp (s, "news:", 5) ||
+ !PL_strncasecmp (s, "snews:", 6) ||
+ !PL_strncasecmp (s, "IMAP:", 5) ||
+ !PL_strncasecmp (s, "file:", 5) || /* rhp: fix targets from included HTML files */
+ !PL_strncasecmp (s, "mailbox:", 8))
+ goto GIVE_UP_ON_CONTENT_BASE;
+
+ /* rhp - Put in a pref for using Content-Location instead of Content-Base.
+ This will get tweaked to default to true in 5.0
+ */
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->GetBoolPref("mail.use_content_location_on_send", &useContentLocation);
+
+ if (useContentLocation)
+ PUSH_STRING ("Content-Location: \"");
+ else
+ PUSH_STRING ("Content-Base: \"");
+ /* rhp - Pref for Content-Location usage */
+
+/* rhp: this is to work with the Content-Location stuff */
+CONTENT_LOC_HACK:
+
+ while (*s != 0 && *s != '#')
+ {
+ const char *ot = buffer_tail;
+
+ /* URLs must be wrapped at 40 characters or less. */
+ if (col >= 38) {
+ PUSH_STRING(CRLF "\t");
+ col = 0;
+ }
+
+ if (*s == ' ')
+ PUSH_STRING("%20");
+ else if (*s == '\t')
+ PUSH_STRING("%09");
+ else if (*s == '\n')
+ PUSH_STRING("%0A");
+ else if (*s == '\r')
+ PUSH_STRING("%0D");
+ else {
+ *buffer_tail++ = *s;
+ *buffer_tail = '\0';
+ }
+ s++;
+ col += (buffer_tail - ot);
+ }
+ PUSH_STRING ("\"" CRLF);
+
+ /* rhp: this is to try to get around this fun problem with Content-Location */
+ if (!useContentLocation) {
+ PUSH_STRING ("Content-Location: \"");
+ s = base_url;
+ col = 0;
+ useContentLocation = PR_TRUE;
+ goto CONTENT_LOC_HACK;
+ }
+ /* rhp: this is to try to get around this fun problem with Content-Location */
+
+GIVE_UP_ON_CONTENT_BASE:
+ ;
+ }
+#endif /* GENERATE_CONTENT_BASE */
+
+ /* realloc it smaller... */
+ buffer = (char*) PR_REALLOC (buffer, buffer_tail - buffer + 1);
+
+ return buffer;
+}
+
+char *
+msg_generate_message_id (void)
+{
+ time_t now = XP_TIME();
+ PRUint32 salt = 0;
+ nsMsgCompPrefs pCompPrefs;
+ const char *host = 0;
+ const char *from = pCompPrefs.GetUserEmail();
+
+ GenerateGlobalRandomBytes((unsigned char *) &salt, sizeof(salt));
+ if (from) {
+ host = PL_strchr (from, '@');
+ if (host) {
+ const char *s;
+ for (s = ++host; *s; s++)
+ if (!XP_IS_ALPHA(*s) && !XP_IS_DIGIT(*s) &&
+ *s != '-' && *s != '_' && *s != '.') {
+ host = 0;
+ break;
+ }
+ }
+ }
+
+ if (! host)
+ /* If we couldn't find a valid host name to use, we can't generate a
+ valid message ID, so bail, and let NNTP and SMTP generate them. */
+ return 0;
+
+ return PR_smprintf("<%lX.%lX@%s>",
+ (unsigned long) now, (unsigned long) salt, host);
+}
+
+char *
+RFC2231ParmFolding(const char *parmName, const char *charset,
+ const char *language, const char *parmValue)
+{
+#define PR_MAX_FOLDING_LEN 75 // this is to gurantee the folded line will
+ // never be greater than 78 = 75 + CRLFLWSP
+ char *foldedParm = NULL;
+ char *dupParm = NULL;
+ PRInt32 parmNameLen = 0;
+ PRInt32 parmValueLen = 0;
+ PRInt32 charsetLen = 0;
+ PRInt32 languageLen = 0;
+ PRBool needEscape = PR_FALSE;
+
+ NS_ASSERTION(parmName && *parmName && parmValue && *parmValue, "null parameters");
+ if (!parmName || !*parmName || !parmValue || !*parmValue)
+ return NULL;
+ if ((charset && *charset && PL_strcasecmp(charset, "us-ascii") != 0) ||
+ (language && *language && PL_strcasecmp(language, "en") != 0 &&
+ PL_strcasecmp(language, "en-us") != 0))
+ needEscape = PR_TRUE;
+
+ if (needEscape)
+ dupParm = nsEscape(parmValue, url_Path);
+ else
+ dupParm = PL_strdup(parmValue);
+
+ if (!dupParm)
+ return NULL;
+
+ if (needEscape)
+ {
+ parmValueLen = PL_strlen(dupParm);
+ parmNameLen = PL_strlen(parmName);
+ }
+
+ if (needEscape)
+ parmNameLen += 5; // *=__'__'___ or *[0]*=__'__'__ or *[1]*=___
+ else
+ parmNameLen += 5; // *[0]="___";
+ charsetLen = charset ? PL_strlen(charset) : 0;
+ languageLen = language ? PL_strlen(language) : 0;
+
+ if ((parmValueLen + parmNameLen + charsetLen + languageLen) <
+ PR_MAX_FOLDING_LEN)
+ {
+ foldedParm = PL_strdup(parmName);
+ if (needEscape)
+ {
+ StrAllocCat(foldedParm, "*=");
+ if (charsetLen)
+ StrAllocCat(foldedParm, charset);
+ StrAllocCat(foldedParm, "'");
+ if (languageLen)
+ StrAllocCat(foldedParm, language);
+ StrAllocCat(foldedParm, "'");
+ }
+ else
+ StrAllocCat(foldedParm, "=\"");
+ StrAllocCat(foldedParm, dupParm);
+ if (!needEscape)
+ StrAllocCat(foldedParm, "\"");
+ goto done;
+ }
+ else
+ {
+ int curLineLen = 0;
+ int counter = 0;
+ char digits[32];
+ char *start = dupParm;
+ char *end = NULL;
+ char tmp = 0;
+
+ while (parmValueLen > 0)
+ {
+ curLineLen = 0;
+ if (counter == 0) {
+ PR_FREEIF(foldedParm)
+ foldedParm = PL_strdup(parmName);
+ }
+ else {
+ if (needEscape)
+ StrAllocCat(foldedParm, "\r\n ");
+ else
+ StrAllocCat(foldedParm, ";\r\n ");
+ StrAllocCat(foldedParm, parmName);
+ }
+ PR_snprintf(digits, sizeof(digits), "*%d", counter);
+ StrAllocCat(foldedParm, digits);
+ curLineLen += PL_strlen(digits);
+ if (needEscape)
+ {
+ StrAllocCat(foldedParm, "*=");
+ if (counter == 0)
+ {
+ if (charsetLen)
+ StrAllocCat(foldedParm, charset);
+ StrAllocCat(foldedParm, "'");
+ if (languageLen)
+ StrAllocCat(foldedParm, language);
+ StrAllocCat (foldedParm, "'");
+ curLineLen += charsetLen;
+ curLineLen += languageLen;
+ }
+ }
+ else
+ {
+ StrAllocCat(foldedParm, "=\"");
+ }
+ counter++;
+ curLineLen += parmNameLen;
+ if (parmValueLen <= PR_MAX_FOLDING_LEN - curLineLen)
+ end = start + parmValueLen;
+ else
+ end = start + (PR_MAX_FOLDING_LEN - curLineLen);
+
+ tmp = 0;
+ if (*end && needEscape)
+ {
+ // check to see if we are in the middle of escaped char
+ if (*end == '%')
+ {
+ tmp = '%'; *end = nsnull;
+ }
+ else if (end-1 > start && *(end-1) == '%')
+ {
+ end -= 1; tmp = '%'; *end = nsnull;
+ }
+ else if (end-2 > start && *(end-2) == '%')
+ {
+ end -= 2; tmp = '%'; *end = nsnull;
+ }
+ else
+ {
+ tmp = *end; *end = nsnull;
+ }
+ }
+ else
+ {
+ tmp = *end; *end = nsnull;
+ }
+ StrAllocCat(foldedParm, start);
+ if (!needEscape)
+ StrAllocCat(foldedParm, "\"");
+
+ parmValueLen -= (end-start);
+ if (tmp)
+ *end = tmp;
+ start = end;
+ }
+ }
+
+done:
+ PR_FREEIF(dupParm);
+ return foldedParm;
+}
+
+PRBool
+mime_7bit_data_p (const char *string, PRUint32 size)
+{
+ const unsigned char *s = (const unsigned char *) string;
+ const unsigned char *end = s + size;
+ if (s)
+ for (; s < end; s++)
+ if (*s > 0x7F)
+ return PR_FALSE;
+ return PR_TRUE;
+}
+
+/* Strips whitespace, and expands newlines into newline-tab for use in
+ mail headers. Returns a new string or 0 (if it would have been empty.)
+ If addr_p is true, the addresses will be parsed and reemitted as
+ rfc822 mailboxes.
+ */
+char *
+mime_fix_header_1 (const char *string, PRBool addr_p, PRBool news_p)
+{
+ char *new_string;
+ const char *in;
+ char *out;
+ PRInt32 i, old_size, new_size;
+
+ if (!string || !*string)
+ return 0;
+
+ if (addr_p) {
+ nsIMsgHeaderParser * pHeader;
+ nsresult rv = nsComponentManager::CreateInstance(kMsgHeaderParserCID,
+ NULL,
+ nsIMsgHeaderParser::GetIID(),
+ (void **) &pHeader);
+ if (NS_SUCCEEDED(rv)) {
+ char *n;
+ pHeader->ReformatHeaderAddresses(nsnull, string, &n);
+ pHeader->Release();
+ if (n)
+ return n;
+ }
+ }
+
+ old_size = PL_strlen (string);
+ new_size = old_size;
+ for (i = 0; i < old_size; i++)
+ if (string[i] == CR || string[i] == LF)
+ new_size += 2;
+
+ new_string = (char *) PR_Malloc (new_size + 1);
+ if (! new_string)
+ return 0;
+
+ in = string;
+ out = new_string;
+
+ /* strip leading whitespace. */
+ while (IS_SPACE (*in))
+ in++;
+
+ /* replace CR, LF, or CRLF with CRLF-TAB. */
+ while (*in) {
+ if (*in == CR || *in == LF) {
+ if (*in == CR && in[1] == LF)
+ in++;
+ in++;
+ *out++ = CR;
+ *out++ = LF;
+ *out++ = '\t';
+ }
+ else
+ if (news_p && *in == ',') {
+ *out++ = *in++;
+ /* skip over all whitespace after a comma. */
+ while (IS_SPACE (*in))
+ in++;
+ }
+ else
+ *out++ = *in++;
+ }
+ *out = 0;
+
+ /* strip trailing whitespace. */
+ while (out > in && IS_SPACE (out[-1]))
+ *out-- = 0;
+
+ /* If we ended up throwing it all away, use 0 instead of "". */
+ if (!*new_string) {
+ PR_Free (new_string);
+ new_string = 0;
+ }
+
+ return new_string;
+}
+
+char *
+mime_fix_header (const char *string)
+{
+ return mime_fix_header_1 (string, PR_FALSE, PR_FALSE);
+}
+
+char *
+mime_fix_addr_header (const char *string)
+{
+ return mime_fix_header_1 (string, PR_TRUE, PR_FALSE);
+}
+
+char *
+mime_fix_news_header (const char *string)
+{
+ return mime_fix_header_1 (string, PR_FALSE, PR_TRUE);
+}
+
+PRBool
+mime_type_requires_b64_p (const char *type)
+{
+ if (!type || !PL_strcasecmp (type, UNKNOWN_CONTENT_TYPE))
+ /* Unknown types don't necessarily require encoding. (Note that
+ "unknown" and "application/octet-stream" aren't the same.) */
+ return PR_FALSE;
+
+ else if (!PL_strncasecmp (type, "image/", 6) ||
+ !PL_strncasecmp (type, "audio/", 6) ||
+ !PL_strncasecmp (type, "video/", 6) ||
+ !PL_strncasecmp (type, "application/", 12))
+ {
+ /* The following types are application/ or image/ types that are actually
+ known to contain textual data (meaning line-based, not binary, where
+ CRLF conversion is desired rather than disasterous.) So, if the type
+ is any of these, it does not *require* base64, and if we do need to
+ encode it for other reasons, we'll probably use quoted-printable.
+ But, if it's not one of these types, then we assume that any subtypes
+ of the non-"text/" types are binary data, where CRLF conversion would
+ corrupt it, so we use base64 right off the bat.
+
+ The reason it's desirable to ship these as text instead of just using
+ base64 all the time is mainly to preserve the readability of them for
+ non-MIME users: if I mail a /bin/sh script to someone, it might not
+ need to be encoded at all, so we should leave it readable if we can.
+
+ This list of types was derived from the comp.mail.mime FAQ, section
+ 10.2.2, "List of known unregistered MIME types" on 2-Feb-96.
+ */
+ static const char *app_and_image_types_which_are_really_text[] = {
+ "application/mac-binhex40", /* APPLICATION_BINHEX */
+ "application/pgp", /* APPLICATION_PGP */
+ "application/x-pgp-message", /* APPLICATION_PGP2 */
+ "application/postscript", /* APPLICATION_POSTSCRIPT */
+ "application/x-uuencode", /* APPLICATION_UUENCODE */
+ "application/x-uue", /* APPLICATION_UUENCODE2 */
+ "application/uue", /* APPLICATION_UUENCODE4 */
+ "application/uuencode", /* APPLICATION_UUENCODE3 */
+ "application/sgml",
+ "application/x-csh",
+ "application/x-javascript",
+ "application/x-latex",
+ "application/x-macbinhex40",
+ "application/x-ns-proxy-autoconfig",
+ "application/x-www-form-urlencoded",
+ "application/x-perl",
+ "application/x-sh",
+ "application/x-shar",
+ "application/x-tcl",
+ "application/x-tex",
+ "application/x-texinfo",
+ "application/x-troff",
+ "application/x-troff-man",
+ "application/x-troff-me",
+ "application/x-troff-ms",
+ "application/x-troff-ms",
+ "application/x-wais-source",
+ "image/x-bitmap",
+ "image/x-pbm",
+ "image/x-pgm",
+ "image/x-portable-anymap",
+ "image/x-portable-bitmap",
+ "image/x-portable-graymap",
+ "image/x-portable-pixmap", /* IMAGE_PPM */
+ "image/x-ppm",
+ "image/x-xbitmap", /* IMAGE_XBM */
+ "image/x-xbm", /* IMAGE_XBM2 */
+ "image/xbm", /* IMAGE_XBM3 */
+ "image/x-xpixmap",
+ "image/x-xpm",
+ 0 };
+ const char **s;
+ for (s = app_and_image_types_which_are_really_text; *s; s++)
+ if (!PL_strcasecmp (type, *s))
+ return PR_FALSE;
+
+ /* All others must be assumed to be binary formats, and need Base64. */
+ return PR_TRUE;
+ }
+
+ else
+ return PR_FALSE;
+}
+
+//
+// Some types should have a "charset=" parameter, and some shouldn't.
+// This is what decides.
+//
+PRBool
+mime_type_needs_charset (const char *type)
+{
+ /* Only text types should have charset. */
+ if (!type || !*type)
+ return PR_FALSE;
+ else
+ if (!PL_strncasecmp (type, "text", 4))
+ return PR_TRUE;
+ else
+ return PR_FALSE;
+}
+
+//
+// Generate headers for a form post to a mailto: URL.
+// This lets the URL specify additional headers, but is careful to
+// ignore headers which would be dangerous. It may modify the URL
+// (because of CC) so a new URL to actually post to is returned.
+//
+int
+nsMsgMIMEGenerateMailtoFormPostHeaders (const char *old_post_url,
+ const char * /*referer*/,
+ char **new_post_url_return,
+ char **headers_return)
+{
+ char *from = 0, *to = 0, *cc = 0, *body = 0, *search = 0;
+ char *extra_headers = 0;
+ char *s;
+ PRBool subject_p = PR_FALSE;
+ PRBool sign_p = PR_FALSE, encrypt_p = PR_FALSE;
+ char *rest;
+ int status = 0;
+ nsMsgCompFields *fields = NULL;
+ static const char *forbidden_headers[] = {
+ "Apparently-To",
+ "BCC",
+ "Content-Encoding",
+ HEADER_CONTENT_LENGTH,
+ "Content-Transfer-Encoding",
+ "Content-Type",
+ "Date",
+ "Distribution",
+ "FCC",
+ "Followup-To",
+ "From",
+ "Lines",
+ "MIME-Version",
+ "Message-ID",
+ "Newsgroups",
+ "Organization",
+ "Reply-To",
+ "Sender",
+ HEADER_X_MOZILLA_STATUS,
+ HEADER_X_MOZILLA_STATUS2,
+ HEADER_X_MOZILLA_NEWSHOST,
+ HEADER_X_UIDL,
+ "XRef",
+ 0 };
+
+ from = MIME_MakeFromField (CS_DEFAULT);
+ if (!from) {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ to = NET_ParseURL (old_post_url, GET_PATH_PART);
+ if (!to) {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ if (!*to)
+ {
+ status = MK_MIME_NO_RECIPIENTS; /* rb -1; */
+ goto FAIL;
+ }
+
+ search = NET_ParseURL (old_post_url, GET_SEARCH_PART);
+
+ rest = search;
+ if (rest && *rest == '?')
+ {
+ /* start past the '?' */
+ rest++;
+ rest = XP_STRTOK (rest, "&");
+ while (rest && *rest)
+ {
+ char *token = rest;
+ char *value = 0;
+ char *eq;
+
+ rest = XP_STRTOK (0, "&");
+
+ eq = PL_strchr (token, '=');
+ if (eq)
+ {
+ value = eq+1;
+ *eq = 0;
+ }
+
+ if (!PL_strcasecmp (token, "subject"))
+ subject_p = PR_TRUE;
+
+ if (value)
+ /* Don't allow newlines or control characters in the value. */
+ for (s = value; *s; s++)
+ if (*s < ' ' && *s != '\t')
+ *s = ' ';
+
+ if (!PL_strcasecmp (token, "to"))
+ {
+ if (to && *to)
+ {
+ StrAllocCat (to, ", ");
+ StrAllocCat (to, value);
+ }
+ else
+ {
+ PR_FREEIF(to);
+ to = PL_strdup(value);
+ }
+ }
+ else if (!PL_strcasecmp (token, "cc"))
+ {
+ if (cc && *cc)
+ {
+ StrAllocCat (cc, ", ");
+ StrAllocCat (cc, value);
+ }
+ else
+ {
+ PR_FREEIF(cc);
+ cc = PL_strdup (value);
+ }
+ }
+ else if (!PL_strcasecmp (token, "body"))
+ {
+ if (body && *body)
+ {
+ StrAllocCat (body, "\n");
+ StrAllocCat (body, value);
+ }
+ else
+ {
+ PR_FREEIF(body);
+ body = PL_strdup (value);
+ }
+ }
+ else if (!PL_strcasecmp (token, "encrypt") ||
+ !PL_strcasecmp (token, "encrypted"))
+ {
+ encrypt_p = (!PL_strcasecmp(value, "true") ||
+ !PL_strcasecmp(value, "yes"));
+ }
+ else if (!PL_strcasecmp (token, "sign") ||
+ !PL_strcasecmp (token, "signed"))
+ {
+ sign_p = (!PL_strcasecmp(value, "true") ||
+ !PL_strcasecmp(value, "yes"));
+ }
+ else
+ {
+ const char **fh = forbidden_headers;
+ PRBool ok = PR_TRUE;
+ while (*fh)
+ if (!PL_strcasecmp (token, *fh++))
+ {
+ ok = PR_FALSE;
+ break;
+ }
+ if (ok)
+ {
+ PRBool upper_p = PR_FALSE;
+ char *s;
+ for (s = token; *s; s++)
+ {
+ if (*s >= 'A' && *s <= 'Z')
+ upper_p = PR_TRUE;
+ else if (*s <= ' ' || *s >= '~' || *s == ':')
+ goto NOT_OK; /* bad character in header! */
+ }
+ if (!upper_p && *token >= 'a' && *token <= 'z')
+ *token -= ('a' - 'A');
+
+ StrAllocCat (extra_headers, token);
+ StrAllocCat (extra_headers, ": ");
+ if (value)
+ StrAllocCat (extra_headers, value);
+ StrAllocCat (extra_headers, CRLF);
+ NOT_OK: ;
+ }
+ }
+ }
+ }
+
+ if (!subject_p)
+ {
+ char* sAppName = nsnull;
+ nsresult rv = NS_OK;
+ NS_WITH_SERVICE(nsINetService, pNetService, kNetServiceCID, &rv);
+
+ if (NS_SUCCEEDED(rv) && pNetService)
+ {
+ nsString aNSStr;
+
+ pNetService->GetAppCodeName(aNSStr);
+ sAppName = aNSStr.ToNewCString();
+ }
+ /* If the URL didn't provide a subject, we will. */
+ StrAllocCat (extra_headers, "Subject: Form posted from ");
+ NS_ASSERTION (sAppName, "null XP_AppCodeName");
+ StrAllocCat (extra_headers, sAppName);
+ StrAllocCat (extra_headers, CRLF);
+ }
+
+ /* Note: the `encrypt', `sign', and `body' parameters are currently
+ ignored in mailto form submissions. */
+
+ *new_post_url_return = 0;
+
+ /*JFD
+ nsMsgCompPrefs pCompPrefs;
+ fields = MSG_CreateCompositionFields(from, 0, to, cc, 0, 0, 0, 0,
+ (char *)pCompPrefs.GetOrganization(), 0, 0,
+ extra_headers, 0, 0, 0,
+ encrypt_p, sign_p);
+ */
+ if (!fields)
+ {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ fields->SetDefaultBody(body, NULL);
+
+ *headers_return = mime_generate_headers (fields, 0, nsMsgDeliverNow);
+ if (*headers_return == 0)
+ {
+ status = MK_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ StrAllocCat ((*new_post_url_return), "mailto:");
+ if (to)
+ StrAllocCat ((*new_post_url_return), to);
+ if (to && cc)
+ StrAllocCat ((*new_post_url_return), ",");
+ if (cc)
+ StrAllocCat ((*new_post_url_return), cc);
+
+ FAIL:
+ PR_FREEIF (from);
+ PR_FREEIF (to);
+ PR_FREEIF (cc);
+ PR_FREEIF (body);
+ PR_FREEIF (search);
+ PR_FREEIF (extra_headers);
+ /*JFD
+ if (fields)
+ MSG_DestroyCompositionFields(fields);
+*/
+
+ return status;
+}
+
+/* Given a string, convert it to 'qtext' (quoted text) for RFC822 header purposes. */
+char *
+msg_make_filename_qtext(const char *srcText, PRBool stripCRLFs)
+{
+ /* newString can be at most twice the original string (every char quoted). */
+ char *newString = (char *) PR_Malloc(PL_strlen(srcText)*2 + 1);
+ if (!newString) return NULL;
+
+ const char *s = srcText;
+ const char *end = srcText + PL_strlen(srcText);
+ char *d = newString;
+
+ while(*s)
+ {
+ /* Put backslashes in front of existing backslashes, or double quote
+ characters.
+ If stripCRLFs is true, don't write out CRs or LFs. Otherwise,
+ write out a backslash followed by the CR but not
+ linear-white-space.
+ We might already have quoted pair of "\ " or "\\t" skip it.
+ */
+ if (*s == '\\' || *s == '"' ||
+ (!stripCRLFs &&
+ (*s == CR && (*(s+1) != LF ||
+ (*(s+1) == LF && (s+2) < end && !IS_SPACE(*(s+2)))))))
+ *d++ = '\\';
+
+ if (*s == CR)
+ {
+ if (stripCRLFs && *(s+1) == LF && (s+2) < end && IS_SPACE(*(s+2)))
+ s += 2; // skip CRLFLWSP
+ }
+ else
+ {
+ *d++ = *s;
+ }
+ s++;
+ }
+ *d = 0;
+
+ return newString;
+}
+
+/* Rip apart the URL and extract a reasonable value for the `real_name' slot.
+ */
+void
+msg_pick_real_name (nsMsgAttachmentHandler *attachment, const char *charset)
+{
+ nsresult rv;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
+ const char *s, *s2;
+ char *s3;
+ char *url;
+
+ if (attachment->m_real_name)
+ return;
+
+ url = attachment->m_url_string;
+
+ /* Perhaps the MIME parser knows a better name than the URL itself?
+ This can happen when one attaches a MIME part from one message
+ directly into another message.
+
+ ### mwelch Note that this function simply duplicates and returns an existing
+ MIME header, so we don't need to process it. */
+ attachment->m_real_name =
+ MimeGuessURLContentName(attachment->m_mime_delivery_state->GetContext(),
+ url);
+ if (attachment->m_real_name)
+ return;
+
+ /* Otherwise, extract a name from the URL. */
+
+ s = url;
+ s2 = PL_strchr (s, ':');
+ if (s2) s = s2 + 1;
+ /* If we know the URL doesn't have a sensible file name in it,
+ don't bother emitting a content-disposition. */
+ if (!PL_strncasecmp (url, "news:", 5) ||
+ !PL_strncasecmp (url, "snews:", 6) ||
+ !PL_strncasecmp (url, "IMAP:", 5) ||
+ !PL_strncasecmp (url, "mailbox:", 8))
+ return;
+
+ /* Take the part of the file name after the last / or \ */
+ s2 = PL_strrchr (s, '/');
+ if (s2) s = s2+1;
+ s2 = PL_strrchr (s, '\\');
+
+#if 0
+//TODO: convert to unicode to do the truncation
+ if (csid & MULTIBYTE)
+ {
+ // We don't want to truncate the file name in case of the double
+ // byte file name
+ while ( s2 != NULL &&
+ s2 > s &&
+ nsMsgI18NIsLeadByte(csid, *(s2-1)))
+ {
+ s3 = (char *) s2;
+ *s3 = 0;
+ s2 = PL_strrchr(s, '\\');
+ *s3 = '\\';
+ }
+ }
+#endif
+
+ if (s2) s = s2+1;
+ /* Copy it into the attachment struct. */
+ PR_FREEIF(attachment->m_real_name);
+ attachment->m_real_name = PL_strdup (s);
+ /* Now trim off any named anchors or search data. */
+ s3 = PL_strchr (attachment->m_real_name, '?');
+ if (s3) *s3 = 0;
+ s3 = PL_strchr (attachment->m_real_name, '#');
+ if (s3) *s3 = 0;
+
+ /* Now lose the %XX crap. */
+ nsUnescape (attachment->m_real_name);
+
+ PRInt32 parmFolding = 0;
+ if (NS_SUCCEEDED(rv) && prefs)
+ prefs->GetIntPref("mail.strictly_mime.parm_folding", &parmFolding);
+
+ if (parmFolding == 0 || parmFolding == 1)
+ {
+ /* Try to MIME-2 encode the filename... */
+ char *mime2Name = nsMsgI18NEncodeMimePartIIStr(attachment->m_real_name, charset,
+ nsMsgMIMEGetConformToStandard());
+ if (mime2Name && (mime2Name != attachment->m_real_name))
+ {
+ PR_Free(attachment->m_real_name);
+ attachment->m_real_name = mime2Name;
+ }
+
+ /* ... and then put backslashes before special characters (RFC 822 tells us
+ to). */
+
+ char *qtextName = NULL;
+
+ qtextName = msg_make_filename_qtext(attachment->m_real_name,
+ (parmFolding == 0 ? PR_TRUE : PR_FALSE));
+
+ if (qtextName)
+ {
+ PR_Free(attachment->m_real_name);
+ attachment->m_real_name = qtextName;
+ }
+ }
+
+ /* Now a special case for attaching uuencoded files...
+
+ If we attach a file "foo.txt.uu", we will send it out with
+ Content-Type: text/plain; Content-Transfer-Encoding: x-uuencode.
+ When saving such a file, a mail reader will generally decode it first
+ (thus removing the uuencoding.) So, let's make life a little easier by
+ removing the indication of uuencoding from the file name itself. (This
+ will presumably make the file name in the Content-Disposition header be
+ the same as the file name in the "begin" line of the uuencoded data.)
+
+ However, since there are mailers out there (including earlier versions of
+ Mozilla) that will use "foo.txt.uu" as the file name, we still need to
+ cope with that; the code which copes with that is in the MIME parser, in
+ libmime/mimei.c.
+ */
+ if (attachment->m_already_encoded_p &&
+ attachment->m_encoding)
+ {
+ char *result = attachment->m_real_name;
+ PRInt32 L = PL_strlen(result);
+ const char **exts = 0;
+
+ /* #### TOTAL KLUDGE.
+ I'd like to ask the mime.types file, "what extensions correspond
+ to obj->encoding (which happens to be "x-uuencode") but doing that
+ in a non-sphagetti way would require brain surgery. So, since
+ currently uuencode is the only content-transfer-encoding which we
+ understand which traditionally has an extension, we just special-
+ case it here!
+
+ Note that it's special-cased in a similar way in libmime/mimei.c.
+ */
+ if (!PL_strcasecmp(attachment->m_encoding, ENCODING_UUENCODE) ||
+ !PL_strcasecmp(attachment->m_encoding, ENCODING_UUENCODE2) ||
+ !PL_strcasecmp(attachment->m_encoding, ENCODING_UUENCODE3) ||
+ !PL_strcasecmp(attachment->m_encoding, ENCODING_UUENCODE4))
+ {
+ static const char *uue_exts[] = { "uu", "uue", 0 };
+ exts = uue_exts;
+ }
+
+ while (exts && *exts)
+ {
+ const char *ext = *exts;
+ PRInt32 L2 = PL_strlen(ext);
+ if (L > L2 + 1 && /* long enough */
+ result[L - L2 - 1] == '.' && /* '.' in right place*/
+ !PL_strcasecmp(ext, result + (L - L2))) /* ext matches */
+ {
+ result[L - L2 - 1] = 0; /* truncate at '.' and stop. */
+ break;
+ }
+ exts++;
+ }
+ }
+}
diff --git a/mailnews/compose/src/nsMsgUtils.h b/mailnews/compose/src/nsMsgUtils.h
new file mode 100644
index 000000000000..b654c2bd6eeb
--- /dev/null
+++ b/mailnews/compose/src/nsMsgUtils.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgUtils_H_
+#define _nsMsgUtils_H_
+
+#include "nscore.h"
+#include "nsMsgSend.h"
+#include "nsFileSpec.h"
+#include "nsMsgCompFields.h"
+#include "nsIMsgSend.h"
+
+NS_BEGIN_EXTERN_C
+
+//
+// Create a file spec or file name using the name passed
+// in as a template
+//
+nsFileSpec *nsMsgCreateTempFileSpec(char *tFileName);
+char *nsMsgCreateTempFileName(char *tFileName);
+
+
+//
+// Various utilities for building parts of MIME encoded
+// messages during message composition
+//
+int mime_sanity_check_fields (
+ const char *from,
+ const char *reply_to,
+ const char *to,
+ const char *cc,
+ const char *bcc,
+ const char *fcc,
+ const char *newsgroups,
+ const char *followup_to,
+ const char * /*subject*/,
+ const char * /*references*/,
+ const char * /*organization*/,
+ const char * /*other_random_headers*/);
+
+char *mime_generate_headers (nsMsgCompFields *fields,
+ const char *charset,
+ nsMsgDeliverMode deliver_mode);
+
+char *mime_make_separator(const char *prefix);
+
+char *mime_generate_attachment_headers (const char *type,
+ const char *encoding,
+ const char *description,
+ const char *x_mac_type,
+ const char *x_mac_creator,
+ const char *real_name,
+ const char *base_url,
+ PRBool digest_p,
+ nsMsgAttachmentHandler *ma,
+ const char *charset);
+
+char *msg_generate_message_id (void);
+
+char *RFC2231ParmFolding(const char *parmName, const char *charset,
+ const char *language, const char *parmValue);
+
+PRBool mime_7bit_data_p (const char *string, PRUint32 size);
+
+char *mime_fix_header_1 (const char *string, PRBool addr_p, PRBool news_p);
+char *mime_fix_header (const char *string);
+char *mime_fix_addr_header (const char *string);
+char *mime_fix_news_header (const char *string);
+
+PRBool mime_type_requires_b64_p (const char *type);
+PRBool mime_type_needs_charset (const char *type);
+
+int nsMsgMIMEGenerateMailtoFormPostHeaders (const char *old_post_url,
+ const char * /*referer*/,
+ char **new_post_url_return,
+ char **headers_return);
+
+char *msg_make_filename_qtext(const char *srcText, PRBool stripCRLFs);
+
+// Rip apart the URL and extract a reasonable value for the `real_name' slot.
+void msg_pick_real_name (nsMsgAttachmentHandler *attachment, const char *charset);
+
+//
+// Informational calls...
+//
+void nsMsgMIMESetConformToStandard (PRBool conform_p);
+PRBool nsMsgMIMEGetConformToStandard (void);
+
+
+NS_END_EXTERN_C
+
+
+#endif /* _nsMsgUtils_H_ */
+
diff --git a/mailnews/compose/src/nsMsgZapIt.cpp b/mailnews/compose/src/nsMsgZapIt.cpp
new file mode 100644
index 000000000000..5166b112b30e
--- /dev/null
+++ b/mailnews/compose/src/nsMsgZapIt.cpp
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "msgCore.h"
+#include "nsMsgZapIt.h"
+#include "nsCRT.h"
+
+#if defined(XP_OS2) && defined(__DEBUG_ALLOC__)
+void* nsMsgZapIt::operator new(size_t size, const char *file, size_t line) {
+ void* rv = ::operator new(size, file, line);
+ if (rv) {
+ nsCRT::memset(rv, 0, size);
+ }
+ return rv;
+}
+#else
+void* nsMsgZapIt::operator new(size_t size) {
+ void* rv = ::operator new(size);
+ if (rv) {
+ nsCRT::memset(rv, 0, size);
+ }
+ return rv;
+}
+
+#endif
+
\ No newline at end of file
diff --git a/mailnews/compose/src/nsMsgZapIt.h b/mailnews/compose/src/nsMsgZapIt.h
new file mode 100644
index 000000000000..f3c005b8f182
--- /dev/null
+++ b/mailnews/compose/src/nsMsgZapIt.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef _nsMsgZapIt_H_
+#define _nsMsgZapIt_H_
+
+// The whole purpose of this class is to redefine operator new for any subclass
+// so that it will automatically zero out the whole class for me; thanks.
+
+class nsMsgZapIt {
+public:
+#if defined(XP_OS2) && defined(__DEBUG_ALLOC__)
+ static void* operator new(size_t size, const char *file, size_t line);
+#else
+ static void* operator new(size_t size);
+#endif
+};
+
+
+
+#endif /* _nsMsgZapIt_H_ */
diff --git a/mailnews/compose/tests/compose/test.cpp b/mailnews/compose/tests/compose/test.cpp
index 693e6a9a7aa2..0f7fb7978b91 100644
--- a/mailnews/compose/tests/compose/test.cpp
+++ b/mailnews/compose/tests/compose/test.cpp
@@ -17,6 +17,9 @@
#include "nsIServiceManager.h"
#include "nscore.h"
#include "nsIMsgMailSession.h"
+#include "nsINetSupportDialogService.h"
+#include "nsIAppShellService.h"
+#include "nsAppShellCIDs.h"
#include "nsINetService.h"
@@ -35,6 +38,7 @@
#include "prmem.h"
#include "nsIMimeURLUtils.h"
+#include "nsMsgSendLater.h"
#ifdef XP_PC
@@ -64,8 +68,8 @@
static NS_DEFINE_CID(kNetServiceCID, NS_NETSERVICE_CID);
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kSmtpServiceCID, NS_SMTPSERVICE_CID);
-static NS_DEFINE_IID(kFileLocatorCID, NS_FILELOCATOR_CID);
-static NS_DEFINE_IID(kEventQueueCID, NS_EVENTQUEUE_CID);
+static NS_DEFINE_CID(kFileLocatorCID, NS_FILELOCATOR_CID);
+static NS_DEFINE_CID(kEventQueueCID, NS_EVENTQUEUE_CID);
static NS_DEFINE_IID(kIMsgComposeIID, NS_IMSGCOMPOSE_IID);
static NS_DEFINE_CID(kCMsgMailSessionCID, NS_MSGMAILSESSION_CID);
static NS_DEFINE_CID(kMsgComposeCID, NS_MSGCOMPOSE_CID);
@@ -75,6 +79,29 @@ static NS_DEFINE_IID(kIMsgSendIID, NS_IMSGSEND_IID);
static NS_DEFINE_CID(kMsgSendCID, NS_MSGSEND_CID);
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kMimeURLUtilsCID, NS_IMIME_URLUTILS_CID);
+static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID);
+static NS_DEFINE_CID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID);
+static NS_DEFINE_IID(kIAppShellServiceIID, NS_IAPPSHELL_SERVICE_IID);
+
+
+static NS_DEFINE_IID(kIMsgSendLaterIID, NS_IMSGSENDLATER_IID);
+static NS_DEFINE_CID(kMsgSendLaterCID, NS_MSGSENDLATER_CID);
+
+
+void
+DoIT()
+{
+ nsresult rv = NS_OK;
+ nsIMsgSendLater *pMsgSendLater;
+
+ rv = nsComponentManager::CreateInstance(kMsgSendLaterCID, NULL, kIMsgSendLaterIID, (void **) &pMsgSendLater);
+ if (rv == NS_OK && pMsgSendLater)
+ {
+ printf("We succesfully obtained a nsIMsgSendLater interface....\n");
+ nsIMsgIdentity *identity = nsnull;
+ pMsgSendLater->SendUnsentMessages(identity, "Outbox", "nsmail-2");
+ }
+}
nsresult OnIdentityCheck()
{
@@ -119,8 +146,8 @@ GetAttachments(void)
return NULL;
nsCRT::memset(attachments, 0, sizeof(MSG_AttachedFile) * 2);
- attachments[0].orig_url = PL_strdup("file://C:/big.bmp");
- attachments[0].file_name = PL_strdup("C:\\big.bmp");
+ attachments[0].orig_url = PL_strdup("file://C:/boxster.jpg");
+ attachments[0].file_name = PL_strdup("C:\\boxster.jpg");
attachments[0].type = PL_strdup("image/jpeg");
attachments[0].encoding = PL_strdup(ENCODING_BINARY);
attachments[0].description = PL_strdup("Boxster Image");
@@ -150,6 +177,7 @@ int main(int argc, char *argv[])
nsIMsgCompFields *pMsgCompFields;
nsIMsgSend *pMsgSend;
nsresult rv = NS_OK;
+ nsIAppShellService* appShell = nsnull;
nsComponentManager::RegisterComponent(kNetServiceCID, NULL, NULL, NETLIB_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kEventQueueServiceCID, NULL, NULL, XPCOM_DLL, PR_FALSE, PR_FALSE);
@@ -157,6 +185,19 @@ int main(int argc, char *argv[])
nsComponentManager::RegisterComponent(kPrefCID, nsnull, nsnull, PREF_DLL, PR_TRUE, PR_TRUE);
nsComponentManager::RegisterComponent(kFileLocatorCID, NULL, NULL, APPSHELL_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kMimeURLUtilsCID, NULL, NULL, MIME_DLL, PR_FALSE, PR_FALSE);
+ nsComponentManager::RegisterComponent(kNetSupportDialogCID, NULL, NULL, APPSHELL_DLL, PR_FALSE, PR_FALSE);
+ nsComponentManager::RegisterComponent(kAppShellServiceCID, NULL, NULL, APPSHELL_DLL, PR_FALSE, PR_FALSE);
+
+ /*
+ * Create the Application Shell instance...
+ */
+ nsIWebShellWindow* newWindow;
+ rv = nsServiceManager::GetService(kAppShellServiceCID,
+ kIAppShellServiceIID,
+ (nsISupports**)&appShell);
+ if (NS_SUCCEEDED(rv))
+ appShell->CreateTopLevelWindow(nsnull, nsnull, PR_TRUE, newWindow,
+ nsnull, nsnull, 200, 200);
// Create the Event Queue for this thread...
NS_WITH_SERVICE(nsIEventQueueService, pEventQService, kEventQueueServiceCID, &rv);
@@ -195,6 +236,8 @@ int main(int argc, char *argv[])
OnIdentityCheck();
+ DoIT();
+
rv = nsComponentManager::CreateInstance(kMsgCompFieldsCID, NULL,
nsIMsgCompFields::GetIID(), (void **) &pMsgCompFields);
if (rv == NS_OK && pMsgCompFields) {
@@ -236,7 +279,7 @@ int main(int argc, char *argv[])
else
nBodyLength = 0;
- // nsMsgAttachmentData *ptr = GetAttachments();
+ //nsMsgAttachedFile *ptr = NULL;
nsMsgAttachedFile *ptr = GetAttachments();
pMsgSend->SendMessage(pMsgCompFields,