aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbuild-mac/mailcore2.xcodeproj/project.pbxproj24
-rw-r--r--src/async/nntp/MCAsyncNNTP.h1
-rw-r--r--src/async/nntp/MCNNTPAsyncSession.cpp19
-rw-r--r--src/async/nntp/MCNNTPAsyncSession.h4
-rw-r--r--src/async/nntp/MCNNTPSendOperation.cpp58
-rw-r--r--src/async/nntp/MCNNTPSendOperation.h44
-rw-r--r--src/core/nntp/MCNNTPSession.cpp135
-rw-r--r--src/core/nntp/MCNNTPSession.h7
-rw-r--r--src/objc/nntp/MCONNTP.h1
-rw-r--r--src/objc/nntp/MCONNTPSendOperation.h41
-rw-r--r--src/objc/nntp/MCONNTPSendOperation.mm116
-rw-r--r--src/objc/nntp/MCONNTPSession.h27
-rw-r--r--src/objc/nntp/MCONNTPSession.mm12
13 files changed, 489 insertions, 0 deletions
diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj
index cc76c25f..64058b61 100755
--- a/build-mac/mailcore2.xcodeproj/project.pbxproj
+++ b/build-mac/mailcore2.xcodeproj/project.pbxproj
@@ -962,6 +962,14 @@
DAD28C8C1783CFFC00F2BB8F /* MCHTMLBodyRendererTemplateCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DAD28C891783CFFC00F2BB8F /* MCHTMLBodyRendererTemplateCallback.cpp */; };
DAE42E89178F7E1800E0DB8F /* MCOIMAPMessageRenderingOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DA89896B178A47D200F6D90A /* MCOIMAPMessageRenderingOperation.h */; };
DAE42E8A178F7E2200E0DB8F /* MCOIMAPMessageRenderingOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DA89896B178A47D200F6D90A /* MCOIMAPMessageRenderingOperation.h */; };
+ F382219F1C7A626700E00721 /* MCNNTPSendOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F382219E1C7A626700E00721 /* MCNNTPSendOperation.cpp */; };
+ F38221A01C7A626700E00721 /* MCNNTPSendOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F382219E1C7A626700E00721 /* MCNNTPSendOperation.cpp */; };
+ F38221A31C7AAD8100E00721 /* MCONNTPSendOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = F38221A21C7AAD8100E00721 /* MCONNTPSendOperation.mm */; };
+ F38221A41C7AAD8100E00721 /* MCONNTPSendOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = F38221A21C7AAD8100E00721 /* MCONNTPSendOperation.mm */; };
+ F38221A51C7B629B00E00721 /* MCNNTPSendOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F382219D1C7A60A800E00721 /* MCNNTPSendOperation.h */; };
+ F38221A61C7B62E900E00721 /* MCONNTPSendOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F38221A11C7AAD8100E00721 /* MCONNTPSendOperation.h */; };
+ F38221A71C7B638200E00721 /* MCNNTPSendOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F382219D1C7A60A800E00721 /* MCNNTPSendOperation.h */; };
+ F38221A81C7B63E500E00721 /* MCONNTPSendOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F38221A11C7AAD8100E00721 /* MCONNTPSendOperation.h */; };
F87F190C16BB62B00012652F /* MCOIMAPFetchFoldersOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = F87F190B16BB62B00012652F /* MCOIMAPFetchFoldersOperation.mm */; };
F8EA941716BB1C9D0011AC6F /* MCOIMAPSession.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F8EA941416BAED6E0011AC6F /* MCOIMAPSession.h */; };
/* End PBXBuildFile section */
@@ -1027,6 +1035,8 @@
dstPath = include/MailCore;
dstSubfolderSpec = 16;
files = (
+ F38221A81C7B63E500E00721 /* MCONNTPSendOperation.h in CopyFiles */,
+ F38221A71C7B638200E00721 /* MCNNTPSendOperation.h in CopyFiles */,
C6BEC1AB1B1256C100546519 /* MCHTMLCleaner.h in CopyFiles */,
27E91D601A80D3F4005A3244 /* MCMXRecordResolverOperation.h in CopyFiles */,
27478E861A76475F004AE621 /* MCOAccountValidator.h in CopyFiles */,
@@ -1264,6 +1274,8 @@
dstPath = include/MailCore;
dstSubfolderSpec = 16;
files = (
+ F38221A61C7B62E900E00721 /* MCONNTPSendOperation.h in CopyFiles */,
+ F38221A51C7B629B00E00721 /* MCNNTPSendOperation.h in CopyFiles */,
C6BEC1AA1B1256BA00546519 /* MCHTMLCleaner.h in CopyFiles */,
276A65D01A7B7E7D008722C2 /* MCMXRecordResolverOperation.h in CopyFiles */,
27478E881A7647AC004AE621 /* MCOAccountValidator.h in CopyFiles */,
@@ -2107,6 +2119,10 @@
DAACAD5017886807000B4517 /* MCHTMLRendererIMAPDataCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCHTMLRendererIMAPDataCallback.h; sourceTree = "<group>"; };
DAD28C891783CFFC00F2BB8F /* MCHTMLBodyRendererTemplateCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCHTMLBodyRendererTemplateCallback.cpp; sourceTree = "<group>"; };
DAD28C8A1783CFFC00F2BB8F /* MCHTMLBodyRendererTemplateCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCHTMLBodyRendererTemplateCallback.h; sourceTree = "<group>"; };
+ F382219D1C7A60A800E00721 /* MCNNTPSendOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCNNTPSendOperation.h; sourceTree = "<group>"; };
+ F382219E1C7A626700E00721 /* MCNNTPSendOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCNNTPSendOperation.cpp; sourceTree = "<group>"; };
+ F38221A11C7AAD8100E00721 /* MCONNTPSendOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCONNTPSendOperation.h; sourceTree = "<group>"; };
+ F38221A21C7AAD8100E00721 /* MCONNTPSendOperation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCONNTPSendOperation.mm; sourceTree = "<group>"; };
F87F190816BB62690012652F /* MCOIMAPFetchFoldersOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPFetchFoldersOperation.h; sourceTree = "<group>"; };
F87F190B16BB62B00012652F /* MCOIMAPFetchFoldersOperation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPFetchFoldersOperation.mm; sourceTree = "<group>"; };
F8EA941416BAED6E0011AC6F /* MCOIMAPSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPSession.h; sourceTree = "<group>"; };
@@ -2265,6 +2281,8 @@
84D7372E199BF704005124E5 /* MCNNTPOperation.cpp */,
84D7372F199BF704005124E5 /* MCNNTPOperation.h */,
84D7373F199BF887005124E5 /* MCNNTPOperationCallback.h */,
+ F382219D1C7A60A800E00721 /* MCNNTPSendOperation.h */,
+ F382219E1C7A626700E00721 /* MCNNTPSendOperation.cpp */,
);
path = nntp;
sourceTree = "<group>";
@@ -2294,6 +2312,8 @@
84D7378E199C02A8005124E5 /* MCONNTPDisconnectOperation.mm */,
84D73791199C0511005124E5 /* MCONNTPGroupInfo.h */,
84D73792199C0511005124E5 /* MCONNTPGroupInfo.mm */,
+ F38221A11C7AAD8100E00721 /* MCONNTPSendOperation.h */,
+ F38221A21C7AAD8100E00721 /* MCONNTPSendOperation.mm */,
);
path = nntp;
sourceTree = "<group>";
@@ -3664,6 +3684,7 @@
C6F61F9917016B460073032E /* MCOIMAPSearchExpression.mm in Sources */,
C6F61F9F17016EA10073032E /* MCOIMAPFolderInfo.mm in Sources */,
C6D4FD3F19FB7534001F7E01 /* MCMessageParserMac.mm in Sources */,
+ F38221A31C7AAD8100E00721 /* MCONNTPSendOperation.mm in Sources */,
C6F61FB51702AB340073032E /* MCOIMAPBaseOperation.mm in Sources */,
C608167517759967001F1018 /* MCSMTPDisconnectOperation.cpp in Sources */,
C6A81BBF17068E5E00882C15 /* MCOSMTPSession.mm in Sources */,
@@ -3707,6 +3728,7 @@
9EF9AB09175F2EC60027FA3B /* MCOIMAPFolderStatus.mm in Sources */,
9EF9AB11175F319A0027FA3B /* MCIMAPFolderStatusOperation.cpp in Sources */,
9EF9AB19175F36600027FA3B /* MCOIMAPFolderStatusOperation.mm in Sources */,
+ F382219F1C7A626700E00721 /* MCNNTPSendOperation.cpp in Sources */,
9E774D891767C7F60065EB9B /* MCIMAPFolderStatus.cpp in Sources */,
DAD28C8B1783CFFC00F2BB8F /* MCHTMLBodyRendererTemplateCallback.cpp in Sources */,
BD63713B177DFF080094121B /* MCLibetpan.cpp in Sources */,
@@ -3940,6 +3962,7 @@
C6E665BC1796500C0063F2CF /* unzip.c in Sources */,
C6BA2C121705F4E6003F0E9E /* MCOIMAPSearchExpression.mm in Sources */,
C6D4FD4019FB7786001F7E01 /* MCMessageParserMac.mm in Sources */,
+ F38221A41C7AAD8100E00721 /* MCONNTPSendOperation.mm in Sources */,
C6BA2C131705F4E6003F0E9E /* MCOIMAPFolderInfo.mm in Sources */,
C6BA2C141705F4E6003F0E9E /* MCOIMAPBaseOperation.mm in Sources */,
C608167617759968001F1018 /* MCSMTPDisconnectOperation.cpp in Sources */,
@@ -3983,6 +4006,7 @@
C6CF62CB175324F0006398B9 /* MCNetService.cpp in Sources */,
9EF9AB0A175F2EC60027FA3B /* MCOIMAPFolderStatus.mm in Sources */,
9EF9AB12175F319A0027FA3B /* MCIMAPFolderStatusOperation.cpp in Sources */,
+ F38221A01C7A626700E00721 /* MCNNTPSendOperation.cpp in Sources */,
9EF9AB1A175F36600027FA3B /* MCOIMAPFolderStatusOperation.mm in Sources */,
9E774D8A1767C7F60065EB9B /* MCIMAPFolderStatus.cpp in Sources */,
DAD28C8C1783CFFC00F2BB8F /* MCHTMLBodyRendererTemplateCallback.cpp in Sources */,
diff --git a/src/async/nntp/MCAsyncNNTP.h b/src/async/nntp/MCAsyncNNTP.h
index 914cc754..57b80cb8 100644
--- a/src/async/nntp/MCAsyncNNTP.h
+++ b/src/async/nntp/MCAsyncNNTP.h
@@ -18,6 +18,7 @@
#include <MailCore/MCNNTPListNewsgroupsOperation.h>
#include <MailCore/MCNNTPFetchOverviewOperation.h>
#include <MailCore/MCNNTPFetchServerTimeOperation.h>
+#include <MailCore/MCNNTPSendOperation.h>
#include <MailCore/MCNNTPOperationCallback.h>
#endif
diff --git a/src/async/nntp/MCNNTPAsyncSession.cpp b/src/async/nntp/MCNNTPAsyncSession.cpp
index ad74f7a9..ddd4c804 100644
--- a/src/async/nntp/MCNNTPAsyncSession.cpp
+++ b/src/async/nntp/MCNNTPAsyncSession.cpp
@@ -16,6 +16,7 @@
#include "MCNNTPFetchOverviewOperation.h"
#include "MCNNTPCheckAccountOperation.h"
#include "MCNNTPFetchServerTimeOperation.h"
+#include "MCNNTPSendOperation.h"
#include "MCNNTPDisconnectOperation.h"
#include "MCOperationQueueCallback.h"
#include "MCConnectionLogger.h"
@@ -236,6 +237,24 @@ NNTPListNewsgroupsOperation * NNTPAsyncSession::listDefaultNewsgroupsOperation()
return op;
}
+NNTPSendOperation * NNTPAsyncSession::sendMessageOperation(Data * messageData)
+{
+ NNTPSendOperation * op = new NNTPSendOperation();
+ op->setSession(this);
+ op->setMessageData(messageData);
+ op->autorelease();
+ return op;
+}
+
+NNTPSendOperation * NNTPAsyncSession::sendMessageOperation(String * filename)
+{
+ NNTPSendOperation * op = new NNTPSendOperation();
+ op->setSession(this);
+ op->setMessageFilepath(filename);
+ op->autorelease();
+ return op;
+}
+
NNTPOperation * NNTPAsyncSession::disconnectOperation()
{
NNTPDisconnectOperation * op = new NNTPDisconnectOperation();
diff --git a/src/async/nntp/MCNNTPAsyncSession.h b/src/async/nntp/MCNNTPAsyncSession.h
index b3e40ea8..c41066ac 100644
--- a/src/async/nntp/MCNNTPAsyncSession.h
+++ b/src/async/nntp/MCNNTPAsyncSession.h
@@ -16,6 +16,7 @@ namespace mailcore {
class NNTPFetchOverviewOperation;
class NNTPListNewsgroupsOperation;
class NNTPFetchServerTimeOperation;
+ class NNTPSendOperation;
class NNTPOperationQueueCallback;
class NNTPConnectionLogger;
@@ -72,6 +73,9 @@ namespace mailcore {
virtual NNTPListNewsgroupsOperation * listAllNewsgroupsOperation();
virtual NNTPListNewsgroupsOperation * listDefaultNewsgroupsOperation();
+ virtual NNTPSendOperation * sendMessageOperation(Data * messageData);
+ virtual NNTPSendOperation * sendMessageOperation(String * filename);
+
virtual NNTPOperation * disconnectOperation();
virtual NNTPOperation * checkAccountOperation();
diff --git a/src/async/nntp/MCNNTPSendOperation.cpp b/src/async/nntp/MCNNTPSendOperation.cpp
new file mode 100644
index 00000000..d5f27928
--- /dev/null
+++ b/src/async/nntp/MCNNTPSendOperation.cpp
@@ -0,0 +1,58 @@
+//
+// MCNNTPSendOperation.cpp
+// mailcore2
+//
+// Created by Daryle Walker on 2/21/16.
+// Copyright © 2016 MailCore. All rights reserved.
+//
+
+#include "MCNNTPSendOperation.h"
+
+#include "MCNNTPAsyncSession.h"
+#include "MCNNTPSession.h"
+
+using namespace mailcore;
+
+NNTPSendOperation::NNTPSendOperation()
+{
+ mMessageData = NULL;
+ mMessageFilepath = NULL;
+}
+
+NNTPSendOperation::~NNTPSendOperation()
+{
+ MC_SAFE_RELEASE(mMessageFilepath);
+ MC_SAFE_RELEASE(mMessageData);
+}
+
+void NNTPSendOperation::setMessageData(Data * data)
+{
+ MC_SAFE_REPLACE_RETAIN(Data, mMessageData, data);
+}
+
+Data * NNTPSendOperation::messageData()
+{
+ return mMessageData;
+}
+
+void NNTPSendOperation::setMessageFilepath(String * path)
+{
+ MC_SAFE_REPLACE_RETAIN(String, mMessageFilepath, path);
+}
+
+String * NNTPSendOperation::messageFilepath()
+{
+ return mMessageFilepath;
+}
+
+void NNTPSendOperation::main()
+{
+ ErrorCode error;
+ if (mMessageFilepath != NULL) {
+ session()->session()->sendMessage(mMessageFilepath, this, &error);
+ }
+ else {
+ session()->session()->sendMessage(mMessageData, this, &error);
+ }
+ setError(error);
+}
diff --git a/src/async/nntp/MCNNTPSendOperation.h b/src/async/nntp/MCNNTPSendOperation.h
new file mode 100644
index 00000000..d859cd58
--- /dev/null
+++ b/src/async/nntp/MCNNTPSendOperation.h
@@ -0,0 +1,44 @@
+//
+// MCNNTPSendOperation.h
+// mailcore2
+//
+// Created by Daryle Walker on 2/21/16.
+// Copyright © 2016 MailCore. All rights reserved.
+//
+
+#ifndef MAILCORE_MCNNTPSENDOPERATION_H
+
+#define MAILCORE_MCNNTPSENDOPERATION_H
+
+#include <MailCore/MCBaseTypes.h>
+#include <MailCore/MCAbstract.h>
+#include <MailCore/MCNNTPOperation.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class MAILCORE_EXPORT NNTPSendOperation : public NNTPOperation {
+ public:
+ NNTPSendOperation();
+ virtual ~NNTPSendOperation();
+
+ virtual void setMessageData(Data * data);
+ virtual Data * messageData();
+
+ virtual void setMessageFilepath(String * path);
+ virtual String * messageFilepath();
+
+ public: // subclass behavior
+ virtual void main();
+
+ private:
+ Data * mMessageData;
+ String * mMessageFilepath;
+ };
+
+}
+
+#endif
+
+#endif
diff --git a/src/core/nntp/MCNNTPSession.cpp b/src/core/nntp/MCNNTPSession.cpp
index 933f10f2..c40301a4 100644
--- a/src/core/nntp/MCNNTPSession.cpp
+++ b/src/core/nntp/MCNNTPSession.cpp
@@ -15,6 +15,7 @@
#include "MCNNTPGroupInfo.h"
#include "MCMessageHeader.h"
+#include "MCNNTPProgressCallback.h"
#include "MCConnectionLoggerUtils.h"
#include "MCCertificateUtils.h"
#include "MCLibetpan.h"
@@ -45,6 +46,7 @@ void NNTPSession::init()
mTimeout = 30;
mNNTP = NULL;
+ mProgressCallback = NULL;
mState = STATE_DISCONNECTED;
mConnectionLogger = NULL;
}
@@ -138,6 +140,21 @@ bool NNTPSession::checkCertificate()
return mailcore::checkCertificate(mNNTP->nntp_stream, hostname());
}
+void NNTPSession::body_progress(size_t current, size_t maximum, void * context)
+{
+ NNTPSession * session;
+
+ session = (NNTPSession *) context;
+ session->bodyProgress((unsigned int) current, (unsigned int) maximum);
+}
+
+void NNTPSession::bodyProgress(unsigned int current, unsigned int maximum)
+{
+ if (mProgressCallback != NULL) {
+ mProgressCallback->bodyProgress(this, current, maximum);
+ }
+}
+
static void logger(newsnntp * nntp, int log_type, const char * buffer, size_t size, void * context)
{
NNTPSession * session = (NNTPSession *) context;
@@ -605,6 +622,124 @@ Array * NNTPSession::fetchOverArticlesInRange(Range range, String * groupName, E
return result;
}
+void NNTPSession::sendMessage(Data * messageData, NNTPProgressCallback * callback, ErrorCode * pError)
+{
+ int r;
+
+ messageData = dataWithFilteredBcc(messageData);
+
+ mProgressCallback = callback;
+ bodyProgress(0, messageData->length());
+
+ MCLog("setup");
+
+ MCLog("connect");
+ loginIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ goto err;
+ }
+
+ MCLog("send");
+ r = newsnntp_post(mNNTP, messageData->bytes(), messageData->length());
+
+ String * response;
+
+ response = NULL;
+ if (mNNTP->nntp_response != NULL) {
+ response = String::stringWithUTF8Characters(mNNTP->nntp_response);
+ }
+
+ if (r == NEWSNNTP_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ goto err;
+ }
+ else if (r != NEWSNNTP_NO_ERROR) {
+ * pError = ErrorSendMessage;
+ goto err;
+ }
+
+ bodyProgress(messageData->length(), messageData->length());
+ * pError = ErrorNone;
+
+err:
+ mProgressCallback = NULL;
+}
+
+void NNTPSession::sendMessage(String * messagePath, NNTPProgressCallback * callback, ErrorCode * pError)
+{
+ Data * messageData = Data::dataWithContentsOfFile(messagePath);
+ if (!messageData) {
+ * pError = ErrorFile;
+ return;
+ }
+
+ return sendMessage(messageData, callback, pError);
+}
+
+static void mmapStringDeallocator(char * bytes, unsigned int length) {
+ mmap_string_unref(bytes);
+}
+
+Data * NNTPSession::dataWithFilteredBcc(Data * data)
+{
+ int r;
+ size_t idx;
+ struct mailimf_message * msg;
+
+ idx = 0;
+ r = mailimf_message_parse(data->bytes(), data->length(), &idx, &msg);
+ if (r != MAILIMF_NO_ERROR) {
+ return Data::data();
+ }
+
+ struct mailimf_fields * fields = msg->msg_fields;
+ int col = 0;
+
+ int hasRecipient = 0;
+ bool bccWasActuallyRemoved = false;
+ for(clistiter * cur = clist_begin(fields->fld_list) ; cur != NULL ; cur = clist_next(cur)) {
+ struct mailimf_field * field = (struct mailimf_field *) clist_content(cur);
+ if (field->fld_type == MAILIMF_FIELD_BCC) {
+ mailimf_field_free(field);
+ clist_delete(fields->fld_list, cur);
+ bccWasActuallyRemoved = true;
+ break;
+ }
+ else if ((field->fld_type == MAILIMF_FIELD_TO) || (field->fld_type == MAILIMF_FIELD_CC)) {
+ hasRecipient = 1;
+ }
+ }
+ if (!hasRecipient) {
+ struct mailimf_address_list * imfTo;
+ imfTo = mailimf_address_list_new_empty();
+ mailimf_address_list_add_parse(imfTo, (char *) "Undisclosed recipients:;");
+ struct mailimf_to * toField = mailimf_to_new(imfTo);
+ struct mailimf_field * field = mailimf_field_new(MAILIMF_FIELD_TO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, toField, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ mailimf_fields_add(fields, field);
+ }
+
+ Data * result;
+ if (!hasRecipient || bccWasActuallyRemoved) {
+ MMAPString * str = mmap_string_new("");
+ mailimf_fields_write_mem(str, &col, fields);
+ mmap_string_append(str, "\n");
+ mmap_string_append_len(str, msg->msg_body->bd_text, msg->msg_body->bd_size);
+
+ mmap_string_ref(str);
+
+ result = Data::data();
+ result->takeBytesOwnership(str->str, (unsigned int) str->len, mmapStringDeallocator);
+ }
+ else {
+ // filter Bcc and modify To: only if necessary.
+ result = data;
+ }
+
+ mailimf_message_free(msg);
+
+ return result;
+}
+
void NNTPSession::selectGroup(String * folder, ErrorCode * pError)
{
int r;
diff --git a/src/core/nntp/MCNNTPSession.h b/src/core/nntp/MCNNTPSession.h
index ec0080ed..94669edd 100644
--- a/src/core/nntp/MCNNTPSession.h
+++ b/src/core/nntp/MCNNTPSession.h
@@ -57,6 +57,9 @@ namespace mailcore {
virtual time_t fetchServerDate(ErrorCode * pError);
+ virtual void sendMessage(Data * messageData, NNTPProgressCallback * callback, ErrorCode * pError);
+ virtual void sendMessage(String * messagePath, NNTPProgressCallback * callback, ErrorCode * pError);
+
virtual void setConnectionLogger(ConnectionLogger * logger);
virtual ConnectionLogger * connectionLogger();
@@ -70,11 +73,15 @@ namespace mailcore {
time_t mTimeout;
newsnntp * mNNTP;
+ NNTPProgressCallback * mProgressCallback;
int mState;
ConnectionLogger * mConnectionLogger;
void init();
+ Data * dataWithFilteredBcc(Data * data);
+ static void body_progress(size_t current, size_t maximum, void * context);
+ void bodyProgress(unsigned int current, unsigned int maximum);
bool checkCertificate();
void setup();
void unsetup();
diff --git a/src/objc/nntp/MCONNTP.h b/src/objc/nntp/MCONNTP.h
index 71979dfa..213384c4 100644
--- a/src/objc/nntp/MCONNTP.h
+++ b/src/objc/nntp/MCONNTP.h
@@ -18,6 +18,7 @@
#include <MailCore/MCONNTPListNewsgroupsOperation.h>
#include <MailCore/MCONNTPFetchOverviewOperation.h>
#include <MailCore/MCONNTPFetchServerTimeOperation.h>
+#include <MailCore/MCONNTPSendOperation.h>
#include <MailCore/MCONNTPGroupInfo.h>
#endif
diff --git a/src/objc/nntp/MCONNTPSendOperation.h b/src/objc/nntp/MCONNTPSendOperation.h
new file mode 100644
index 00000000..b59c6e80
--- /dev/null
+++ b/src/objc/nntp/MCONNTPSendOperation.h
@@ -0,0 +1,41 @@
+//
+// MCONNTPSendOperation.h
+// mailcore2
+//
+// Created by Daryle Walker on 2/21/16.
+// Copyright © 2016 MailCore. All rights reserved.
+//
+
+#ifndef MAILCORE_MCONNTPSENDOPERATION_H
+
+#define MAILCORE_MCONNTPSENDOPERATION_H
+
+#import <Foundation/Foundation.h>
+#import <MailCore/MCONNTPOperation.h>
+
+/** Send a message from NNTP3 */
+
+typedef void (^MCONNTPOperationProgressBlock)(unsigned int current, unsigned int maximum);
+
+NS_ASSUME_NONNULL_BEGIN
+@interface MCONNTPSendOperation : MCONNTPOperation
+
+/** This block will be called as data is downloaded from the network */
+@property (nonatomic, copy) MCONNTPOperationProgressBlock progress;
+
+/**
+ Starts the asynchronous send operation.
+
+ @param completionBlock Called when the operation is finished.
+
+ - On success `error` will be nil
+
+ - On failure, `error` will be set with `MCOErrorDomain` as domain and an
+ error code available in MCOConstants.h
+ */
+- (void) start:(void (^)(NSError * __nullable error))completionBlock;
+
+@end
+NS_ASSUME_NONNULL_END
+
+#endif
diff --git a/src/objc/nntp/MCONNTPSendOperation.mm b/src/objc/nntp/MCONNTPSendOperation.mm
new file mode 100644
index 00000000..db1277af
--- /dev/null
+++ b/src/objc/nntp/MCONNTPSendOperation.mm
@@ -0,0 +1,116 @@
+//
+// MCONNTPSendOperation.mm
+// mailcore2
+//
+// Created by Daryle Walker on 2/21/16.
+// Copyright © 2016 MailCore. All rights reserved.
+//
+
+#import "MCONNTPSendOperation.h"
+
+#import "MCAsyncNNTP.h"
+
+#import "MCOUtils.h"
+#import "MCOOperation+Private.h"
+
+#define nativeType mailcore::NNTPSendOperation
+
+typedef void (^CompletionType)(NSError *error);
+
+@interface MCONNTPSendOperation ()
+
+- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum;
+
+@end
+
+class MCONNTPSendOperationCallback : public mailcore::NNTPOperationCallback {
+public:
+ MCONNTPSendOperationCallback(MCONNTPSendOperation * op)
+ {
+ mOperation = op;
+ }
+ virtual ~MCONNTPSendOperationCallback()
+ {
+ }
+
+ virtual void bodyProgress(mailcore::NNTPOperation * session, unsigned int current, unsigned int maximum) {
+ [mOperation bodyProgress:current maximum:maximum];
+ }
+
+private:
+ MCONNTPSendOperation * mOperation;
+};
+
+@implementation MCONNTPSendOperation {
+ CompletionType _completionBlock;
+ MCONNTPSendOperationCallback * _popCallback;
+ MCONNTPOperationProgressBlock _progress;
+}
+
+@synthesize progress = _progress;
+
++ (void) load
+{
+ MCORegisterClass(self, &typeid(nativeType));
+}
+
++ (NSObject *) mco_objectWithMCObject:(mailcore::Object *)object
+{
+ nativeType * op = (nativeType *) object;
+ return [[[self alloc] initWithMCOperation:op] autorelease];
+}
+
+- (instancetype) initWithMCOperation:(mailcore::Operation *)op
+{
+ self = [super initWithMCOperation:op];
+
+ _popCallback = new MCONNTPSendOperationCallback(self);
+ ((mailcore::NNTPOperation *) op)->setNNTPCallback(_popCallback);
+
+ return self;
+}
+
+- (void) dealloc
+{
+ [_progress release];
+ [_completionBlock release];
+ delete _popCallback;
+ [super dealloc];
+}
+
+- (void) start:(void (^)(NSError *error))completionBlock
+{
+ _completionBlock = [completionBlock copy];
+ [self start];
+}
+
+- (void) cancel
+{
+ [_completionBlock release];
+ _completionBlock = nil;
+ [super cancel];
+}
+
+- (void) operationCompleted
+{
+ if (_completionBlock == NULL)
+ return;
+
+ nativeType *op = MCO_NATIVE_INSTANCE;
+ if (op->error() == mailcore::ErrorNone) {
+ _completionBlock(nil);
+ } else {
+ _completionBlock([NSError mco_errorWithErrorCode:op->error()]);
+ }
+ [_completionBlock release];
+ _completionBlock = nil;
+}
+
+- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum
+{
+ if (_progress != NULL) {
+ _progress(current, maximum);
+ }
+}
+
+@end
diff --git a/src/objc/nntp/MCONNTPSession.h b/src/objc/nntp/MCONNTPSession.h
index 29fe18af..84b1c5e7 100644
--- a/src/objc/nntp/MCONNTPSession.h
+++ b/src/objc/nntp/MCONNTPSession.h
@@ -20,6 +20,7 @@
@class MCONNTPListNewsgroupsOperation;
@class MCONNTPFetchOverviewOperation;
@class MCONNTPFetchServerTimeOperation;
+@class MCONNTPSendOperation;
@class MCONNTPOperation;
@class MCOIndexSet;
@@ -182,6 +183,32 @@ NS_ASSUME_NONNULL_BEGIN
- (MCONNTPListNewsgroupsOperation *) listDefaultNewsgroupsOperation;
/**
+ Returns an operation that will send the given message through NNTP.
+ It will use the newsgroups set in the message data.
+ It will also filter out Bcc from the content of the message.
+
+ Generate RFC 822 data using MCOMessageBuilder
+
+ MCONNTPOperation * op = [session sendOperationWithData:rfc822Data];
+ [op start:^(NSError * __nullable error) {
+ ...
+ }];
+ */
+- (MCONNTPSendOperation *) sendOperationWithData:(NSData *)messageData;
+
+/**
+ Returns an operation that will send the message from the given file through NNTP.
+ It will use the newsgroups set in the message data.
+ It will also filter out Bcc from the content of the message.
+
+ MCONNTPOperation * op = [session sendOperationWithContentsOfFile:rfc822DataFilename];
+ [op start:^(NSError * __nullable error) {
+ ...
+ }];
+ */
+- (MCONNTPSendOperation *) sendOperationWithContentsOfFile:(NSString *)path;
+
+/**
Returns an operation that will disconnect the session.
MCONNTPOperation * op = [session disconnectOperation];
diff --git a/src/objc/nntp/MCONNTPSession.mm b/src/objc/nntp/MCONNTPSession.mm
index 8237145c..4a6e0c9a 100644
--- a/src/objc/nntp/MCONNTPSession.mm
+++ b/src/objc/nntp/MCONNTPSession.mm
@@ -14,6 +14,7 @@
#import "MCONNTPOperation.h"
#import "MCOOperation+Private.h"
#import "MCONNTPFetchAllArticlesOperation.h"
+#import "MCONNTPSendOperation.h"
#import "MCONNTPOperation+Private.h"
#include "MCOperationQueueCallback.h"
@@ -205,6 +206,17 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue,
return MCO_TO_OBJC_OP(coreOp);
}
+- (MCONNTPSendOperation *) sendOperationWithData:(NSData *)messageData {
+ mailcore::NNTPSendOperation * coreOp = MCO_NATIVE_INSTANCE->sendMessageOperation(MCO_FROM_OBJC(mailcore::Data, messageData));
+ return MCO_TO_OBJC_OP(coreOp);
+}
+
+- (MCONNTPSendOperation *) sendOperationWithContentsOfFile:(NSString *)path
+{
+ mailcore::NNTPSendOperation * coreOp = MCO_NATIVE_INSTANCE->sendMessageOperation(MCO_FROM_OBJC(mailcore::String, path));
+ return MCO_TO_OBJC_OP(coreOp);
+}
+
- (MCONNTPOperation *) disconnectOperation
{
mailcore::NNTPOperation * coreOp = MCO_NATIVE_INSTANCE->disconnectOperation();