diff options
author | Hoà V. DINH <dinh.viet.hoa@gmail.com> | 2016-02-26 07:43:33 -0800 |
---|---|---|
committer | Hoà V. DINH <dinh.viet.hoa@gmail.com> | 2016-02-26 07:43:33 -0800 |
commit | eac836a9858e765e0fb07f1b1f4b325893666fe6 (patch) | |
tree | 42b328e5b80752776658de78cea84a38afec4c3e | |
parent | dbd4f63735beab5f2014597d3b1e0d67af03fe97 (diff) | |
parent | 38cae4a0a329da2618c212f545d3d8e10417af72 (diff) |
Merge pull request #1367 from CTMacUser/NNTPSendOperation
Add upload functionality to NNTP sessions.
-rwxr-xr-x | build-mac/mailcore2.xcodeproj/project.pbxproj | 24 | ||||
-rw-r--r-- | build-windows/build_headers.list | 2 | ||||
-rw-r--r-- | build-windows/mailcore2/mailcore2/mailcore2.vcxproj | 2 | ||||
-rw-r--r-- | build-windows/mailcore2/mailcore2/mailcore2.vcxproj.filters | 6 | ||||
-rw-r--r-- | src/async/nntp/MCAsyncNNTP.h | 1 | ||||
-rw-r--r-- | src/async/nntp/MCNNTPAsyncSession.cpp | 19 | ||||
-rw-r--r-- | src/async/nntp/MCNNTPAsyncSession.h | 4 | ||||
-rw-r--r-- | src/async/nntp/MCNNTPPostOperation.cpp | 58 | ||||
-rw-r--r-- | src/async/nntp/MCNNTPPostOperation.h | 44 | ||||
-rw-r--r-- | src/cmake/async.cmake | 1 | ||||
-rw-r--r-- | src/cmake/objc.cmake | 1 | ||||
-rw-r--r-- | src/cmake/public-headers.cmake | 2 | ||||
-rw-r--r-- | src/core/nntp/MCNNTPSession.cpp | 135 | ||||
-rw-r--r-- | src/core/nntp/MCNNTPSession.h | 7 | ||||
-rw-r--r-- | src/objc/nntp/MCONNTP.h | 1 | ||||
-rw-r--r-- | src/objc/nntp/MCONNTPFetchArticleOperation.h | 4 | ||||
-rw-r--r-- | src/objc/nntp/MCONNTPOperation.h | 4 | ||||
-rw-r--r-- | src/objc/nntp/MCONNTPPostOperation.h | 37 | ||||
-rw-r--r-- | src/objc/nntp/MCONNTPPostOperation.mm | 116 | ||||
-rw-r--r-- | src/objc/nntp/MCONNTPSession.h | 27 | ||||
-rw-r--r-- | src/objc/nntp/MCONNTPSession.mm | 12 |
21 files changed, 503 insertions, 4 deletions
diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index cc76c25f..51f4e1ee 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 /* MCNNTPPostOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F382219E1C7A626700E00721 /* MCNNTPPostOperation.cpp */; }; + F38221A01C7A626700E00721 /* MCNNTPPostOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F382219E1C7A626700E00721 /* MCNNTPPostOperation.cpp */; }; + F38221A31C7AAD8100E00721 /* MCONNTPPostOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = F38221A21C7AAD8100E00721 /* MCONNTPPostOperation.mm */; }; + F38221A41C7AAD8100E00721 /* MCONNTPPostOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = F38221A21C7AAD8100E00721 /* MCONNTPPostOperation.mm */; }; + F38221A51C7B629B00E00721 /* MCNNTPPostOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F382219D1C7A60A800E00721 /* MCNNTPPostOperation.h */; }; + F38221A61C7B62E900E00721 /* MCONNTPPostOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F38221A11C7AAD8100E00721 /* MCONNTPPostOperation.h */; }; + F38221A71C7B638200E00721 /* MCNNTPPostOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F382219D1C7A60A800E00721 /* MCNNTPPostOperation.h */; }; + F38221A81C7B63E500E00721 /* MCONNTPPostOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F38221A11C7AAD8100E00721 /* MCONNTPPostOperation.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 /* MCONNTPPostOperation.h in CopyFiles */, + F38221A71C7B638200E00721 /* MCNNTPPostOperation.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 /* MCONNTPPostOperation.h in CopyFiles */, + F38221A51C7B629B00E00721 /* MCNNTPPostOperation.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 /* MCNNTPPostOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCNNTPPostOperation.h; sourceTree = "<group>"; }; + F382219E1C7A626700E00721 /* MCNNTPPostOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCNNTPPostOperation.cpp; sourceTree = "<group>"; }; + F38221A11C7AAD8100E00721 /* MCONNTPPostOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCONNTPPostOperation.h; sourceTree = "<group>"; }; + F38221A21C7AAD8100E00721 /* MCONNTPPostOperation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCONNTPPostOperation.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 /* MCNNTPPostOperation.h */, + F382219E1C7A626700E00721 /* MCNNTPPostOperation.cpp */, ); path = nntp; sourceTree = "<group>"; @@ -2294,6 +2312,8 @@ 84D7378E199C02A8005124E5 /* MCONNTPDisconnectOperation.mm */, 84D73791199C0511005124E5 /* MCONNTPGroupInfo.h */, 84D73792199C0511005124E5 /* MCONNTPGroupInfo.mm */, + F38221A11C7AAD8100E00721 /* MCONNTPPostOperation.h */, + F38221A21C7AAD8100E00721 /* MCONNTPPostOperation.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 /* MCONNTPPostOperation.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 /* MCNNTPPostOperation.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 /* MCONNTPPostOperation.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 /* MCNNTPPostOperation.cpp in Sources */, 9EF9AB1A175F36600027FA3B /* MCOIMAPFolderStatusOperation.mm in Sources */, 9E774D8A1767C7F60065EB9B /* MCIMAPFolderStatus.cpp in Sources */, DAD28C8C1783CFFC00F2BB8F /* MCHTMLBodyRendererTemplateCallback.cpp in Sources */, diff --git a/build-windows/build_headers.list b/build-windows/build_headers.list index bce6d763..3d5a92e2 100644 --- a/build-windows/build_headers.list +++ b/build-windows/build_headers.list @@ -116,6 +116,7 @@ src\async\nntp\MCNNTPFetchAllArticlesOperation.h src\async\nntp\MCNNTPListNewsgroupsOperation.h src\async\nntp\MCNNTPFetchOverviewOperation.h src\async\nntp\MCNNTPFetchServerTimeOperation.h +src\async\nntp\MCNNTPPostOperation.h src\async\nntp\MCNNTPOperationCallback.h src\objc\MCObjC.h src\objc\utils\MCOUtils.h @@ -198,6 +199,7 @@ src\objc\nntp\MCONNTPFetchAllArticlesOperation.h src\objc\nntp\MCONNTPListNewsgroupsOperation.h src\objc\nntp\MCONNTPFetchOverviewOperation.h src\objc\nntp\MCONNTPFetchServerTimeOperation.h +src\objc\nntp\MCONNTPPostOperation.h src\objc\nntp\MCONNTPGroupInfo.h src\objc\provider\MCOProvider.h src\objc\provider\MCONetService.h diff --git a/build-windows/mailcore2/mailcore2/mailcore2.vcxproj b/build-windows/mailcore2/mailcore2/mailcore2.vcxproj index dbafb587..7fd762c2 100644 --- a/build-windows/mailcore2/mailcore2/mailcore2.vcxproj +++ b/build-windows/mailcore2/mailcore2/mailcore2.vcxproj @@ -63,6 +63,7 @@ <ClInclude Include="..\..\..\src\async\nntp\MCNNTPFetchOverviewOperation.h" /> <ClInclude Include="..\..\..\src\async\nntp\MCNNTPFetchServerTimeOperation.h" /> <ClInclude Include="..\..\..\src\async\nntp\MCNNTPListNewsgroupsOperation.h" /> + <ClInclude Include="..\..\..\src\async\nntp\MCNNTPPostOperation.h" /> <ClInclude Include="..\..\..\src\async\nntp\MCNNTPOperation.h" /> <ClInclude Include="..\..\..\src\async\nntp\MCNNTPOperationCallback.h" /> <ClInclude Include="..\..\..\src\async\pop\MCAsyncPOP.h" /> @@ -223,6 +224,7 @@ <ClCompile Include="..\..\..\src\async\nntp\MCNNTPFetchOverviewOperation.cpp" /> <ClCompile Include="..\..\..\src\async\nntp\MCNNTPFetchServerTimeOperation.cpp" /> <ClCompile Include="..\..\..\src\async\nntp\MCNNTPListNewsgroupsOperation.cpp" /> + <ClCompile Include="..\..\..\src\async\nntp\MCNNTPPostOperation.cpp" /> <ClCompile Include="..\..\..\src\async\nntp\MCNNTPOperation.cpp" /> <ClCompile Include="..\..\..\src\async\pop\MCPOPAsyncSession.cpp" /> <ClCompile Include="..\..\..\src\async\pop\MCPOPCheckAccountOperation.cpp" /> diff --git a/build-windows/mailcore2/mailcore2/mailcore2.vcxproj.filters b/build-windows/mailcore2/mailcore2/mailcore2.vcxproj.filters index 009251c9..77e0f971 100644 --- a/build-windows/mailcore2/mailcore2/mailcore2.vcxproj.filters +++ b/build-windows/mailcore2/mailcore2/mailcore2.vcxproj.filters @@ -537,6 +537,9 @@ <ClInclude Include="..\..\..\src\async\nntp\MCNNTPListNewsgroupsOperation.h"> <Filter>Source Files\async\nntp</Filter> </ClInclude> + <ClInclude Include="..\..\..\src\async\nntp\MCNNTPPostOperation.h"> + <Filter>Source Files\async\nntp</Filter> + </ClInclude> <ClInclude Include="..\..\..\src\async\nntp\MCNNTPOperation.h"> <Filter>Source Files\async\nntp</Filter> </ClInclude> @@ -929,6 +932,9 @@ <ClCompile Include="..\..\..\src\async\nntp\MCNNTPListNewsgroupsOperation.cpp"> <Filter>Source Files\async\nntp</Filter> </ClCompile> + <ClCompile Include="..\..\..\src\async\nntp\MCNNTPPostOperation.cpp"> + <Filter>Source Files\async\nntp</Filter> + </ClCompile> <ClCompile Include="..\..\..\src\async\nntp\MCNNTPOperation.cpp"> <Filter>Source Files\async\nntp</Filter> </ClCompile> diff --git a/src/async/nntp/MCAsyncNNTP.h b/src/async/nntp/MCAsyncNNTP.h index 914cc754..326138dc 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/MCNNTPPostOperation.h> #include <MailCore/MCNNTPOperationCallback.h> #endif diff --git a/src/async/nntp/MCNNTPAsyncSession.cpp b/src/async/nntp/MCNNTPAsyncSession.cpp index ad74f7a9..eeed1244 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 "MCNNTPPostOperation.h" #include "MCNNTPDisconnectOperation.h" #include "MCOperationQueueCallback.h" #include "MCConnectionLogger.h" @@ -236,6 +237,24 @@ NNTPListNewsgroupsOperation * NNTPAsyncSession::listDefaultNewsgroupsOperation() return op; } +NNTPPostOperation * NNTPAsyncSession::postMessageOperation(Data * messageData) +{ + NNTPPostOperation * op = new NNTPPostOperation(); + op->setSession(this); + op->setMessageData(messageData); + op->autorelease(); + return op; +} + +NNTPPostOperation * NNTPAsyncSession::postMessageOperation(String * filename) +{ + NNTPPostOperation * op = new NNTPPostOperation(); + 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..eb2531a4 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 NNTPPostOperation; class NNTPOperationQueueCallback; class NNTPConnectionLogger; @@ -72,6 +73,9 @@ namespace mailcore { virtual NNTPListNewsgroupsOperation * listAllNewsgroupsOperation(); virtual NNTPListNewsgroupsOperation * listDefaultNewsgroupsOperation(); + virtual NNTPPostOperation * postMessageOperation(Data * messageData); + virtual NNTPPostOperation * postMessageOperation(String * filename); + virtual NNTPOperation * disconnectOperation(); virtual NNTPOperation * checkAccountOperation(); diff --git a/src/async/nntp/MCNNTPPostOperation.cpp b/src/async/nntp/MCNNTPPostOperation.cpp new file mode 100644 index 00000000..c5b586f5 --- /dev/null +++ b/src/async/nntp/MCNNTPPostOperation.cpp @@ -0,0 +1,58 @@ +// +// MCNNTPPostOperation.cpp +// mailcore2 +// +// Created by Daryle Walker on 2/21/16. +// Copyright © 2016 MailCore. All rights reserved. +// + +#include "MCNNTPPostOperation.h" + +#include "MCNNTPAsyncSession.h" +#include "MCNNTPSession.h" + +using namespace mailcore; + +NNTPPostOperation::NNTPPostOperation() +{ + mMessageData = NULL; + mMessageFilepath = NULL; +} + +NNTPPostOperation::~NNTPPostOperation() +{ + MC_SAFE_RELEASE(mMessageFilepath); + MC_SAFE_RELEASE(mMessageData); +} + +void NNTPPostOperation::setMessageData(Data * data) +{ + MC_SAFE_REPLACE_RETAIN(Data, mMessageData, data); +} + +Data * NNTPPostOperation::messageData() +{ + return mMessageData; +} + +void NNTPPostOperation::setMessageFilepath(String * path) +{ + MC_SAFE_REPLACE_RETAIN(String, mMessageFilepath, path); +} + +String * NNTPPostOperation::messageFilepath() +{ + return mMessageFilepath; +} + +void NNTPPostOperation::main() +{ + ErrorCode error; + if (mMessageFilepath != NULL) { + session()->session()->postMessage(mMessageFilepath, this, &error); + } + else { + session()->session()->postMessage(mMessageData, this, &error); + } + setError(error); +} diff --git a/src/async/nntp/MCNNTPPostOperation.h b/src/async/nntp/MCNNTPPostOperation.h new file mode 100644 index 00000000..9255dafd --- /dev/null +++ b/src/async/nntp/MCNNTPPostOperation.h @@ -0,0 +1,44 @@ +// +// MCNNTPPostOperation.h +// mailcore2 +// +// Created by Daryle Walker on 2/21/16. +// Copyright © 2016 MailCore. All rights reserved. +// + +#ifndef MAILCORE_MCNNTPPOSTOPERATION_H + +#define MAILCORE_MCNNTPPOSTOPERATION_H + +#include <MailCore/MCBaseTypes.h> +#include <MailCore/MCAbstract.h> +#include <MailCore/MCNNTPOperation.h> + +#ifdef __cplusplus + +namespace mailcore { + + class MAILCORE_EXPORT NNTPPostOperation : public NNTPOperation { + public: + NNTPPostOperation(); + virtual ~NNTPPostOperation(); + + 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/cmake/async.cmake b/src/cmake/async.cmake index 329c958e..1c213a33 100644 --- a/src/cmake/async.cmake +++ b/src/cmake/async.cmake @@ -67,6 +67,7 @@ set(async_nntp_files async/nntp/MCNNTPListNewsgroupsOperation.cpp async/nntp/MCNNTPFetchOverviewOperation.cpp async/nntp/MCNNTPFetchServerTimeOperation.cpp + async/nntp/MCNNTPPostOperation.cpp async/nntp/MCNNTPOperation.cpp ) diff --git a/src/cmake/objc.cmake b/src/cmake/objc.cmake index 12a06bd1..aeb01d3b 100644 --- a/src/cmake/objc.cmake +++ b/src/cmake/objc.cmake @@ -88,6 +88,7 @@ set(objc_nntp_files objc/nntp/MCONNTPListNewsgroupsOperation.mm objc/nntp/MCONNTPFetchOverviewOperation.mm objc/nntp/MCONNTPFetchServerTimeOperation.mm + objc/nntp/MCONNTPPostOperation.mm objc/nntp/MCONNTPOperation.mm objc/nntp/MCONNTPSession.mm ) diff --git a/src/cmake/public-headers.cmake b/src/cmake/public-headers.cmake index db0ebd71..bcbdb0b6 100644 --- a/src/cmake/public-headers.cmake +++ b/src/cmake/public-headers.cmake @@ -118,6 +118,7 @@ async/nntp/MCNNTPFetchAllArticlesOperation.h async/nntp/MCNNTPListNewsgroupsOperation.h async/nntp/MCNNTPFetchOverviewOperation.h async/nntp/MCNNTPFetchServerTimeOperation.h +async/nntp/MCNNTPPostOperation.h async/nntp/MCNNTPOperationCallback.h objc/MCObjC.h objc/utils/MCOUtils.h @@ -201,6 +202,7 @@ objc/nntp/MCONNTPFetchAllArticlesOperation.h objc/nntp/MCONNTPListNewsgroupsOperation.h objc/nntp/MCONNTPFetchOverviewOperation.h objc/nntp/MCONNTPFetchServerTimeOperation.h +objc/nntp/MCONNTPPostOperation.h objc/nntp/MCONNTPGroupInfo.h objc/provider/MCOProvider.h objc/provider/MCONetService.h diff --git a/src/core/nntp/MCNNTPSession.cpp b/src/core/nntp/MCNNTPSession.cpp index 933f10f2..e5004432 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::postMessage(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::postMessage(String * messagePath, NNTPProgressCallback * callback, ErrorCode * pError) +{ + Data * messageData = Data::dataWithContentsOfFile(messagePath); + if (!messageData) { + * pError = ErrorFile; + return; + } + + return postMessage(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..22734f2d 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 postMessage(Data * messageData, NNTPProgressCallback * callback, ErrorCode * pError); + virtual void postMessage(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..62442c2a 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/MCONNTPPostOperation.h> #include <MailCore/MCONNTPGroupInfo.h> #endif diff --git a/src/objc/nntp/MCONNTPFetchArticleOperation.h b/src/objc/nntp/MCONNTPFetchArticleOperation.h index 170f594b..78a974f4 100644 --- a/src/objc/nntp/MCONNTPFetchArticleOperation.h +++ b/src/objc/nntp/MCONNTPFetchArticleOperation.h @@ -13,10 +13,6 @@ #import <Foundation/Foundation.h> #import <MailCore/MCONNTPOperation.h> -/** Fetch a message from NNTP3 */ - -typedef void (^MCONNTPOperationProgressBlock)(unsigned int current, unsigned int maximum); - NS_ASSUME_NONNULL_BEGIN @interface MCONNTPFetchArticleOperation : MCONNTPOperation diff --git a/src/objc/nntp/MCONNTPOperation.h b/src/objc/nntp/MCONNTPOperation.h index bed8874e..0c35970f 100644 --- a/src/objc/nntp/MCONNTPOperation.h +++ b/src/objc/nntp/MCONNTPOperation.h @@ -13,6 +13,10 @@ #import <Foundation/Foundation.h> #import <MailCore/MCOOperation.h> +/** Transmit a message using NNTP3 */ + +typedef void (^MCONNTPOperationProgressBlock)(unsigned int current, unsigned int maximum); + /** This is a generic asynchronous NNTP3 operation. @see MCONNTPSession diff --git a/src/objc/nntp/MCONNTPPostOperation.h b/src/objc/nntp/MCONNTPPostOperation.h new file mode 100644 index 00000000..a2447e70 --- /dev/null +++ b/src/objc/nntp/MCONNTPPostOperation.h @@ -0,0 +1,37 @@ +// +// MCONNTPPostOperation.h +// mailcore2 +// +// Created by Daryle Walker on 2/21/16. +// Copyright © 2016 MailCore. All rights reserved. +// + +#ifndef MAILCORE_MCONNTPPOSTOPERATION_H + +#define MAILCORE_MCONNTPPOSTOPERATION_H + +#import <Foundation/Foundation.h> +#import <MailCore/MCONNTPOperation.h> + +NS_ASSUME_NONNULL_BEGIN +@interface MCONNTPPostOperation : 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/MCONNTPPostOperation.mm b/src/objc/nntp/MCONNTPPostOperation.mm new file mode 100644 index 00000000..f5009afa --- /dev/null +++ b/src/objc/nntp/MCONNTPPostOperation.mm @@ -0,0 +1,116 @@ +// +// MCONNTPPostOperation.mm +// mailcore2 +// +// Created by Daryle Walker on 2/21/16. +// Copyright © 2016 MailCore. All rights reserved. +// + +#import "MCONNTPPostOperation.h" + +#import "MCAsyncNNTP.h" + +#import "MCOUtils.h" +#import "MCOOperation+Private.h" + +#define nativeType mailcore::NNTPPostOperation + +typedef void (^CompletionType)(NSError *error); + +@interface MCONNTPPostOperation () + +- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum; + +@end + +class MCONNTPPostOperationCallback : public mailcore::NNTPOperationCallback { +public: + MCONNTPPostOperationCallback(MCONNTPPostOperation * op) + { + mOperation = op; + } + virtual ~MCONNTPPostOperationCallback() + { + } + + virtual void bodyProgress(mailcore::NNTPOperation * session, unsigned int current, unsigned int maximum) { + [mOperation bodyProgress:current maximum:maximum]; + } + +private: + MCONNTPPostOperation * mOperation; +}; + +@implementation MCONNTPPostOperation { + CompletionType _completionBlock; + MCONNTPPostOperationCallback * _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 MCONNTPPostOperationCallback(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..19fe5ff4 100644 --- a/src/objc/nntp/MCONNTPSession.h +++ b/src/objc/nntp/MCONNTPSession.h @@ -20,6 +20,7 @@ @class MCONNTPListNewsgroupsOperation; @class MCONNTPFetchOverviewOperation; @class MCONNTPFetchServerTimeOperation; +@class MCONNTPPostOperation; @class MCONNTPOperation; @class MCOIndexSet; @@ -182,6 +183,32 @@ NS_ASSUME_NONNULL_BEGIN - (MCONNTPListNewsgroupsOperation *) listDefaultNewsgroupsOperation; /** + Returns an operation that will post 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 postOperationWithData:rfc822Data]; + [op start:^(NSError * __nullable error) { + ... + }]; + */ +- (MCONNTPPostOperation *) postOperationWithData:(NSData *)messageData; + +/** + Returns an operation that will post 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 postOperationWithContentsOfFile:rfc822DataFilename]; + [op start:^(NSError * __nullable error) { + ... + }]; + */ +- (MCONNTPPostOperation *) postOperationWithContentsOfFile:(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..f873cff9 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 "MCONNTPPostOperation.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); } +- (MCONNTPPostOperation *) postOperationWithData:(NSData *)messageData { + mailcore::NNTPPostOperation * coreOp = MCO_NATIVE_INSTANCE->postMessageOperation(MCO_FROM_OBJC(mailcore::Data, messageData)); + return MCO_TO_OBJC_OP(coreOp); +} + +- (MCONNTPPostOperation *) postOperationWithContentsOfFile:(NSString *)path +{ + mailcore::NNTPPostOperation * coreOp = MCO_NATIVE_INSTANCE->postMessageOperation(MCO_FROM_OBJC(mailcore::String, path)); + return MCO_TO_OBJC_OP(coreOp); +} + - (MCONNTPOperation *) disconnectOperation { mailcore::NNTPOperation * coreOp = MCO_NATIVE_INSTANCE->disconnectOperation(); |