diff options
72 files changed, 1568 insertions, 595 deletions
@@ -6,5 +6,6 @@ xcuserdata project.xcworkspace example/ios/iOS UI Test/DerivedData +scripts/prebuilt.list build/ diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index 0f932f5c..c1b46c92 100644 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -26,6 +26,8 @@ 9EF9AB23175F406D0027FA3B /* MCOIMAPFolderStatusOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9EF9AB16175F35C60027FA3B /* MCOIMAPFolderStatusOperation.h */; }; 9EF9AB24175F409D0027FA3B /* MCIMAPFolderStatusOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9EF9AB0E175F30C20027FA3B /* MCIMAPFolderStatusOperation.h */; }; 9EF9AB25175F40C70027FA3B /* MCIMAPFolderStatusOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9EF9AB0E175F30C20027FA3B /* MCIMAPFolderStatusOperation.h */; }; + BD63713B177DFF080094121B /* MCLibetpan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD637139177DFF080094121B /* MCLibetpan.cpp */; }; + BD63713C177DFF080094121B /* MCLibetpan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD637139177DFF080094121B /* MCLibetpan.cpp */; }; C07AD5D7FD82F8ACAB576231 /* NSError+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C07AD44B013BB42A240B4F04 /* NSError+MCO.h */; }; C07AD99B2E2054C684DB8FF6 /* NSError+MCO.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */; }; C07ADC28B83E7959BF114D46 /* MCOIMAPSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */; }; @@ -237,6 +239,10 @@ C668E2CC1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */; }; C668E2CD1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */; }; C668E2DD1736333900A2BB47 /* providers.json in Resources */ = {isa = PBXBuildFile; fileRef = 84AF9E7D172DBAF600E60AA3 /* providers.json */; }; + C68B2AEE1778A865005E61EF /* MCConnectionLogger.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */; }; + C68B2AEF1778A869005E61EF /* MCConnectionLogger.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */; }; + C68B2AF717797389005E61EF /* MCConnectionLoggerUtils.cc in Sources */ = {isa = PBXBuildFile; fileRef = C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */; }; + C68B2AF817797389005E61EF /* MCConnectionLoggerUtils.cc in Sources */ = {isa = PBXBuildFile; fileRef = C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */; }; C6A81B931706840C00882C15 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6A81B921706840C00882C15 /* UIKit.framework */; }; C6A81B941706840C00882C15 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C64EA78F169F259200778456 /* Foundation.framework */; }; C6A81B961706840C00882C15 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6A81B951706840C00882C15 /* CoreGraphics.framework */; }; @@ -709,6 +715,7 @@ C6CF62CD1753250E006398B9 /* MCOMailProvider.h in CopyFiles */, C6CF62CE17532510006398B9 /* MCOMailProvidersManager.h in CopyFiles */, C6CF62D017532521006398B9 /* MCOProvider.h in CopyFiles */, + C68B2AEE1778A865005E61EF /* MCConnectionLogger.h in CopyFiles */, C6CF62D117532527006398B9 /* MCMailProvider.h in CopyFiles */, C6CF62D417532531006398B9 /* MCProvider.h in CopyFiles */, C6CF62D31753252F006398B9 /* MCNetService.h in CopyFiles */, @@ -897,6 +904,7 @@ C6CF62D6175325BD006398B9 /* MCOMailProvidersManager.h in CopyFiles */, C6CF62D7175325BF006398B9 /* MCONetService.h in CopyFiles */, C6CF62D8175325C5006398B9 /* MCOProvider.h in CopyFiles */, + C68B2AEF1778A869005E61EF /* MCConnectionLogger.h in CopyFiles */, C6CF62D9175325CC006398B9 /* MCMailProvider.h in CopyFiles */, C6AC113517124D0A00B715B7 /* MCLibetpanTypes.h in CopyFiles */, C6BA2B0C1705F4E6003F0E9E /* MCHTMLRendererCallback.h in CopyFiles */, @@ -1073,6 +1081,8 @@ 9EF9AB10175F319A0027FA3B /* MCIMAPFolderStatusOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPFolderStatusOperation.cc; sourceTree = "<group>"; }; 9EF9AB16175F35C60027FA3B /* MCOIMAPFolderStatusOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPFolderStatusOperation.h; sourceTree = "<group>"; }; 9EF9AB18175F36600027FA3B /* MCOIMAPFolderStatusOperation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPFolderStatusOperation.mm; sourceTree = "<group>"; }; + BD637139177DFF080094121B /* MCLibetpan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCLibetpan.cpp; sourceTree = "<group>"; }; + BD63713A177DFF080094121B /* MCLibetpan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCLibetpan.h; sourceTree = "<group>"; }; C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPSession.mm; sourceTree = "<group>"; }; C07AD44B013BB42A240B4F04 /* NSError+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+MCO.h"; sourceTree = "<group>"; }; C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSError+MCO.mm"; sourceTree = "<group>"; }; @@ -1313,6 +1323,9 @@ C64FF39016B3C13000F8C162 /* MCOObjectWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOObjectWrapper.mm; sourceTree = "<group>"; }; C668E2C51735C8D500A2BB47 /* MCObjectMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCObjectMac.mm; sourceTree = "<group>"; }; C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCAutoreleasePoolMac.mm; sourceTree = "<group>"; }; + C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCConnectionLogger.h; sourceTree = "<group>"; }; + C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCConnectionLoggerUtils.cc; sourceTree = "<group>"; }; + C68B2AF617797389005E61EF /* MCConnectionLoggerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCConnectionLoggerUtils.h; sourceTree = "<group>"; }; C6A81B911706840C00882C15 /* test-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "test-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; C6A81B921706840C00882C15 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; C6A81B951706840C00882C15 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; @@ -1821,6 +1834,11 @@ C6AC1131171249DF00B715B7 /* MCLibetpanTypes.h */, C6D6F9691720F8F4006F5B28 /* MCICUTypes.h */, C6D6F96D1721028D006F5B28 /* MCIterator.h */, + C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */, + C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */, + C68B2AF617797389005E61EF /* MCConnectionLoggerUtils.h */, + BD637139177DFF080094121B /* MCLibetpan.cpp */, + BD63713A177DFF080094121B /* MCLibetpan.h */, ); path = basetypes; sourceTree = "<group>"; @@ -2345,6 +2363,7 @@ C64EA72F169E847800778456 /* MCIMAPPart.cc in Sources */, C64EA732169E847800778456 /* MCIMAPSearchExpression.cc in Sources */, C64EA734169E847800778456 /* MCIMAPSession.cc in Sources */, + C68B2AF717797389005E61EF /* MCConnectionLoggerUtils.cc in Sources */, C64EA737169E847800778456 /* MCPOPMessageInfo.cc in Sources */, C64EA73A169E847800778456 /* MCPOPSession.cc in Sources */, C64EA73C169E847800778456 /* MCAttachment.cc in Sources */, @@ -2467,6 +2486,7 @@ 9EF9AB11175F319A0027FA3B /* MCIMAPFolderStatusOperation.cc in Sources */, 9EF9AB19175F36600027FA3B /* MCOIMAPFolderStatusOperation.mm in Sources */, 9E774D891767C7F60065EB9B /* MCIMAPFolderStatus.cc in Sources */, + BD63713B177DFF080094121B /* MCLibetpan.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2525,6 +2545,7 @@ C6BA2BB41705F4E6003F0E9E /* MCIMAPPart.cc in Sources */, C6BA2BB51705F4E6003F0E9E /* MCIMAPSearchExpression.cc in Sources */, C6BA2BB61705F4E6003F0E9E /* MCIMAPSession.cc in Sources */, + C68B2AF817797389005E61EF /* MCConnectionLoggerUtils.cc in Sources */, C6BA2BB71705F4E6003F0E9E /* MCPOPMessageInfo.cc in Sources */, C6BA2BB81705F4E6003F0E9E /* MCPOPSession.cc in Sources */, C6BA2BB91705F4E6003F0E9E /* MCAttachment.cc in Sources */, @@ -2647,6 +2668,7 @@ 9EF9AB12175F319A0027FA3B /* MCIMAPFolderStatusOperation.cc in Sources */, 9EF9AB1A175F36600027FA3B /* MCOIMAPFolderStatusOperation.mm in Sources */, 9E774D8A1767C7F60065EB9B /* MCIMAPFolderStatus.cc in Sources */, + BD63713C177DFF080094121B /* MCLibetpan.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/scripts/get-prebuilt.sh b/scripts/get-prebuilt.sh index 75eccb45..8a44c659 100755 --- a/scripts/get-prebuilt.sh +++ b/scripts/get-prebuilt.sh @@ -1,18 +1,49 @@ #!/bin/sh +url="https://github.com/MailCore/mailcore2-deps" +url_prefix="$url/raw/master" + if test x$1 != xskipprebuilt ; then + file_timestamp=0 + if test -f prebuilt.list ; then + file_timestamp=`stat -f '%m' prebuilt.list` + fi + timestamp=`ruby -e 'puts Time.now.to_i'` + age=$((($timestamp-$file_timestamp)/3600)) # in hours if test ! -d ../Externals/prebuilt ; then - mkdir -p ../Externals/builds/builds - mkdir -p ../Externals/prebuilt - pushd ../Externals/prebuilt - if test -d mailcore2-deps ; then - cd mailcore2-deps - git pull --rebase - cd .. - else - git clone --depth=1 https://github.com/MailCore/mailcore2-deps.git + age=1 + fi + if test $age -gt 0 ; then + networkerror=no + #echo "$url_prefix/prebuilt.list" + curl -s -L "$url_prefix/prebuilt.list" > prebuilt.list.tmp + if test x$? != x0 ; then + networkerror=yes + fi + + if test x$networkerror = xyes ; then + echo WARNING: could not get prebuilt.list from repository + exit 1 + fi + + mv prebuilt.list.tmp prebuilt.list + + if test -f prebuilt.list ; then + files=`cat prebuilt.list` + mkdir -p ../Externals/builds/builds + mkdir -p ../Externals/prebuilt + pushd ../Externals/prebuilt + rm -rf .git + echo Getting prebuilt libraries... + if test -d mailcore2-deps ; then + cd mailcore2-deps + git pull --rebase + cd .. + else + git clone --depth 1 "$url" + fi + rsync --exclude=.git -av mailcore2-deps/ ../builds/builds/ + popd fi - cp mailcore2-deps/*.zip ../builds/builds - popd fi fi diff --git a/scripts/prepare-ctemplate-ios.sh b/scripts/prepare-ctemplate-ios.sh index 240dc5d9..caeb430c 100755 --- a/scripts/prepare-ctemplate-ios.sh +++ b/scripts/prepare-ctemplate-ios.sh @@ -42,6 +42,8 @@ if test -f "$resultdir/ctemplate-ios-$version.zip" ; then mkdir -p ../Externals/tmp unzip -q "$resultdir/ctemplate-ios-$version.zip" -d ../Externals/tmp mv "../Externals/tmp/ctemplate-ios-$version/ctemplate-ios" ../Externals + mkdir -p ../Externals/installed + ln -sf "$resultdir/ctemplate-ios-$version.zip" ../Externals/installed rm -rf ../Externals/tmp exit 0 fi diff --git a/scripts/prepare-ctemplate-macos.sh b/scripts/prepare-ctemplate-macos.sh index bea782f9..2e0fdd60 100755 --- a/scripts/prepare-ctemplate-macos.sh +++ b/scripts/prepare-ctemplate-macos.sh @@ -48,6 +48,8 @@ if test -f "$resultdir/ctemplate-$version.zip" ; then mkdir -p ../Externals/tmp unzip -q "$resultdir/ctemplate-$version.zip" -d ../Externals/tmp mv "../Externals/tmp/ctemplate-$version/ctemplate" ../Externals + mkdir -p ../Externals/installed + ln -sf "$resultdir/ctemplate-$version.zip" ../Externals/installed rm -rf ../Externals/tmp exit 0 fi diff --git a/scripts/prepare-icu4c-ios.sh b/scripts/prepare-icu4c-ios.sh index 9d50d985..5630c2e1 100755 --- a/scripts/prepare-icu4c-ios.sh +++ b/scripts/prepare-icu4c-ios.sh @@ -6,6 +6,7 @@ version='51_1' url="http://download.icu-project.org/files/icu4c/$versionfolder/icu4c-$version-src.tgz" package_filename="icu4c-$version-src.tgz" sysrootpath="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk" +enable_icu_data=0 pushd `dirname $0` > /dev/null scriptpath=`pwd` @@ -27,6 +28,8 @@ if test -f "$resultdir/icu4c-ios-$version.zip" ; then mkdir -p ../Externals/tmp unzip -q "$resultdir/icu4c-ios-$version.zip" -d ../Externals/tmp mv "../Externals/tmp/icu4c-ios-$version/icu4c-ios" ../Externals + mkdir -p ../Externals/installed + ln -sf "$resultdir/icu4c-ios-$version.zip" ../Externals/installed rm -rf ../Externals/tmp exit 0 fi @@ -113,8 +116,10 @@ done mkdir -p "$tmpdir/bin/icu4c-ios" cp -R $tmpdir/crossbuild/icu4c-x86_64/include "$tmpdir/bin/icu4c-ios" -mkdir -p "$tmpdir/bin/icu4c-ios/share/icu" -cp "$tmpdir/crossbuild/icu4c-x86_64/share/icu/$versionfolder/icudt51l.dat" "$tmpdir/bin/icu4c-ios/share/icu" +if test x$enable_icu_data = x1 ; then + mkdir -p "$tmpdir/bin/icu4c-ios/share/icu" + cp "$tmpdir/crossbuild/icu4c-x86_64/share/icu/$versionfolder/icudt51l.dat" "$tmpdir/bin/icu4c-ios/share/icu" +fi mkdir -p "$tmpdir/bin/icu4c-ios/lib" cd "$tmpdir/bin" diff --git a/scripts/prepare-icu4c-macos.sh b/scripts/prepare-icu4c-macos.sh index 903d2fa8..55806bc2 100755 --- a/scripts/prepare-icu4c-macos.sh +++ b/scripts/prepare-icu4c-macos.sh @@ -6,6 +6,7 @@ url="http://download.icu-project.org/files/icu4c/$versionfolder/icu4c-$version-s package_filename="icu4c-$version-src.tgz" arch="x86_64" sysrootpath="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk" +enable_icu_data=0 arch_flags="" for current_arch in $arch ; do @@ -32,6 +33,8 @@ if test -f "$resultdir/icu4c-$version.zip" ; then mkdir -p ../Externals/tmp unzip -q "$resultdir/icu4c-$version.zip" -d ../Externals/tmp mv "../Externals/tmp/icu4c-$version/icu4c" ../Externals + mkdir -p ../Externals/installed + ln -sf "$resultdir/icu4c-$version.zip" ../Externals/installed rm -rf ../Externals/tmp exit 0 fi @@ -88,8 +91,10 @@ done mkdir -p "$tmpdir/bin/icu4c" cp -R "$tmpdir/bin/icu4c-x86_64/include" "$tmpdir/bin/icu4c" -mkdir -p "$tmpdir/bin/icu4c/share/icu" -cp "$tmpdir/bin/icu4c-x86_64/share/icu/$versionfolder/icudt51l.dat" "$tmpdir/bin/icu4c/share/icu" +if test x$enable_icu_data = x1 ; then + mkdir -p "$tmpdir/bin/icu4c/share/icu" + cp "$tmpdir/bin/icu4c-x86_64/share/icu/$versionfolder/icudt51l.dat" "$tmpdir/bin/icu4c/share/icu" +fi mkdir -p "$tmpdir/bin/icu4c/lib" cd "$tmpdir/bin" diff --git a/scripts/prepare-ios.sh b/scripts/prepare-ios.sh index 44ccb2e0..49bac30e 100755 --- a/scripts/prepare-ios.sh +++ b/scripts/prepare-ios.sh @@ -1,15 +1,15 @@ #!/bin/sh ./get-prebuilt.sh -if test ! -d ../Externals/tidy-html5-ios ; then +missing=no +for filename in `cat prebuilt.list|grep -- -ios` ; do + if test ! -f "../Externals/installed/$filename" ; then + missing=yes + fi +done +if test $missing = yes ; then ./prepare-tidy-ios.sh -fi -if test ! -d ../Externals/icu4c-ios ; then ./prepare-icu4c-ios.sh -fi -if test ! -d ../Externals/libetpan-ios ; then ./prepare-libetpan-ios.sh -fi -if test ! -d ../Externals/ctemplate-ios ; then ./prepare-ctemplate-ios.sh fi diff --git a/scripts/prepare-libetpan-ios.sh b/scripts/prepare-libetpan-ios.sh index e7ed4928..7a5a054b 100755 --- a/scripts/prepare-libetpan-ios.sh +++ b/scripts/prepare-libetpan-ios.sh @@ -2,7 +2,7 @@ sdkversion=6.1 url="https://github.com/dinhviethoa/libetpan.git" -rev=349d184dcf2008ee7b5396743580e32b3bf65689 +rev=78427a0506be00e1e72ac8f88aa4b71bebd4137f pushd `dirname $0` > /dev/null scriptpath=`pwd` @@ -46,6 +46,9 @@ if test -f "$resultdir/libetpan-ios-$version.zip" ; then unzip -q "$resultdir/libsasl-ios-$version.zip" -d ../Externals/tmp mv "../Externals/tmp/libetpan-ios-$version/libetpan-ios" ../Externals mv "../Externals/tmp/libsasl-ios-$version/libsasl-ios" ../Externals + mkdir -p ../Externals/installed + ln -sf "$resultdir/libetpan-ios-$version.zip" ../Externals/installed + ln -sf "$resultdir/libsasl-ios-$version.zip" ../Externals/installed rm -rf ../Externals/tmp exit 0 fi diff --git a/scripts/prepare-libetpan-macos.sh b/scripts/prepare-libetpan-macos.sh index 3854ef22..81013fa6 100755 --- a/scripts/prepare-libetpan-macos.sh +++ b/scripts/prepare-libetpan-macos.sh @@ -1,7 +1,7 @@ #!/bin/sh url="https://github.com/dinhviethoa/libetpan.git" -rev=349d184dcf2008ee7b5396743580e32b3bf65689 +rev=78427a0506be00e1e72ac8f88aa4b71bebd4137f pushd `dirname $0` > /dev/null scriptpath=`pwd` @@ -42,6 +42,8 @@ if test -f "$resultdir/libetpan-$version.zip" ; then mkdir -p ../Externals/tmp unzip -q "$resultdir/libetpan-$version.zip" -d ../Externals/tmp mv "../Externals/tmp/libetpan-$version/libetpan" ../Externals + mkdir -p ../Externals/installed + ln -sf "$resultdir/libetpan-$version.zip" ../Externals/installed rm -rf ../Externals/tmp exit 0 fi diff --git a/scripts/prepare-mac.sh b/scripts/prepare-mac.sh index f29dfa04..2b9fdca8 100755 --- a/scripts/prepare-mac.sh +++ b/scripts/prepare-mac.sh @@ -1,13 +1,15 @@ #!/bin/sh ./get-prebuilt.sh -if test ! -d ../Externals/icu4c ; then +missing=no +for filename in `cat prebuilt.list|grep -v -- -ios` ; do + if test ! -f "../Externals/installed/$filename" ; then + missing=yes + fi +done +if test $missing = yes ; then ./prepare-icu4c-macos.sh -fi -if test ! -d ../Externals/libetpan ; then ./prepare-libetpan-macos.sh -fi -if test ! -d ../Externals/ctemplate ; then ./prepare-ctemplate-macos.sh fi diff --git a/scripts/prepare-tidy-ios.sh b/scripts/prepare-tidy-ios.sh index 55435e2b..53989950 100755 --- a/scripts/prepare-tidy-ios.sh +++ b/scripts/prepare-tidy-ios.sh @@ -41,6 +41,8 @@ if test -f "$resultdir/tidy-html5-ios-$version.zip" ; then mkdir -p ../Externals/tmp unzip -q "$resultdir/tidy-html5-ios-$version.zip" -d ../Externals/tmp mv "../Externals/tmp/tidy-html5-ios-$version/tidy-html5-ios" ../Externals + mkdir -p ../Externals/installed + ln -sf "$resultdir/tidy-html5-ios-$version.zip" ../Externals/installed rm -rf ../Externals/tmp exit 0 fi diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 2891d439..fc1935b7 100644 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -33,6 +33,7 @@ #include "MCOperationQueueCallback.h" #include "MCIMAPDisconnectOperation.h" #include "MCIMAPAsyncSession.h" +#include "MCConnectionLogger.h" using namespace mailcore; @@ -46,11 +47,11 @@ namespace mailcore { virtual ~IMAPOperationQueueCallback() { } - virtual void queueStartRunning() { + virtual void queueStartRunning(OperationQueue * queue) { mConnection->queueStartRunning(); } - virtual void queueStoppedRunning() { + virtual void queueStoppedRunning(OperationQueue * queue) { mConnection->tryAutomaticDisconnect(); mConnection->queueStoppedRunning(); } @@ -58,6 +59,24 @@ namespace mailcore { private: IMAPAsyncConnection * mConnection; }; + + class IMAPConnectionLogger : public Object, public ConnectionLogger { + public: + IMAPConnectionLogger(IMAPAsyncConnection * connection) { + mConnection = connection; + } + + virtual ~IMAPConnectionLogger() { + } + + virtual void log(void * context, void * sender, ConnectionLogType logType, Data * buffer) + { + mConnection->logConnection(logType, buffer); + } + + private: + IMAPAsyncConnection * mConnection; + }; } IMAPAsyncConnection::IMAPAsyncConnection() @@ -70,11 +89,16 @@ IMAPAsyncConnection::IMAPAsyncConnection() mQueueCallback = new IMAPOperationQueueCallback(this); mQueue->setCallback(mQueueCallback); mOwner = NULL; + mConnectionLogger = NULL; + pthread_mutex_init(&mConnectionLoggerLock, NULL); + mInternalLogger = new IMAPConnectionLogger(this); } IMAPAsyncConnection::~IMAPAsyncConnection() { cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL); + pthread_mutex_destroy(&mConnectionLoggerLock); + MC_SAFE_RELEASE(mInternalLogger); MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mLastFolder); MC_SAFE_RELEASE(mDefaultNamespace); @@ -122,6 +146,16 @@ String * IMAPAsyncConnection::password() return mSession->password(); } +void IMAPAsyncConnection::setOAuth2Token(String * token) +{ + mSession->setOAuth2Token(token); +} + +String * IMAPAsyncConnection::OAuth2Token() +{ + return mSession->OAuth2Token(); +} + void IMAPAsyncConnection::setAuthType(AuthType authType) { mSession->setAuthType(authType); @@ -526,4 +560,35 @@ IMAPAsyncSession * IMAPAsyncConnection::owner() return mOwner; } +void IMAPAsyncConnection::setConnectionLogger(ConnectionLogger * logger) +{ + pthread_mutex_lock(&mConnectionLoggerLock); + mConnectionLogger = logger; + if (mConnectionLogger != NULL) { + mSession->setConnectionLogger(mInternalLogger); + } + else { + mSession->setConnectionLogger(NULL); + } + pthread_mutex_unlock(&mConnectionLoggerLock); +} +ConnectionLogger * IMAPAsyncConnection::connectionLogger() +{ + ConnectionLogger * result; + + pthread_mutex_lock(&mConnectionLoggerLock); + result = mConnectionLogger; + pthread_mutex_unlock(&mConnectionLoggerLock); + + return result; +} + +void IMAPAsyncConnection::logConnection(ConnectionLogType logType, Data * buffer) +{ + pthread_mutex_lock(&mConnectionLoggerLock); + if (mConnectionLogger != NULL) { + mConnectionLogger->log(this, logType, buffer); + } + pthread_mutex_unlock(&mConnectionLoggerLock); +} diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index d6ef6a91..319cc224 100644 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -8,129 +8,139 @@ #ifdef __cplusplus namespace mailcore { - - class IMAPOperation; - class IMAPFetchFoldersOperation; - class IMAPAppendMessageOperation; - class IMAPCopyMessagesOperation; - class IMAPFetchMessagesOperation; - class IMAPFetchContentOperation; - class IMAPIdleOperation; - class IMAPFolderInfoOperation; - class IMAPFolderStatusOperation; - class IMAPSession; - class IMAPNamespace; - class IMAPSearchOperation; - class IMAPSearchExpression; - class IMAPFetchNamespaceOperation; - class IMAPIdentityOperation; - class IMAPCapabilityOperation; + + class IMAPOperation; + class IMAPFetchFoldersOperation; + class IMAPAppendMessageOperation; + class IMAPCopyMessagesOperation; + class IMAPFetchMessagesOperation; + class IMAPFetchContentOperation; + class IMAPIdleOperation; + class IMAPFolderInfoOperation; + class IMAPFolderStatusOperation; + class IMAPSession; + class IMAPNamespace; + class IMAPSearchOperation; + class IMAPSearchExpression; + class IMAPFetchNamespaceOperation; + class IMAPIdentityOperation; + class IMAPCapabilityOperation; class IMAPOperationQueueCallback; class IMAPAsyncSession; + class IMAPConnectionLogger; - class IMAPAsyncConnection : public Object { - public: - IMAPAsyncConnection(); - virtual ~IMAPAsyncConnection(); - - virtual void setHostname(String * hostname); - virtual String * hostname(); + class IMAPAsyncConnection : public Object { + public: + IMAPAsyncConnection(); + virtual ~IMAPAsyncConnection(); + + virtual void setHostname(String * hostname); + virtual String * hostname(); + + virtual void setPort(unsigned int port); + virtual unsigned int port(); + + virtual void setUsername(String * username); + virtual String * username(); + + virtual void setPassword(String * password); + virtual String * password(); - virtual void setPort(unsigned int port); - virtual unsigned int port(); + virtual void setOAuth2Token(String * token); + virtual String * OAuth2Token(); - virtual void setUsername(String * username); - virtual String * username(); + virtual void setAuthType(AuthType authType); + virtual AuthType authType(); - virtual void setPassword(String * password); - virtual String * password(); + virtual void setConnectionType(ConnectionType connectionType); + virtual ConnectionType connectionType(); - virtual void setAuthType(AuthType authType); - virtual AuthType authType(); + virtual void setTimeout(time_t timeout); + virtual time_t timeout(); - virtual void setConnectionType(ConnectionType connectionType); - virtual ConnectionType connectionType(); + virtual void setCheckCertificateEnabled(bool enabled); + virtual bool isCheckCertificateEnabled(); - virtual void setTimeout(time_t timeout); - virtual time_t timeout(); - - virtual void setCheckCertificateEnabled(bool enabled); - virtual bool isCheckCertificateEnabled(); + virtual void setVoIPEnabled(bool enabled); + virtual bool isVoIPEnabled(); - virtual void setVoIPEnabled(bool enabled); - virtual bool isVoIPEnabled(); + virtual void setDelimiter(char delimiter); + virtual char delimiter(); - virtual void setDelimiter(char delimiter); - virtual char delimiter(); + virtual void setDefaultNamespace(IMAPNamespace * ns); + virtual IMAPNamespace * defaultNamespace(); - virtual void setDefaultNamespace(IMAPNamespace * ns); - virtual IMAPNamespace * defaultNamespace(); + virtual void setConnectionLogger(ConnectionLogger * logger); + virtual ConnectionLogger * connectionLogger(); - virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder); + virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder); virtual IMAPFolderStatusOperation * folderStatusOperation(String * folder); - - virtual IMAPFetchFoldersOperation * fetchSubscribedFoldersOperation(); - virtual IMAPFetchFoldersOperation * fetchAllFoldersOperation(); - - virtual IMAPOperation * renameFolderOperation(String * folder, String * otherName); - virtual IMAPOperation * deleteFolderOperation(String * folder); - virtual IMAPOperation * createFolderOperation(String * folder); - - virtual IMAPOperation * subscribeFolderOperation(String * folder); - virtual IMAPOperation * unsubscribeFolderOperation(String * folder); - - virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags); - - virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder); - - virtual IMAPOperation * expungeOperation(String * folder); - - virtual IMAPFetchMessagesOperation * fetchMessagesByUIDOperation(String * folder, IMAPMessagesRequestKind requestKind, + + virtual IMAPFetchFoldersOperation * fetchSubscribedFoldersOperation(); + virtual IMAPFetchFoldersOperation * fetchAllFoldersOperation(); + + virtual IMAPOperation * renameFolderOperation(String * folder, String * otherName); + virtual IMAPOperation * deleteFolderOperation(String * folder); + virtual IMAPOperation * createFolderOperation(String * folder); + + virtual IMAPOperation * subscribeFolderOperation(String * folder); + virtual IMAPOperation * unsubscribeFolderOperation(String * folder); + + virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags); + + virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder); + + virtual IMAPOperation * expungeOperation(String * folder); + + virtual IMAPFetchMessagesOperation * fetchMessagesByUIDOperation(String * folder, IMAPMessagesRequestKind requestKind, IndexSet * uids); - virtual IMAPFetchMessagesOperation * fetchMessagesByNumberOperation(String * folder, IMAPMessagesRequestKind requestKind, + virtual IMAPFetchMessagesOperation * fetchMessagesByNumberOperation(String * folder, IMAPMessagesRequestKind requestKind, IndexSet * numbers); virtual IMAPFetchMessagesOperation * syncMessagesByUID(String * folder, IMAPMessagesRequestKind requestKind, IndexSet * uids, uint64_t modSeq); - virtual IMAPFetchContentOperation * fetchMessageByUIDOperation(String * folder, uint32_t uid); - virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, + virtual IMAPFetchContentOperation * fetchMessageByUIDOperation(String * folder, uint32_t uid); + virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding); - - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); - virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); - - virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); - virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchExpression * expression); - - virtual IMAPIdleOperation * idleOperation(String * folder, uint32_t lastKnownUID); - - virtual IMAPFetchNamespaceOperation * fetchNamespaceOperation(); - - virtual IMAPIdentityOperation * identityOperation(String * vendor, String * name, String * version); + + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); + virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); + + virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); + virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchExpression * expression); + + virtual IMAPIdleOperation * idleOperation(String * folder, uint32_t lastKnownUID); + + virtual IMAPFetchNamespaceOperation * fetchNamespaceOperation(); + + virtual IMAPIdentityOperation * identityOperation(String * vendor, String * name, String * version); virtual IMAPOperation * checkAccountOperation(); virtual IMAPCapabilityOperation * capabilityOperation(); private: - IMAPSession * mSession; - OperationQueue * mQueue; - char mDelimiter; - IMAPNamespace * mDefaultNamespace; - String * mLastFolder; + IMAPSession * mSession; + OperationQueue * mQueue; + char mDelimiter; + IMAPNamespace * mDefaultNamespace; + String * mLastFolder; IMAPOperationQueueCallback * mQueueCallback; - IMAPAsyncSession * mOwner; + IMAPAsyncSession * mOwner; + ConnectionLogger * mConnectionLogger; + IMAPConnectionLogger * mInternalLogger; + pthread_mutex_t mConnectionLoggerLock; virtual void tryAutomaticDisconnectAfterDelay(void * context); - + public: // private - virtual void runOperation(IMAPOperation * operation); - virtual IMAPSession * session(); + virtual void runOperation(IMAPOperation * operation); + virtual IMAPSession * session(); - virtual unsigned int operationsCount(); + virtual unsigned int operationsCount(); - virtual void setLastFolder(String * folder); - virtual String * lastFolder(); + virtual void setLastFolder(String * folder); + virtual String * lastFolder(); virtual void tryAutomaticDisconnect(); virtual void queueStartRunning(); @@ -138,6 +148,8 @@ namespace mailcore { virtual void setOwner(IMAPAsyncSession * owner); virtual IMAPAsyncSession * owner(); + + virtual void logConnection(ConnectionLogType logType, Data * buffer); }; } diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 7c085e4a..6981322e 100644 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -11,6 +11,7 @@ #include "MCIMAPAsyncConnection.h" #include "MCIMAPNamespace.h" #include "MCOperationQueueCallback.h" +#include "MCConnectionLogger.h" #define DEFAULT_MAX_CONNECTIONS 3 @@ -26,6 +27,7 @@ IMAPAsyncSession::IMAPAsyncSession() mPort = 0; mUsername = NULL; mPassword = NULL; + mOAuth2Token = NULL; mAuthType = AuthTypeSASLNone; mConnectionType = ConnectionTypeClear; mCheckCertificateEnabled = true; @@ -33,11 +35,17 @@ IMAPAsyncSession::IMAPAsyncSession() mDelimiter = 0; mDefaultNamespace = NULL; mTimeout = 30.; + mConnectionLogger = NULL; } IMAPAsyncSession::~IMAPAsyncSession() { MC_SAFE_RELEASE(mSessions); + MC_SAFE_RELEASE(mHostname); + MC_SAFE_RELEASE(mUsername); + MC_SAFE_RELEASE(mPassword); + MC_SAFE_RELEASE(mOAuth2Token); + MC_SAFE_RELEASE(mDefaultNamespace); } void IMAPAsyncSession::setHostname(String * hostname) @@ -80,6 +88,16 @@ String * IMAPAsyncSession::password() return mPassword; } +void IMAPAsyncSession::setOAuth2Token(String * token) +{ + MC_SAFE_REPLACE_COPY(String, mOAuth2Token, token); +} + +String * IMAPAsyncSession::OAuth2Token() +{ + return mOAuth2Token; +} + void IMAPAsyncSession::setAuthType(AuthType authType) { mAuthType = authType; @@ -174,6 +192,7 @@ unsigned int IMAPAsyncSession::maximumConnections() IMAPAsyncConnection * IMAPAsyncSession::session() { IMAPAsyncConnection * session = new IMAPAsyncConnection(); + session->setConnectionLogger(mConnectionLogger); session->setOwner(this); session->autorelease(); @@ -181,6 +200,7 @@ IMAPAsyncConnection * IMAPAsyncSession::session() session->setPort(mPort); session->setUsername(mUsername); session->setPassword(mPassword); + session->setOAuth2Token(mOAuth2Token); session->setAuthType(mAuthType); session->setConnectionType(mConnectionType); session->setTimeout(mTimeout); @@ -429,3 +449,16 @@ IMAPCapabilityOperation * IMAPAsyncSession::capabilityOperation() return session->capabilityOperation(); } +void IMAPAsyncSession::setConnectionLogger(ConnectionLogger * logger) +{ + mConnectionLogger = logger; + for(unsigned int i = 0 ; i < mSessions->count() ; i ++) { + IMAPAsyncConnection * currentSession = (IMAPAsyncConnection *) mSessions->objectAtIndex(i); + currentSession->setConnectionLogger(logger); + } +} + +ConnectionLogger * IMAPAsyncSession::connectionLogger() +{ + return mConnectionLogger; +} diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 390fdab8..ae1bbb90 100644 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -51,6 +51,11 @@ namespace mailcore { virtual void setPassword(String * password); virtual String * password(); + // To authenticate using OAuth2, username and oauth2token should be set. + // auth type to use is AuthTypeOAuth2. + virtual void setOAuth2Token(String * token); + virtual String * OAuth2Token(); + virtual void setAuthType(AuthType authType); virtual AuthType authType(); @@ -78,6 +83,9 @@ namespace mailcore { virtual void setMaximumConnections(unsigned int maxConnections); virtual unsigned int maximumConnections(); + virtual void setConnectionLogger(ConnectionLogger * logger); + virtual ConnectionLogger * connectionLogger(); + virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder); virtual IMAPFolderStatusOperation * folderStatusOperation(String * folder); @@ -124,7 +132,7 @@ namespace mailcore { virtual IMAPOperation * checkAccountOperation(); virtual IMAPCapabilityOperation * capabilityOperation(); - + private: Array * mSessions; @@ -132,6 +140,7 @@ namespace mailcore { unsigned int mPort; String * mUsername; String * mPassword; + String * mOAuth2Token; AuthType mAuthType; ConnectionType mConnectionType; bool mCheckCertificateEnabled; @@ -141,6 +150,7 @@ namespace mailcore { time_t mTimeout; bool mAllowsFolderConcurrentAccessEnabled; unsigned int mMaximumConnections; + ConnectionLogger * mConnectionLogger; virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false); virtual IMAPAsyncConnection * session(); diff --git a/src/async/imap/MCIMAPCheckAccountOperation.h b/src/async/imap/MCIMAPCheckAccountOperation.h index 78c95d52..2e3ddbd9 100644 --- a/src/async/imap/MCIMAPCheckAccountOperation.h +++ b/src/async/imap/MCIMAPCheckAccountOperation.h @@ -1,4 +1,4 @@ -// +x// // MCIMAPCheckAccountOperation.h // mailcore2 // diff --git a/src/async/pop/MCPOPAsyncSession.cc b/src/async/pop/MCPOPAsyncSession.cc index 1269a34b..342b0f5e 100644 --- a/src/async/pop/MCPOPAsyncSession.cc +++ b/src/async/pop/MCPOPAsyncSession.cc @@ -15,6 +15,7 @@ #include "MCPOPFetchMessagesOperation.h" #include "MCPOPCheckAccountOperation.h" #include "MCOperationQueueCallback.h" +#include "MCConnectionLogger.h" using namespace mailcore; @@ -28,17 +29,35 @@ namespace mailcore { virtual ~POPOperationQueueCallback() { } - virtual void queueStartRunning() { + virtual void queueStartRunning(OperationQueue * queue) { mSession->retain(); } - virtual void queueStoppedRunning() { + virtual void queueStoppedRunning(OperationQueue * queue) { mSession->release(); } private: POPAsyncSession * mSession; }; + + class POPConnectionLogger : public Object, public ConnectionLogger { + public: + POPConnectionLogger(POPAsyncSession * session) { + mSession = session; + } + + virtual ~POPConnectionLogger() { + } + + virtual void log(void * context, void * sender, ConnectionLogType logType, Data * buffer) + { + mSession->logConnection(logType, buffer); + } + + private: + POPAsyncSession * mSession; + }; } POPAsyncSession::POPAsyncSession() @@ -47,10 +66,16 @@ POPAsyncSession::POPAsyncSession() mQueue = new OperationQueue(); mQueueCallback = new POPOperationQueueCallback(this); mQueue->setCallback(mQueueCallback); + mConnectionLogger = NULL; + pthread_mutex_init(&mConnectionLoggerLock, NULL); + mInternalLogger = new POPConnectionLogger(this); + mSession->setConnectionLogger(mInternalLogger); } POPAsyncSession::~POPAsyncSession() { + MC_SAFE_RELEASE(mInternalLogger); + pthread_mutex_destroy(&mConnectionLoggerLock); MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mSession); MC_SAFE_RELEASE(mQueue); @@ -193,3 +218,36 @@ void POPAsyncSession::runOperation(POPOperation * operation) { mQueue->addOperation(operation); } + +void POPAsyncSession::setConnectionLogger(ConnectionLogger * logger) +{ + pthread_mutex_lock(&mConnectionLoggerLock); + mConnectionLogger = logger; + if (mConnectionLogger != NULL) { + mSession->setConnectionLogger(mInternalLogger); + } + else { + mSession->setConnectionLogger(NULL); + } + pthread_mutex_unlock(&mConnectionLoggerLock); +} + +ConnectionLogger * POPAsyncSession::connectionLogger() +{ + ConnectionLogger * result; + + pthread_mutex_lock(&mConnectionLoggerLock); + result = mConnectionLogger; + pthread_mutex_unlock(&mConnectionLoggerLock); + + return result; +} + +void POPAsyncSession::logConnection(ConnectionLogType logType, Data * buffer) +{ + pthread_mutex_lock(&mConnectionLoggerLock); + if (mConnectionLogger != NULL) { + mConnectionLogger->log(this, logType, buffer); + } + pthread_mutex_unlock(&mConnectionLoggerLock); +} diff --git a/src/async/pop/MCPOPAsyncSession.h b/src/async/pop/MCPOPAsyncSession.h index 452d4d75..0345ecd6 100644 --- a/src/async/pop/MCPOPAsyncSession.h +++ b/src/async/pop/MCPOPAsyncSession.h @@ -23,6 +23,7 @@ namespace mailcore { class POPDeleteMessagesOperation; class POPFetchMessagesOperation; class POPOperationQueueCallback; + class POPConnectionLogger; class POPAsyncSession : public Object { public: @@ -53,6 +54,9 @@ namespace mailcore { virtual void setCheckCertificateEnabled(bool enabled); virtual bool isCheckCertificateEnabled(); + virtual void setConnectionLogger(ConnectionLogger * logger); + virtual ConnectionLogger * connectionLogger(); + virtual POPFetchMessagesOperation * fetchMessagesOperation(); virtual POPFetchHeaderOperation * fetchHeaderOperation(unsigned int index); @@ -70,11 +74,14 @@ namespace mailcore { POPSession * mSession; OperationQueue * mQueue; POPOperationQueueCallback * mQueueCallback; + ConnectionLogger * mConnectionLogger; + pthread_mutex_t mConnectionLoggerLock; + POPConnectionLogger * mInternalLogger; public: // private virtual void runOperation(POPOperation * operation); virtual POPSession * session(); - + virtual void logConnection(ConnectionLogType logType, Data * buffer); }; } diff --git a/src/async/smtp/MCSMTPAsyncSession.cc b/src/async/smtp/MCSMTPAsyncSession.cc index 723c0330..fafc2e82 100644 --- a/src/async/smtp/MCSMTPAsyncSession.cc +++ b/src/async/smtp/MCSMTPAsyncSession.cc @@ -19,11 +19,11 @@ namespace mailcore { virtual ~SMTPOperationQueueCallback() { } - virtual void queueStartRunning() { + virtual void queueStartRunning(OperationQueue * queue) { mSession->retain(); } - virtual void queueStoppedRunning() { + virtual void queueStoppedRunning(OperationQueue * queue) { mSession->tryAutomaticDisconnect(); mSession->release(); } @@ -31,6 +31,24 @@ namespace mailcore { private: SMTPAsyncSession * mSession; }; + + class SMTPConnectionLogger : public Object, public ConnectionLogger { + public: + SMTPConnectionLogger(SMTPAsyncSession * session) { + mSession = session; + } + + virtual ~SMTPConnectionLogger() { + } + + virtual void log(void * context, void * sender, ConnectionLogType logType, Data * buffer) + { + mSession->logConnection(logType, buffer); + } + + private: + SMTPAsyncSession * mSession; + }; } SMTPAsyncSession::SMTPAsyncSession() @@ -39,10 +57,16 @@ SMTPAsyncSession::SMTPAsyncSession() mQueue = new OperationQueue(); mQueueCallback = new SMTPOperationQueueCallback(this); mQueue->setCallback(mQueueCallback); + mConnectionLogger = NULL; + pthread_mutex_init(&mConnectionLoggerLock, NULL); + mInternalLogger = new SMTPConnectionLogger(this); + mSession->setConnectionLogger(mInternalLogger); } SMTPAsyncSession::~SMTPAsyncSession() { + MC_SAFE_RELEASE(mInternalLogger); + pthread_mutex_destroy(&mConnectionLoggerLock); cancelDelayedPerformMethod((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL); MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mQueue); @@ -184,3 +208,36 @@ SMTPOperation * SMTPAsyncSession::checkAccountOperation(Address * from) op->setSession(this); return (SMTPOperation *) op->autorelease(); } + +void SMTPAsyncSession::setConnectionLogger(ConnectionLogger * logger) +{ + pthread_mutex_lock(&mConnectionLoggerLock); + mConnectionLogger = logger; + if (mConnectionLogger != NULL) { + mSession->setConnectionLogger(mInternalLogger); + } + else { + mSession->setConnectionLogger(NULL); + } + pthread_mutex_unlock(&mConnectionLoggerLock); +} + +ConnectionLogger * SMTPAsyncSession::connectionLogger() +{ + ConnectionLogger * result; + + pthread_mutex_lock(&mConnectionLoggerLock); + result = mConnectionLogger; + pthread_mutex_unlock(&mConnectionLoggerLock); + + return result; +} + +void SMTPAsyncSession::logConnection(ConnectionLogType logType, Data * buffer) +{ + pthread_mutex_lock(&mConnectionLoggerLock); + if (mConnectionLogger != NULL) { + mConnectionLogger->log(this, logType, buffer); + } + pthread_mutex_unlock(&mConnectionLoggerLock); +} diff --git a/src/async/smtp/MCSMTPAsyncSession.h b/src/async/smtp/MCSMTPAsyncSession.h index 9cd7a8f0..9fa6dbdf 100644 --- a/src/async/smtp/MCSMTPAsyncSession.h +++ b/src/async/smtp/MCSMTPAsyncSession.h @@ -14,6 +14,7 @@ namespace mailcore { class SMTPSession; class Address; class SMTPOperationQueueCallback; + class SMTPConnectionLogger; class SMTPAsyncSession : public Object { public: @@ -47,6 +48,9 @@ namespace mailcore { virtual void setUseHeloIPEnabled(bool enabled); virtual bool useHeloIPEnabled(); + virtual void setConnectionLogger(ConnectionLogger * logger); + virtual ConnectionLogger * connectionLogger(); + virtual SMTPOperation * sendMessageOperation(Data * messageData); virtual SMTPOperation * checkAccountOperation(Address * from); @@ -54,11 +58,15 @@ namespace mailcore { virtual void runOperation(SMTPOperation * operation); virtual SMTPSession * session(); virtual void tryAutomaticDisconnect(); - + virtual void logConnection(ConnectionLogType logType, Data * buffer); + private: SMTPSession * mSession; OperationQueue * mQueue; SMTPOperationQueueCallback * mQueueCallback; + ConnectionLogger * mConnectionLogger; + pthread_mutex_t mConnectionLoggerLock; + SMTPConnectionLogger * mInternalLogger; virtual void tryAutomaticDisconnectAfterDelay(void * context); }; diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index 417bdb6c..9e1b46b7 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -4,214 +4,215 @@ #ifdef __cplusplus namespace mailcore { - - enum ConnectionType { - ConnectionTypeClear = 1 << 0, - ConnectionTypeStartTLS = 1 << 1, - ConnectionTypeTLS = 1 << 2, - }; + + enum ConnectionType { + ConnectionTypeClear = 1 << 0, + ConnectionTypeStartTLS = 1 << 1, + ConnectionTypeTLS = 1 << 2, + }; - enum AuthType { - AuthTypeSASLNone = 0, - AuthTypeSASLCRAMMD5 = 1 << 0, - AuthTypeSASLPlain = 1 << 1, - AuthTypeSASLGSSAPI = 1 << 2, - AuthTypeSASLDIGESTMD5 = 1 << 3, - AuthTypeSASLLogin = 1 << 4, - AuthTypeSASLSRP = 1 << 5, - AuthTypeSASLNTLM = 1 << 6, - AuthTypeSASLKerberosV4 = 1 << 7, - }; + enum AuthType { + AuthTypeSASLNone = 0, + AuthTypeSASLCRAMMD5 = 1 << 0, + AuthTypeSASLPlain = 1 << 1, + AuthTypeSASLGSSAPI = 1 << 2, + AuthTypeSASLDIGESTMD5 = 1 << 3, + AuthTypeSASLLogin = 1 << 4, + AuthTypeSASLSRP = 1 << 5, + AuthTypeSASLNTLM = 1 << 6, + AuthTypeSASLKerberosV4 = 1 << 7, + AuthTypeXOAuth2 = 1 << 8, + }; - enum IMAPFolderFlag { - IMAPFolderFlagNone = 0, - IMAPFolderFlagMarked = 1 << 0, - IMAPFolderFlagUnmarked = 1 << 1, - IMAPFolderFlagNoSelect = 1 << 2, - IMAPFolderFlagNoInferiors = 1 << 3, - IMAPFolderFlagInbox = 1 << 4, - IMAPFolderFlagSentMail = 1 << 5, - IMAPFolderFlagStarred = 1 << 6, - IMAPFolderFlagAllMail = 1 << 7, - IMAPFolderFlagTrash = 1 << 8, - IMAPFolderFlagDrafts = 1 << 9, - IMAPFolderFlagSpam = 1 << 10, - IMAPFolderFlagImportant = 1 << 11, - IMAPFolderFlagArchive = 1 << 12, + enum IMAPFolderFlag { + IMAPFolderFlagNone = 0, + IMAPFolderFlagMarked = 1 << 0, + IMAPFolderFlagUnmarked = 1 << 1, + IMAPFolderFlagNoSelect = 1 << 2, + IMAPFolderFlagNoInferiors = 1 << 3, + IMAPFolderFlagInbox = 1 << 4, + IMAPFolderFlagSentMail = 1 << 5, + IMAPFolderFlagStarred = 1 << 6, + IMAPFolderFlagAllMail = 1 << 7, + IMAPFolderFlagTrash = 1 << 8, + IMAPFolderFlagDrafts = 1 << 9, + IMAPFolderFlagSpam = 1 << 10, + IMAPFolderFlagImportant = 1 << 11, + IMAPFolderFlagArchive = 1 << 12, IMAPFolderFlagAll = IMAPFolderFlagAllMail, IMAPFolderFlagJunk = IMAPFolderFlagSpam, IMAPFolderFlagFlagged = IMAPFolderFlagStarred, - }; + }; - enum MessageFlag { - MessageFlagNone = 0, - MessageFlagSeen = 1 << 0, - MessageFlagAnswered = 1 << 1, - MessageFlagFlagged = 1 << 2, - MessageFlagDeleted = 1 << 3, - MessageFlagDraft = 1 << 4, - MessageFlagMDNSent = 1 << 5, - MessageFlagForwarded = 1 << 6, - MessageFlagSubmitPending = 1 << 7, - MessageFlagSubmitted = 1 << 8, - } ; + enum MessageFlag { + MessageFlagNone = 0, + MessageFlagSeen = 1 << 0, + MessageFlagAnswered = 1 << 1, + MessageFlagFlagged = 1 << 2, + MessageFlagDeleted = 1 << 3, + MessageFlagDraft = 1 << 4, + MessageFlagMDNSent = 1 << 5, + MessageFlagForwarded = 1 << 6, + MessageFlagSubmitPending = 1 << 7, + MessageFlagSubmitted = 1 << 8, + } ; - enum IMAPMessagesRequestKind { - IMAPMessagesRequestKindUid = 0, // This is the default and it's always fetched - IMAPMessagesRequestKindFlags = 1 << 0, - IMAPMessagesRequestKindHeaders = 1 << 1, - IMAPMessagesRequestKindStructure = 1 << 2, - IMAPMessagesRequestKindInternalDate = 1 << 3, - IMAPMessagesRequestKindFullHeaders = 1 << 4, - IMAPMessagesRequestKindHeaderSubject = 1 << 5, - IMAPMessagesRequestKindGmailLabels = 1 << 6, - IMAPMessagesRequestKindGmailMessageID = 1 << 7, - IMAPMessagesRequestKindGmailThreadID = 1 << 8, - }; + enum IMAPMessagesRequestKind { + IMAPMessagesRequestKindUid = 0, // This is the default and it's always fetched + IMAPMessagesRequestKindFlags = 1 << 0, + IMAPMessagesRequestKindHeaders = 1 << 1, + IMAPMessagesRequestKindStructure = 1 << 2, + IMAPMessagesRequestKindInternalDate = 1 << 3, + IMAPMessagesRequestKindFullHeaders = 1 << 4, + IMAPMessagesRequestKindHeaderSubject = 1 << 5, + IMAPMessagesRequestKindGmailLabels = 1 << 6, + IMAPMessagesRequestKindGmailMessageID = 1 << 7, + IMAPMessagesRequestKindGmailThreadID = 1 << 8, + }; - enum IMAPFetchRequestType { - IMAPFetchRequestTypeUID = 0, - IMAPFetchRequestTypeSequence = 1 - }; + enum IMAPFetchRequestType { + IMAPFetchRequestTypeUID = 0, + IMAPFetchRequestTypeSequence = 1 + }; - enum IMAPStoreFlagsRequestKind { - IMAPStoreFlagsRequestKindAdd, - IMAPStoreFlagsRequestKindRemove, - IMAPStoreFlagsRequestKindSet, - }; + enum IMAPStoreFlagsRequestKind { + IMAPStoreFlagsRequestKindAdd, + IMAPStoreFlagsRequestKindRemove, + IMAPStoreFlagsRequestKindSet, + }; - enum IMAPWorkaround { - IMAPWorkaroundGmail = 1 << 0, - IMAPWorkaroundYahoo = 1 << 1, - IMAPWorkaroundExchange2003 = 1 << 2, - }; + enum IMAPWorkaround { + IMAPWorkaroundGmail = 1 << 0, + IMAPWorkaroundYahoo = 1 << 1, + IMAPWorkaroundExchange2003 = 1 << 2, + }; - enum IMAPCapability { - IMAPCapabilityACL, - IMAPCapabilityBinary, - IMAPCapabilityCatenate, - IMAPCapabilityChildren, - IMAPCapabilityCompressDeflate, - IMAPCapabilityCondstore, - IMAPCapabilityEnable, - IMAPCapabilityIdle, - IMAPCapabilityId, - IMAPCapabilityLiteralPlus, - IMAPCapabilityMultiAppend, - IMAPCapabilityNamespace, - IMAPCapabilityQResync, - IMAPCapabilityQuota, - IMAPCapabilitySort, - IMAPCapabilityStartTLS, - IMAPCapabilityThreadOrderedSubject, - IMAPCapabilityThreadReferences, - IMAPCapabilityUIDPlus, - IMAPCapabilityUnselect, - IMAPCapabilityXList, - IMAPCapabilityAuthAnonymous, - IMAPCapabilityAuthCRAMMD5, - IMAPCapabilityAuthDigestMD5, - IMAPCapabilityAuthExternal, - IMAPCapabilityAuthGSSAPI, - IMAPCapabilityAuthKerberosV4, - IMAPCapabilityAuthLogin, - IMAPCapabilityAuthNTLM, - IMAPCapabilityAuthOTP, - IMAPCapabilityAuthPlain, - IMAPCapabilityAuthSKey, - IMAPCapabilityAuthSRP, - }; + enum IMAPCapability { + IMAPCapabilityACL, + IMAPCapabilityBinary, + IMAPCapabilityCatenate, + IMAPCapabilityChildren, + IMAPCapabilityCompressDeflate, + IMAPCapabilityCondstore, + IMAPCapabilityEnable, + IMAPCapabilityIdle, + IMAPCapabilityId, + IMAPCapabilityLiteralPlus, + IMAPCapabilityMultiAppend, + IMAPCapabilityNamespace, + IMAPCapabilityQResync, + IMAPCapabilityQuota, + IMAPCapabilitySort, + IMAPCapabilityStartTLS, + IMAPCapabilityThreadOrderedSubject, + IMAPCapabilityThreadReferences, + IMAPCapabilityUIDPlus, + IMAPCapabilityUnselect, + IMAPCapabilityXList, + IMAPCapabilityAuthAnonymous, + IMAPCapabilityAuthCRAMMD5, + IMAPCapabilityAuthDigestMD5, + IMAPCapabilityAuthExternal, + IMAPCapabilityAuthGSSAPI, + IMAPCapabilityAuthKerberosV4, + IMAPCapabilityAuthLogin, + IMAPCapabilityAuthNTLM, + IMAPCapabilityAuthOTP, + IMAPCapabilityAuthPlain, + IMAPCapabilityAuthSKey, + IMAPCapabilityAuthSRP, + }; - enum POPCapability { - POPCapabilityNone, - POPCapabilityStartTLS, - POPCapabilityTop, - POPCapabilityUser, - POPCapabilityRespCodes, - POPCapabilityPipelining, - POPCapabilityUIDL, - POPCapabilitySASL, - POPCapabilityAuthAnonymous, - POPCapabilityAuthCRAMMD5, - POPCapabilityAuthDigestMD5, - POPCapabilityAuthExternal, - POPCapabilityAuthGSSAPI, - POPCapabilityAuthKerberosV4, - POPCapabilityAuthLogin, - POPCapabilityAuthNTLM, - POPCapabilityAuthOTP, - POPCapabilityAuthPlain, - POPCapabilityAuthSKey, - POPCapabilityAuthSRP, - }; + enum POPCapability { + POPCapabilityNone, + POPCapabilityStartTLS, + POPCapabilityTop, + POPCapabilityUser, + POPCapabilityRespCodes, + POPCapabilityPipelining, + POPCapabilityUIDL, + POPCapabilitySASL, + POPCapabilityAuthAnonymous, + POPCapabilityAuthCRAMMD5, + POPCapabilityAuthDigestMD5, + POPCapabilityAuthExternal, + POPCapabilityAuthGSSAPI, + POPCapabilityAuthKerberosV4, + POPCapabilityAuthLogin, + POPCapabilityAuthNTLM, + POPCapabilityAuthOTP, + POPCapabilityAuthPlain, + POPCapabilityAuthSKey, + POPCapabilityAuthSRP, + }; - enum Encoding { - Encoding7Bit = 0, // should match MAILIMAP_BODY_FLD_ENC_7BIT - Encoding8Bit = 1, // should match MAILIMAP_BODY_FLD_ENC_8BIT - EncodingBinary = 2, // should match MAILIMAP_BODY_FLD_ENC_BINARY - EncodingBase64 = 3, // should match MAILIMAP_BODY_FLD_ENC_BASE64 - EncodingQuotedPrintable = 4, // should match MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE - EncodingOther = 5, // should match MAILIMAP_BODY_FLD_ENC_OTHER - // negative values should be used for other encoding - EncodingUUEncode = -1 - }; - - enum IMAPSearchKind { - IMAPSearchKindNone, - IMAPSearchKindFrom, - IMAPSearchKindRecipient, - IMAPSearchKindSubject, - IMAPSearchKindContent, - IMAPSearchKindHeader, - IMAPSearchKindOr, - IMAPSearchKindAnd, - }; - - enum ErrorCode { - ErrorNone, - ErrorConnection, - ErrorTLSNotAvailable, - ErrorParse, - ErrorCertificate, - ErrorAuthentication, - ErrorGmailIMAPNotEnabled, - ErrorGmailExceededBandwidthLimit, - ErrorGmailTooManySimultaneousConnections, - ErrorMobileMeMoved, - ErrorYahooUnavailable, - ErrorNonExistantFolder, - ErrorRename, - ErrorDelete, - ErrorCreate, - ErrorSubscribe, - ErrorAppend, - ErrorCopy, - ErrorExpunge, - ErrorFetch, - ErrorIdle, - ErrorIdentity, - ErrorNamespace, - ErrorStore, + enum Encoding { + Encoding7Bit = 0, // should match MAILIMAP_BODY_FLD_ENC_7BIT + Encoding8Bit = 1, // should match MAILIMAP_BODY_FLD_ENC_8BIT + EncodingBinary = 2, // should match MAILIMAP_BODY_FLD_ENC_BINARY + EncodingBase64 = 3, // should match MAILIMAP_BODY_FLD_ENC_BASE64 + EncodingQuotedPrintable = 4, // should match MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE + EncodingOther = 5, // should match MAILIMAP_BODY_FLD_ENC_OTHER + // negative values should be used for other encoding + EncodingUUEncode = -1 + }; + + enum IMAPSearchKind { + IMAPSearchKindNone, + IMAPSearchKindFrom, + IMAPSearchKindRecipient, + IMAPSearchKindSubject, + IMAPSearchKindContent, + IMAPSearchKindHeader, + IMAPSearchKindOr, + IMAPSearchKindAnd, + }; + + enum ErrorCode { + ErrorNone, + ErrorConnection, + ErrorTLSNotAvailable, + ErrorParse, + ErrorCertificate, + ErrorAuthentication, + ErrorGmailIMAPNotEnabled, + ErrorGmailExceededBandwidthLimit, + ErrorGmailTooManySimultaneousConnections, + ErrorMobileMeMoved, + ErrorYahooUnavailable, + ErrorNonExistantFolder, + ErrorRename, + ErrorDelete, + ErrorCreate, + ErrorSubscribe, + ErrorAppend, + ErrorCopy, + ErrorExpunge, + ErrorFetch, + ErrorIdle, + ErrorIdentity, + ErrorNamespace, + ErrorStore, ErrorCapability, - ErrorStartTLSNotAvailable, - ErrorSendMessageIllegalAttachment, - ErrorStorageLimit, - ErrorSendMessageNotAllowed, - ErrorNeedsConnectToWebmail, - ErrorSendMessage, - ErrorAuthenticationRequired, - ErrorFetchMessageList, - ErrorDeleteMessage, + ErrorStartTLSNotAvailable, + ErrorSendMessageIllegalAttachment, + ErrorStorageLimit, + ErrorSendMessageNotAllowed, + ErrorNeedsConnectToWebmail, + ErrorSendMessage, + ErrorAuthenticationRequired, + ErrorFetchMessageList, + ErrorDeleteMessage, ErrorInvalidAccount, - }; - - enum PartType { - PartTypeSingle, - PartTypeMessage, - PartTypeMultipartMixed, - PartTypeMultipartRelated, - PartTypeMultipartAlternative, - }; + }; + + enum PartType { + PartTypeSingle, + PartTypeMessage, + PartTypeMultipartMixed, + PartTypeMultipartRelated, + PartTypeMultipartAlternative, + }; } #endif diff --git a/src/core/basetypes/MCBaseTypes.h b/src/core/basetypes/MCBaseTypes.h index 4919e1f5..96fa23fd 100644 --- a/src/core/basetypes/MCBaseTypes.h +++ b/src/core/basetypes/MCBaseTypes.h @@ -25,5 +25,6 @@ #include <MailCore/MCLibetpanTypes.h> #include <MailCore/MCICUTypes.h> #include <MailCore/MCIterator.h> +#include <MailCore/MCConnectionLogger.h> #endif diff --git a/src/core/basetypes/MCConnectionLogger.h b/src/core/basetypes/MCConnectionLogger.h new file mode 100644 index 00000000..dd596857 --- /dev/null +++ b/src/core/basetypes/MCConnectionLogger.h @@ -0,0 +1,45 @@ +// +// MCConnectionLogger.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/24/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_CONNECTION_LOGGER_H_ +#define __MAILCORE_CONNECTION_LOGGER_H_ + +#include <stdlib.h> + +#ifdef __cplusplus + +namespace mailcore { + + class Data; + class String; + + enum ConnectionLogType { + // Received data + ConnectionLogTypeReceived, + // Sent data + ConnectionLogTypeSent, + // Sent private data + ConnectionLogTypeSentPrivate, + // Parse error + ConnectionLogTypeErrorParse, + // Error while receiving data - log() is called with a NULL buffer. + ConnectionLogTypeErrorReceived, + // Error while sending data - log() is called with a NULL buffer. + ConnectionLogTypeErrorSent, + }; + + class ConnectionLogger { + public: + virtual void log(void * sender, ConnectionLogType logType, Data * buffer) {} + }; + +} + +#endif + +#endif diff --git a/src/core/basetypes/MCConnectionLoggerUtils.cc b/src/core/basetypes/MCConnectionLoggerUtils.cc new file mode 100644 index 00000000..234713e7 --- /dev/null +++ b/src/core/basetypes/MCConnectionLoggerUtils.cc @@ -0,0 +1,62 @@ +// +// MCConnectionLoggerUtils.cc +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/24/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#include "MCConnectionLoggerUtils.h" + +#include <libetpan/libetpan.h> + +#include "MCConnectionLogger.h" + +mailcore::ConnectionLogType mailcore::getConnectionType(int log_type) +{ + ConnectionLogType type = (ConnectionLogType) -1; + bool isBuffer = false; + + switch (log_type) { + case MAILSTREAM_LOG_TYPE_ERROR_PARSE: + type = ConnectionLogTypeErrorParse; + isBuffer = true; + break; + case MAILSTREAM_LOG_TYPE_ERROR_RECEIVED: + type = ConnectionLogTypeErrorReceived; + isBuffer = true; + break; + case MAILSTREAM_LOG_TYPE_ERROR_SENT: + type = ConnectionLogTypeErrorSent; + isBuffer = true; + break; + case MAILSTREAM_LOG_TYPE_DATA_RECEIVED: + type = ConnectionLogTypeReceived; + isBuffer = true; + break; + case MAILSTREAM_LOG_TYPE_DATA_SENT: + type = ConnectionLogTypeSent; + isBuffer = true; + break; + case MAILSTREAM_LOG_TYPE_DATA_SENT_PRIVATE: + type = ConnectionLogTypeSentPrivate; + isBuffer = true; + break; + } + return type; +} + +bool mailcore::isBufferFromLogType(int log_type) +{ + bool isBuffer = false; + + switch (log_type) { + case MAILSTREAM_LOG_TYPE_ERROR_PARSE: + case MAILSTREAM_LOG_TYPE_DATA_RECEIVED: + case MAILSTREAM_LOG_TYPE_DATA_SENT: + case MAILSTREAM_LOG_TYPE_DATA_SENT_PRIVATE: + isBuffer = true; + break; + } + return isBuffer; +} diff --git a/src/core/basetypes/MCConnectionLoggerUtils.h b/src/core/basetypes/MCConnectionLoggerUtils.h new file mode 100644 index 00000000..86f3c591 --- /dev/null +++ b/src/core/basetypes/MCConnectionLoggerUtils.h @@ -0,0 +1,21 @@ +// +// MCConnectionLoggerUtils.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/24/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCCONNECTIONLOGGERUTILS_H_ +#define __MAILCORE_MCCONNECTIONLOGGERUTILS_H_ + +#include <MailCore/MCConnectionLogger.h> + +namespace mailcore { + + ConnectionLogType getConnectionType(int log_type); + bool isBufferFromLogType(int log_type); + +} + +#endif diff --git a/src/core/basetypes/MCHTMLCleaner.cc b/src/core/basetypes/MCHTMLCleaner.cc index 12f1371e..7d45d3f2 100644 --- a/src/core/basetypes/MCHTMLCleaner.cc +++ b/src/core/basetypes/MCHTMLCleaner.cc @@ -68,6 +68,7 @@ String * HTMLCleaner::cleanHTML(String * input) String * result = String::stringWithUTF8Characters((const char *) output.bp); + tidyBufFree(&docbuf); tidyBufFree(&output); tidyBufFree(&errbuf); tidyRelease(tdoc); diff --git a/src/core/basetypes/MCLibetpan.cpp b/src/core/basetypes/MCLibetpan.cpp new file mode 100644 index 00000000..c8258cc2 --- /dev/null +++ b/src/core/basetypes/MCLibetpan.cpp @@ -0,0 +1,16 @@ +// +// MCLibetpan.cpp +// mailcore2 +// +// Created by Hoa Dinh on 6/28/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#include "MCLibetpan.h" + +#include <libetpan/libetpan.h> + +__attribute__((constructor)) +static void initialize() { + mailstream_cfstream_enabled = 1; +} diff --git a/src/core/basetypes/MCLibetpan.h b/src/core/basetypes/MCLibetpan.h new file mode 100644 index 00000000..ef7db1f8 --- /dev/null +++ b/src/core/basetypes/MCLibetpan.h @@ -0,0 +1,14 @@ +// +// MCLibetpan.h +// mailcore2 +// +// Created by Hoa Dinh on 6/28/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCLIBETPAN_H_ +#define __MAILCORE_MCLIBETPAN_H_ + +// No API in this file. + +#endif diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc index 879c194f..235738cd 100644 --- a/src/core/basetypes/MCObject.cc +++ b/src/core/basetypes/MCObject.cc @@ -83,7 +83,9 @@ String * Object::className() { int status; char * unmangled = abi::__cxa_demangle(typeid(* this).name(), NULL, NULL, &status); - return mailcore::String::uniquedStringWithUTF8Characters(unmangled); + String * result = String::uniquedStringWithUTF8Characters(unmangled); + free(unmangled); + return result; } String * Object::description() diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index d4529fab..9c30ad22 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -159,7 +159,7 @@ void OperationQueue::stoppedOnMainThread(void * context) mStarted = false; if (mCallback) { - mCallback->queueStoppedRunning(); + mCallback->queueStoppedRunning(this); } release(); // (2) @@ -173,7 +173,7 @@ void OperationQueue::startThread() return; if (mCallback) { - mCallback->queueStartRunning(); + mCallback->queueStartRunning(this); } retain(); // (3) diff --git a/src/core/basetypes/MCOperationQueueCallback.h b/src/core/basetypes/MCOperationQueueCallback.h index 367888bb..605de030 100644 --- a/src/core/basetypes/MCOperationQueueCallback.h +++ b/src/core/basetypes/MCOperationQueueCallback.h @@ -15,8 +15,8 @@ namespace mailcore { class OperationQueueCallback { public: - virtual void queueStartRunning() {} - virtual void queueStoppedRunning() {} + virtual void queueStartRunning(OperationQueue * queue) {} + virtual void queueStoppedRunning(OperationQueue * queue) {} }; } diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc index 832ffac2..034e3299 100644 --- a/src/core/basetypes/MCString.cc +++ b/src/core/basetypes/MCString.cc @@ -10,6 +10,9 @@ #include <libetpan/libetpan.h> #include <libxml/xmlmemory.h> #include <libxml/HTMLparser.h> +#if __APPLE__ +#include <CoreFoundation/CoreFoundation.h> +#endif #include "MCData.h" #include "MCHash.h" @@ -781,7 +784,9 @@ String * String::stringWithVUTF8Format(const char * format, va_list ap) { char * result; vasprintf(&result, format, ap); - return stringWithUTF8Characters(result); + String * str = stringWithUTF8Characters(result); + free(result); + return str; } String * String::stringWithUTF8Characters(const char * UTF8Characters) @@ -1121,6 +1126,20 @@ String * String::uppercaseString() void String::appendBytes(const char * bytes, unsigned int length, const char * charset) { +#if __APPLE__ + CFStringRef encodingName = CFStringCreateWithCString(NULL, charset, kCFStringEncodingUTF8); + CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding(encodingName); + CFStringRef cfStr = CFStringCreateWithBytes(NULL, (const UInt8 *) bytes, (CFIndex) length, encoding, false); + if (cfStr != NULL) { + CFDataRef data = CFStringCreateExternalRepresentation(NULL, cfStr, kCFStringEncodingUTF16LE, '_'); + if (data != NULL) { + appendCharactersLength((const UChar *) CFDataGetBytePtr(data), (unsigned int) CFDataGetLength(data) / 2); + CFRelease(data); + } + CFRelease(cfStr); + } + CFRelease(encodingName); +#else UErrorCode err; err = U_ZERO_ERROR; @@ -1150,6 +1169,7 @@ void String::appendBytes(const char * bytes, unsigned int length, const char * c free(dest); ucnv_close(converter); +#endif } String * String::extractedSubject() @@ -1773,7 +1793,7 @@ String * String::flattenHTML() bool String::hasSuffix(String * suffix) { - if (mLength > suffix->mLength) { + if (mLength >= suffix->mLength) { if (u_memcmp(suffix->mUnicodeChars + (mLength - suffix->mLength), mUnicodeChars, suffix->mLength) == 0) { return true; @@ -1784,7 +1804,7 @@ bool String::hasSuffix(String * suffix) bool String::hasPrefix(String * prefix) { - if (mLength > prefix->mLength) { + if (mLength >= prefix->mLength) { if (u_memcmp(prefix->mUnicodeChars, mUnicodeChars, prefix->mLength) == 0) { return true; } @@ -1810,13 +1830,34 @@ String * String::pathExtension() Data * String::dataUsingEncoding(const char * charset) { - UErrorCode err; - Data * data; - if (charset == NULL) { charset = "utf-8"; } +#if __APPLE__ + Data * data; + + data = NULL; + CFStringRef encodingName = CFStringCreateWithCString(NULL, charset, kCFStringEncodingUTF8); + CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding(encodingName); + CFStringRef cfStr = CFStringCreateWithBytes(NULL, (const UInt8 *) mUnicodeChars, + (CFIndex) mLength * sizeof(* mUnicodeChars), kCFStringEncodingUTF16LE, false); + if (cfStr != NULL) { + CFDataRef cfData = CFStringCreateExternalRepresentation(NULL, cfStr, encoding, '_'); + if (cfData != NULL) { + data = Data::dataWithBytes((const char *) CFDataGetBytePtr(cfData), + (unsigned int) CFDataGetLength(cfData)); + CFRelease(cfData); + } + CFRelease(cfStr); + } + CFRelease(encodingName); + + return data; +#else + UErrorCode err; + Data * data; + err = U_ZERO_ERROR; UConverter * converter = ucnv_open(charset, &err); if (converter == NULL) { @@ -1846,6 +1887,7 @@ Data * String::dataUsingEncoding(const char * charset) ucnv_close(converter); return data; +#endif } const char * String::fileSystemRepresentation() diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index a03c3edb..8437cded 100644 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -14,6 +14,8 @@ #include "MCIMAPNamespace.h" #include "MCIMAPSyncResult.h" #include "MCIMAPFolderStatus.h" +#include "MCConnectionLogger.h" +#include "MCConnectionLoggerUtils.h" using namespace mailcore; @@ -308,38 +310,40 @@ static IndexSet * indexSetFromSet(struct mailimap_set * imap_set) void IMAPSession::init() { mHostname = NULL; - mPort = 0; + mPort = 0; mUsername = NULL; mPassword = NULL; + mOAuth2Token = NULL; mAuthType = AuthTypeSASLNone; mConnectionType = ConnectionTypeClear; - mCheckCertificateEnabled = true; + mCheckCertificateEnabled = true; mVoIPEnabled = true; - mDelimiter = 0; - + mDelimiter = 0; + mBodyProgressEnabled = true; mIdleEnabled = false; - mXListEnabled = false; + mXListEnabled = false; mQResyncEnabled = false; mCondstoreEnabled = false; mIdentityEnabled = false; mWelcomeString = NULL; - mNeedsMboxMailWorkaround = false; - mDefaultNamespace = NULL; - mTimeout = 30; - mUIDValidity = 0; - mUIDNext = 0; + mNeedsMboxMailWorkaround = false; + mDefaultNamespace = NULL; + mTimeout = 30; + mUIDValidity = 0; + mUIDNext = 0; mModSequenceValue = 0; - mFolderMsgCount = 0; + mFolderMsgCount = 0; mFirstUnseenUid = 0; - mLastFetchedSequenceNumber = 0; - mCurrentFolder = NULL; + mLastFetchedSequenceNumber = 0; + mCurrentFolder = NULL; pthread_mutex_init(&mIdleLock, NULL); mCanIdle = false; - mState = STATE_DISCONNECTED; - mImap = NULL; - mProgressCallback = NULL; - mProgressItemsCount = 0; + mState = STATE_DISCONNECTED; + mImap = NULL; + mProgressCallback = NULL; + mProgressItemsCount = 0; + mConnectionLogger = NULL; } IMAPSession::IMAPSession() @@ -352,6 +356,7 @@ IMAPSession::~IMAPSession() MC_SAFE_RELEASE(mHostname); MC_SAFE_RELEASE(mUsername); MC_SAFE_RELEASE(mPassword); + MC_SAFE_RELEASE(mOAuth2Token); MC_SAFE_RELEASE(mWelcomeString); MC_SAFE_RELEASE(mDefaultNamespace); MC_SAFE_RELEASE(mCurrentFolder); @@ -398,6 +403,16 @@ String * IMAPSession::password() return mPassword; } +void IMAPSession::setOAuth2Token(String * token) +{ + MC_SAFE_REPLACE_COPY(String, mOAuth2Token, token); +} + +String * IMAPSession::OAuth2Token() +{ + return mOAuth2Token; +} + void IMAPSession::setAuthType(AuthType authType) { mAuthType = authType; @@ -487,6 +502,28 @@ void IMAPSession::items_progress(size_t current, size_t maximum, void * context) session->itemsProgress((unsigned int) current, (unsigned int) maximum); } +static void logger(mailimap * imap, int log_type, const char * buffer, size_t size, void * context) +{ + IMAPSession * session = (IMAPSession *) context; + + if (session->connectionLogger() == NULL) + return; + + ConnectionLogType type = getConnectionType(log_type); + if ((int) type == -1) + return; + + bool isBuffer = isBufferFromLogType(log_type); + + if (isBuffer) { + Data * data = Data::dataWithBytes(buffer, (unsigned int) size); + session->connectionLogger()->log(session, type, data); + } + else { + session->connectionLogger()->log(session, type, NULL); + } +} + void IMAPSession::setup() { MCAssert(mImap == NULL); @@ -494,6 +531,7 @@ void IMAPSession::setup() mImap = mailimap_new(0, NULL); mailimap_set_timeout(mImap, timeout()); mailimap_set_progress_callback(mImap, body_progress, IMAPSession::items_progress, this); + mailimap_set_logger(mImap, logger, this); } void IMAPSession::unsetup() @@ -720,6 +758,10 @@ void IMAPSession::login(ErrorCode * pError) utf8username, utf8username, utf8password, NULL/* realm */); break; + + case AuthTypeXOAuth2: + r = mailimap_oauth2_authenticate(mImap, MCUTF8(mUsername), MCUTF8(mOAuth2Token)); + break; } if (r == MAILIMAP_ERROR_STREAM) { * pError = ErrorConnection; @@ -2964,3 +3006,13 @@ bool IMAPSession::isDisconnected() { return mState == STATE_DISCONNECTED; } + +void IMAPSession::setConnectionLogger(ConnectionLogger * logger) +{ + mConnectionLogger = logger; +} + +ConnectionLogger * IMAPSession::connectionLogger() +{ + return mConnectionLogger; +} diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index c21c36cd..212f0876 100644 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -37,6 +37,11 @@ namespace mailcore { virtual void setPassword(String * password); virtual String * password(); + // To authenticate using OAuth2, username and oauth2token should be set. + // auth type to use is AuthTypeOAuth2. + virtual void setOAuth2Token(String * token); + virtual String * OAuth2Token(); + virtual void setAuthType(AuthType authType); virtual AuthType authType(); @@ -132,6 +137,9 @@ namespace mailcore { virtual bool isQResyncEnabled(); virtual bool isIdentityEnabled(); + virtual void setConnectionLogger(ConnectionLogger * logger); + virtual ConnectionLogger * connectionLogger(); + public: // private virtual void loginIfNeeded(ErrorCode * pError); virtual void connectIfNeeded(ErrorCode * pError); @@ -142,6 +150,7 @@ namespace mailcore { unsigned int mPort; String * mUsername; String * mPassword; + String * mOAuth2Token; AuthType mAuthType; ConnectionType mConnectionType; bool mCheckCertificateEnabled; @@ -172,6 +181,7 @@ namespace mailcore { mailimap * mImap; IMAPProgressCallback * mProgressCallback; unsigned int mProgressItemsCount; + ConnectionLogger * mConnectionLogger; void init(); void bodyProgress(unsigned int current, unsigned int maximum); diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc index 9cfe9157..fea4e5e0 100644 --- a/src/core/pop/MCPOPSession.cc +++ b/src/core/pop/MCPOPSession.cc @@ -6,6 +6,7 @@ #include "MCPOPMessageInfo.h" #include "MCPOPProgressCallback.h" #include "MCMessageHeader.h" +#include "MCConnectionLoggerUtils.h" using namespace mailcore; @@ -31,6 +32,7 @@ void POPSession::init() mCapabilities = POPCapabilityNone; mProgressCallback = NULL; mState = STATE_DISCONNECTED; + mConnectionLogger = NULL; } POPSession::POPSession() @@ -146,10 +148,30 @@ void POPSession::body_progress(size_t current, size_t maximum, void * context) session->bodyProgress((unsigned int) current, (unsigned int) maximum); } +static void logger(mailpop3 * pop3, int log_type, const char * buffer, size_t size, void * context) +{ + POPSession * session = (POPSession *) context; + + if (session->connectionLogger() == NULL) + return; + + ConnectionLogType type = getConnectionType(log_type); + bool isBuffer = isBufferFromLogType(log_type); + + if (isBuffer) { + Data * data = Data::dataWithBytes(buffer, (unsigned int) size); + session->connectionLogger()->log(session, type, data); + } + else { + session->connectionLogger()->log(session, type, NULL); + } +} + void POPSession::setup() { mPop = mailpop3_new(0, NULL); mailpop3_set_progress_callback(mPop, POPSession::body_progress, this); + mailpop3_set_logger(mPop, logger, this); } void POPSession::unsetup() @@ -544,3 +566,12 @@ void POPSession::checkAccount(ErrorCode * pError) loginIfNeeded(pError); } +void POPSession::setConnectionLogger(ConnectionLogger * logger) +{ + mConnectionLogger = logger; +} + +ConnectionLogger * POPSession::connectionLogger() +{ + return mConnectionLogger; +} diff --git a/src/core/pop/MCPOPSession.h b/src/core/pop/MCPOPSession.h index 3bbccf61..5de96b60 100644 --- a/src/core/pop/MCPOPSession.h +++ b/src/core/pop/MCPOPSession.h @@ -8,84 +8,89 @@ #ifdef __cplusplus namespace mailcore { - - class POPMessageInfo; - class POPProgressCallback; - class MessageHeader; + + class POPMessageInfo; + class POPProgressCallback; + class MessageHeader; - class POPSession : public Object { - - public: - POPSession(); - virtual ~POPSession(); - - virtual void setHostname(String * hostname); - virtual String * hostname(); + class POPSession : public Object { + + public: + POPSession(); + virtual ~POPSession(); + + virtual void setHostname(String * hostname); + virtual String * hostname(); - virtual void setPort(unsigned int port); - virtual unsigned int port(); + virtual void setPort(unsigned int port); + virtual unsigned int port(); - virtual void setUsername(String * username); - virtual String * username(); + virtual void setUsername(String * username); + virtual String * username(); - virtual void setPassword(String * password); - virtual String * password(); + virtual void setPassword(String * password); + virtual String * password(); - virtual void setAuthType(AuthType authType); - virtual AuthType authType(); + virtual void setAuthType(AuthType authType); + virtual AuthType authType(); - virtual void setConnectionType(ConnectionType connectionType); - virtual ConnectionType connectionType(); + virtual void setConnectionType(ConnectionType connectionType); + virtual ConnectionType connectionType(); - virtual void setTimeout(time_t timeout); - virtual time_t timeout(); - - virtual void setCheckCertificateEnabled(bool enabled); - virtual bool isCheckCertificateEnabled(); + virtual void setTimeout(time_t timeout); + virtual time_t timeout(); + + virtual void setCheckCertificateEnabled(bool enabled); + virtual bool isCheckCertificateEnabled(); - virtual void connect(ErrorCode * pError); - virtual void disconnect(); - - virtual void login(ErrorCode * pError); - + virtual void connect(ErrorCode * pError); + virtual void disconnect(); + + virtual void login(ErrorCode * pError); + virtual void checkAccount(ErrorCode * pError); - Array * /* POPMessageInfo */ fetchMessages(ErrorCode * pError); - - MessageHeader * fetchHeader(unsigned int index, ErrorCode * pError); - MessageHeader * fetchHeader(POPMessageInfo * msg, ErrorCode * pError); - - Data * fetchMessage(unsigned int index, POPProgressCallback * callback, ErrorCode * pError); - Data * fetchMessage(POPMessageInfo * msg, POPProgressCallback * callback, ErrorCode * pError); - - void deleteMessage(unsigned int index, ErrorCode * pError); - void deleteMessage(POPMessageInfo * msg, ErrorCode * pError); + Array * /* POPMessageInfo */ fetchMessages(ErrorCode * pError); + + MessageHeader * fetchHeader(unsigned int index, ErrorCode * pError); + MessageHeader * fetchHeader(POPMessageInfo * msg, ErrorCode * pError); + + Data * fetchMessage(unsigned int index, POPProgressCallback * callback, ErrorCode * pError); + Data * fetchMessage(POPMessageInfo * msg, POPProgressCallback * callback, ErrorCode * pError); + + void deleteMessage(unsigned int index, ErrorCode * pError); + void deleteMessage(POPMessageInfo * msg, ErrorCode * pError); + + virtual void setConnectionLogger(ConnectionLogger * logger); + virtual ConnectionLogger * connectionLogger(); + + private: + String * mHostname; + unsigned int mPort; + String * mUsername; + String * mPassword; + AuthType mAuthType; + ConnectionType mConnectionType; + bool mCheckCertificateEnabled; + time_t mTimeout; + + mailpop3 * mPop; + POPCapability mCapabilities; + POPProgressCallback * mProgressCallback; + int mState; + + ConnectionLogger * mConnectionLogger; - private: - String * mHostname; - unsigned int mPort; - String * mUsername; - String * mPassword; - AuthType mAuthType; - ConnectionType mConnectionType; - bool mCheckCertificateEnabled; - time_t mTimeout; - - mailpop3 * mPop; - POPCapability mCapabilities; - POPProgressCallback * mProgressCallback; - int mState; - - void init(); - void bodyProgress(unsigned int current, unsigned int maximum); - bool checkCertificate(); - static void body_progress(size_t current, size_t maximum, void * context); - void setup(); - void unsetup(); - void connectIfNeeded(ErrorCode * pError); - void loginIfNeeded(ErrorCode * pError); - void listIfNeeded(ErrorCode * pError); - }; + void init(); + void bodyProgress(unsigned int current, unsigned int maximum); + bool checkCertificate(); + static void body_progress(size_t current, size_t maximum, void * context); + void setup(); + void unsetup(); + void connectIfNeeded(ErrorCode * pError); + void loginIfNeeded(ErrorCode * pError); + void listIfNeeded(ErrorCode * pError); + }; } diff --git a/src/core/provider/MCMailProvider.cc b/src/core/provider/MCMailProvider.cc index b814e2ea..43fd94f9 100644 --- a/src/core/provider/MCMailProvider.cc +++ b/src/core/provider/MCMailProvider.cc @@ -18,7 +18,7 @@ using namespace mailcore; void MailProvider::init() { mIdentifier = NULL; - mImapServices = new Array(); + mImapServices = new Array(); mSmtpServices = new Array(); mPopServices = new Array(); mDomainMatch = new Array(); @@ -31,15 +31,27 @@ MailProvider::MailProvider() init(); } +MailProvider::MailProvider(MailProvider * other) +{ + init(); + MC_SAFE_REPLACE_COPY(String, mIdentifier, other->mIdentifier); + MC_SAFE_REPLACE_COPY(Array, mImapServices, other->mImapServices); + MC_SAFE_REPLACE_COPY(Array, mSmtpServices, other->mSmtpServices); + MC_SAFE_REPLACE_COPY(Array, mPopServices, other->mPopServices); + MC_SAFE_REPLACE_COPY(Array, mDomainMatch, other->mDomainMatch); + MC_SAFE_REPLACE_COPY(Set, mMxSet, other->mMxSet); + MC_SAFE_REPLACE_COPY(HashMap, mMailboxPaths, other->mMailboxPaths); +} + MailProvider::~MailProvider() { - MC_SAFE_RELEASE(mImapServices); - MC_SAFE_RELEASE(mSmtpServices); - MC_SAFE_RELEASE(mPopServices); - MC_SAFE_RELEASE(mMxSet); - MC_SAFE_RELEASE(mDomainMatch); - MC_SAFE_RELEASE(mMailboxPaths); - MC_SAFE_RELEASE(mIdentifier); + MC_SAFE_RELEASE(mImapServices); + MC_SAFE_RELEASE(mSmtpServices); + MC_SAFE_RELEASE(mPopServices); + MC_SAFE_RELEASE(mMxSet); + MC_SAFE_RELEASE(mDomainMatch); + MC_SAFE_RELEASE(mMailboxPaths); + MC_SAFE_RELEASE(mIdentifier); } MailProvider * MailProvider::providerWithInfo(HashMap * info) @@ -52,7 +64,7 @@ MailProvider * MailProvider::providerWithInfo(HashMap * info) void MailProvider::fillWithInfo(HashMap * info) { - Array * imapInfos; + Array * imapInfos; Array * smtpInfos; Array * popInfos; HashMap * serverInfo; @@ -68,9 +80,9 @@ void MailProvider::fillWithInfo(HashMap * info) } mxs = (Array *) info->objectForKey(MCSTR("mx")); mMxSet->removeAllObjects(); - mc_foreacharray(String, mx, mxs) { - mMxSet->addObject(mx->lowercaseString()); - } + mc_foreacharray(String, mx, mxs) { + mMxSet->addObject(mx->lowercaseString()); + } serverInfo = (HashMap *) info->objectForKey(MCSTR("servers")); imapInfos = (Array *) serverInfo->objectForKey(MCSTR("imap")); @@ -78,52 +90,52 @@ void MailProvider::fillWithInfo(HashMap * info) popInfos = (Array *) serverInfo->objectForKey(MCSTR("pop")); mImapServices->removeAllObjects(); - mc_foreacharray(HashMap, imapInfo, imapInfos) { - NetService * service = NetService::serviceWithInfo(imapInfo); + mc_foreacharray(HashMap, imapInfo, imapInfos) { + NetService * service = NetService::serviceWithInfo(imapInfo); mImapServices->addObject(service); - } - + } + mSmtpServices->removeAllObjects(); - mc_foreacharray(HashMap, smtpInfo, smtpInfos) { - NetService * service = NetService::serviceWithInfo(smtpInfo); - mSmtpServices->addObject(service); - } - + mc_foreacharray(HashMap, smtpInfo, smtpInfos) { + NetService * service = NetService::serviceWithInfo(smtpInfo); + mSmtpServices->addObject(service); + } + mPopServices->removeAllObjects(); - mc_foreacharray(HashMap, popInfo, popInfos) { - NetService * service = NetService::serviceWithInfo(popInfo); - mPopServices->addObject(service); - } + mc_foreacharray(HashMap, popInfo, popInfos) { + NetService * service = NetService::serviceWithInfo(popInfo); + mPopServices->addObject(service); + } } void MailProvider::setIdentifier(String * identifier) { - MC_SAFE_REPLACE_COPY(String, mIdentifier, identifier); + MC_SAFE_REPLACE_COPY(String, mIdentifier, identifier); } String * MailProvider::identifier() { - return mIdentifier; + return mIdentifier; } Array * MailProvider::imapServices() { - return mImapServices; + return mImapServices; } Array * MailProvider::smtpServices() { - return mSmtpServices; + return mSmtpServices; } Array * MailProvider::popServices() { - return mPopServices; + return mPopServices; } bool MailProvider::matchEmail(String * email) { - Array * components; + Array * components; String * domain; const char * cDomain; @@ -133,9 +145,9 @@ bool MailProvider::matchEmail(String * email) domain = (String *) components->lastObject(); cDomain = domain->UTF8Characters(); - - mc_foreacharray(String, match, mDomainMatch) { - regex_t r; + + mc_foreacharray(String, match, mDomainMatch) { + regex_t r; bool matched; match = String::stringWithUTF8Format("^%s$", match->UTF8Characters()); @@ -151,14 +163,14 @@ bool MailProvider::matchEmail(String * email) if (matched) return true; - } + } return false; } bool MailProvider::matchMX(String * hostname) { - return mMxSet->containsObject(hostname->lowercaseString()); + return mMxSet->containsObject(hostname->lowercaseString()); } String * MailProvider::sentMailFolderPath() @@ -168,38 +180,38 @@ String * MailProvider::sentMailFolderPath() String * MailProvider::starredFolderPath() { - return (String *) mMailboxPaths->objectForKey(MCSTR("starred")); + return (String *) mMailboxPaths->objectForKey(MCSTR("starred")); } String * MailProvider::allMailFolderPath() { - return (String *) mMailboxPaths->objectForKey(MCSTR("allmail")); + return (String *) mMailboxPaths->objectForKey(MCSTR("allmail")); } String * MailProvider::trashFolderPath() { - return (String *) mMailboxPaths->objectForKey(MCSTR("trash")); + return (String *) mMailboxPaths->objectForKey(MCSTR("trash")); } String * MailProvider::draftsFolderPath() { - return (String *) mMailboxPaths->objectForKey(MCSTR("drafts")); + return (String *) mMailboxPaths->objectForKey(MCSTR("drafts")); } String * MailProvider::spamFolderPath() { - return (String *) mMailboxPaths->objectForKey(MCSTR("spam")); + return (String *) mMailboxPaths->objectForKey(MCSTR("spam")); } String * MailProvider::importantFolderPath() { - return (String *) mMailboxPaths->objectForKey(MCSTR("important")); + return (String *) mMailboxPaths->objectForKey(MCSTR("important")); } bool MailProvider::isMainFolder(String * folderPath, String * prefix) { - mc_foreachdictionaryValue(String, path, mMailboxPaths) { - String * fullPath; + mc_foreachdictionaryValue(String, path, mMailboxPaths) { + String * fullPath; if (prefix != NULL) { fullPath = prefix->stringByAppendingString((String *) path); @@ -210,7 +222,7 @@ bool MailProvider::isMainFolder(String * folderPath, String * prefix) if (fullPath->isEqual(folderPath)) return true; - } + } return false; } @@ -219,3 +231,9 @@ String * MailProvider::description() { return String::stringWithUTF8Format("<%s:%p, %s>", className()->UTF8Characters(), this, MCUTF8(mIdentifier)); } + +Object * MailProvider::copy() +{ + return new MailProvider(this); +} + diff --git a/src/core/provider/MCMailProvider.h b/src/core/provider/MCMailProvider.h index 306b180d..81b816e9 100644 --- a/src/core/provider/MCMailProvider.h +++ b/src/core/provider/MCMailProvider.h @@ -45,8 +45,10 @@ namespace mailcore { virtual bool isMainFolder(String * folderPath, String * prefix); public: // subclass behavior + MailProvider(MailProvider * other); virtual String * description(); - + virtual Object * copy(); + public: // private virtual void setIdentifier(String * identifier); virtual void fillWithInfo(HashMap * info); diff --git a/src/core/provider/MCNetService.cc b/src/core/provider/MCNetService.cc index 53ae7475..f760dc61 100644 --- a/src/core/provider/MCNetService.cc +++ b/src/core/provider/MCNetService.cc @@ -19,12 +19,20 @@ void NetService::init() NetService::NetService() { - init(); + init(); +} + +NetService::NetService(NetService * other) +{ + init(); + MC_SAFE_REPLACE_COPY(String, mHostname, other->mHostname); + mPort = other->mPort; + mConnectionType = other->mConnectionType; } NetService::~NetService() { - MC_SAFE_RELEASE(mHostname); + MC_SAFE_RELEASE(mHostname); } NetService * NetService::serviceWithInfo(HashMap * info) @@ -37,10 +45,10 @@ NetService * NetService::serviceWithInfo(HashMap * info) void NetService::fillWithInfo(HashMap * info) { - bool ssl = false; + bool ssl = false; bool starttls = false; - - setHostname((String *) info->objectForKey(MCSTR("hostname"))); + + setHostname((String *) info->objectForKey(MCSTR("hostname"))); if (info->objectForKey(MCSTR("port")) != NULL) { setPort(((Value *) info->objectForKey(MCSTR("port")))->intValue()); } @@ -68,57 +76,57 @@ void NetService::setHostname(String *hostname) String * NetService::hostname() { - return mHostname; + return mHostname; } void NetService::setPort(unsigned int port) { - mPort = port; + mPort = port; } unsigned int NetService::port() { - return mPort; + return mPort; } void NetService::setConnectionType(ConnectionType connectionType) { - mConnectionType = connectionType; + mConnectionType = connectionType; } ConnectionType NetService::connectionType() { - return mConnectionType; + return mConnectionType; } String * NetService::normalizedHostnameWithEmail(String * email) { - Array *components = email->componentsSeparatedByString(MCSTR("@")); - String *hostname = (String *) mHostname->copy(); - if (components->count() != 0) { - hostname->replaceOccurrencesOfString(MCSTR("{domain}"), (String *) components->lastObject()); - return hostname; - } - return mHostname; + Array *components = email->componentsSeparatedByString(MCSTR("@")); + String *hostname = (String *) mHostname->copy(); + if (components->count() != 0) { + hostname->replaceOccurrencesOfString(MCSTR("{domain}"), (String *) components->lastObject()); + return hostname; + } + return mHostname; } HashMap * NetService::info() { - HashMap * result; + HashMap * result; result = new HashMap(); if (mHostname != NULL) { - result->setObjectForKey(MCSTR("hostname"), mHostname); + result->setObjectForKey(MCSTR("hostname"), mHostname); } if (mPort != 0) { - result->setObjectForKey(MCSTR("port"), Value::valueWithIntValue(mPort)); + result->setObjectForKey(MCSTR("port"), Value::valueWithIntValue(mPort)); } switch (mConnectionType) { case ConnectionTypeTLS: - result->setObjectForKey(MCSTR("ssl"), Value::valueWithBoolValue(true)); + result->setObjectForKey(MCSTR("ssl"), Value::valueWithBoolValue(true)); break; case ConnectionTypeStartTLS: - result->setObjectForKey(MCSTR("starttls"), Value::valueWithBoolValue(true)); + result->setObjectForKey(MCSTR("starttls"), Value::valueWithBoolValue(true)); break; default: break; @@ -126,3 +134,13 @@ HashMap * NetService::info() return result; } + +String * NetService::description() +{ + return String::stringWithUTF8Format("<%s:%p, hostname: %s, port: %u>", className()->UTF8Characters(), this, MCUTF8(mHostname), mPort); +} + +Object * NetService::copy() +{ + return new NetService(this); +} diff --git a/src/core/provider/MCNetService.h b/src/core/provider/MCNetService.h index 7b0b9e14..d3aa5dd7 100644 --- a/src/core/provider/MCNetService.h +++ b/src/core/provider/MCNetService.h @@ -15,35 +15,40 @@ #ifdef __cplusplus namespace mailcore { - class NetService : public Object { - - public: - NetService(); - virtual ~NetService(); - - virtual void setHostname(String * hostname); - virtual String * hostname(); - - virtual void setPort(unsigned int port); - virtual unsigned int port(); - - virtual void setConnectionType(ConnectionType connectionType); - virtual ConnectionType connectionType(); - - virtual String * normalizedHostnameWithEmail(String * email); + class NetService : public Object { + + public: + NetService(); + virtual ~NetService(); + + virtual void setHostname(String * hostname); + virtual String * hostname(); + + virtual void setPort(unsigned int port); + virtual unsigned int port(); + + virtual void setConnectionType(ConnectionType connectionType); + virtual ConnectionType connectionType(); + + virtual String * normalizedHostnameWithEmail(String * email); public: // serialization static NetService * serviceWithInfo(HashMap * info); - virtual HashMap * info(); + virtual HashMap * info(); + + public: //subclass behavior + NetService(NetService * other); + virtual String * description(); + virtual Object * copy(); + + private: + String * mHostname; + unsigned int mPort; + ConnectionType mConnectionType; - private: - String * mHostname; - unsigned int mPort; - ConnectionType mConnectionType; - - void init(); + void init(); void fillWithInfo(HashMap * info); - }; + }; } #endif diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc index ee225b16..dcbad71e 100644 --- a/src/core/smtp/MCSMTPSession.cc +++ b/src/core/smtp/MCSMTPSession.cc @@ -8,6 +8,7 @@ #include "MCMessageParser.h" #include "MCMessageHeader.h" #include "MCSMTPProgressCallback.h" +#include "MCConnectionLoggerUtils.h" using namespace mailcore; @@ -35,6 +36,7 @@ void SMTPSession::init() mLastSMTPResponse = NULL; mLastLibetpanError = 0; mLastSMTPResponseCode = 0; + mConnectionLogger = NULL; } SMTPSession::SMTPSession() @@ -161,11 +163,33 @@ void SMTPSession::bodyProgress(unsigned int current, unsigned int maximum) } } + +static void logger(mailsmtp * smtp, int log_type, const char * buffer, size_t size, void * context) +{ + SMTPSession * session = (SMTPSession *) context; + + if (session->connectionLogger() == NULL) + return; + + ConnectionLogType type = getConnectionType(log_type); + bool isBuffer = isBufferFromLogType(log_type); + + if (isBuffer) { + Data * data = Data::dataWithBytes(buffer, (unsigned int) size); + session->connectionLogger()->log(session, type, data); + } + else { + session->connectionLogger()->log(session, type, NULL); + } +} + + void SMTPSession::setup() { - mSmtp = mailsmtp_new(0, NULL); - mailsmtp_set_timeout(mSmtp, timeout()); + mSmtp = mailsmtp_new(0, NULL); + mailsmtp_set_timeout(mSmtp, timeout()); mailsmtp_set_progress_callback(mSmtp, body_progress, this); + mailsmtp_set_logger(mSmtp, logger, this); } void SMTPSession::unsetup() @@ -681,3 +705,13 @@ bool SMTPSession::isDisconnected() { return mState == STATE_DISCONNECTED; } + +void SMTPSession::setConnectionLogger(ConnectionLogger * logger) +{ + mConnectionLogger = logger; +} + +ConnectionLogger * SMTPSession::connectionLogger() +{ + return mConnectionLogger; +} diff --git a/src/core/smtp/MCSMTPSession.h b/src/core/smtp/MCSMTPSession.h index 57c6e0ce..491ecb07 100644 --- a/src/core/smtp/MCSMTPSession.h +++ b/src/core/smtp/MCSMTPSession.h @@ -8,88 +8,93 @@ #ifdef __cplusplus namespace mailcore { - - class Address; - class SMTPProgressCallback; - class MessageBuilder; + + class Address; + class SMTPProgressCallback; + class MessageBuilder; - class SMTPSession : public Object { - public: - SMTPSession(); - virtual ~SMTPSession(); - - virtual void setHostname(String * hostname); - virtual String * hostname(); + class SMTPSession : public Object { + public: + SMTPSession(); + virtual ~SMTPSession(); + + virtual void setHostname(String * hostname); + virtual String * hostname(); - virtual void setPort(unsigned int port); - virtual unsigned int port(); + virtual void setPort(unsigned int port); + virtual unsigned int port(); - virtual void setUsername(String * username); - virtual String * username(); + virtual void setUsername(String * username); + virtual String * username(); - virtual void setPassword(String * password); - virtual String * password(); + virtual void setPassword(String * password); + virtual String * password(); - virtual void setAuthType(AuthType authType); - virtual AuthType authType(); + virtual void setAuthType(AuthType authType); + virtual AuthType authType(); - virtual void setConnectionType(ConnectionType connectionType); - virtual ConnectionType connectionType(); + virtual void setConnectionType(ConnectionType connectionType); + virtual ConnectionType connectionType(); - virtual void setTimeout(time_t timeout); - virtual time_t timeout(); - - virtual void setCheckCertificateEnabled(bool enabled); - virtual bool isCheckCertificateEnabled(); - - virtual void setUseHeloIPEnabled(bool enabled); - virtual bool useHeloIPEnabled(); - - virtual void connect(ErrorCode * pError); - virtual void disconnect(); - - virtual void login(ErrorCode * pError); - + virtual void setTimeout(time_t timeout); + virtual time_t timeout(); + + virtual void setCheckCertificateEnabled(bool enabled); + virtual bool isCheckCertificateEnabled(); + + virtual void setUseHeloIPEnabled(bool enabled); + virtual bool useHeloIPEnabled(); + + virtual void connect(ErrorCode * pError); + virtual void disconnect(); + + virtual void login(ErrorCode * pError); + virtual void checkAccount(Address * from, ErrorCode * pError); - virtual void sendMessage(Data * messageData, SMTPProgressCallback * callback, ErrorCode * pError); + virtual void sendMessage(Data * messageData, SMTPProgressCallback * callback, ErrorCode * pError); - private: - String * mHostname; - unsigned int mPort; - String * mUsername; - String * mPassword; - AuthType mAuthType; - ConnectionType mConnectionType; - time_t mTimeout; - bool mCheckCertificateEnabled; - bool mUseHeloIPEnabled; - - mailsmtp * mSmtp; - SMTPProgressCallback * mProgressCallback; - int mState; - String * mLastSMTPResponse; + virtual void setConnectionLogger(ConnectionLogger * logger); + virtual ConnectionLogger * connectionLogger(); + + private: + String * mHostname; + unsigned int mPort; + String * mUsername; + String * mPassword; + AuthType mAuthType; + ConnectionType mConnectionType; + time_t mTimeout; + bool mCheckCertificateEnabled; + bool mUseHeloIPEnabled; + + mailsmtp * mSmtp; + SMTPProgressCallback * mProgressCallback; + int mState; + String * mLastSMTPResponse; int mLastLibetpanError; int mLastSMTPResponseCode; - - 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); - void setup(); - void unsetup(); - void connectIfNeeded(ErrorCode * pError); - void loginIfNeeded(ErrorCode * pError); - bool checkCertificate(); - - void sendMessage(Address * from, Array * /* Address */ recipients, Data * messageData, + + 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); + void setup(); + void unsetup(); + void connectIfNeeded(ErrorCode * pError); + void loginIfNeeded(ErrorCode * pError); + bool checkCertificate(); + + void sendMessage(Address * from, Array * /* Address */ recipients, Data * messageData, SMTPProgressCallback * callback, ErrorCode * pError); - void sendMessage(MessageBuilder * msg, SMTPProgressCallback * callback, ErrorCode * pError); + void sendMessage(MessageBuilder * msg, SMTPProgressCallback * callback, ErrorCode * pError); public: // private virtual bool isDisconnected(); - }; - + }; + } #endif diff --git a/src/objc/abstract/MCOAbstractMessage.mm b/src/objc/abstract/MCOAbstractMessage.mm index 6fedcc8a..05530845 100644 --- a/src/objc/abstract/MCOAbstractMessage.mm +++ b/src/objc/abstract/MCOAbstractMessage.mm @@ -28,6 +28,12 @@ return _message; } +- (id) init +{ + MCAssert(0); + return nil; +} + - (id) initWithMCMessage:(mailcore::AbstractMessage *)message { self = [super init]; @@ -40,7 +46,7 @@ - (void) dealloc { - _message->release(); + MC_SAFE_RELEASE(_message); [super dealloc]; } diff --git a/src/objc/abstract/MCOAbstractPart.mm b/src/objc/abstract/MCOAbstractPart.mm index 8b2b008d..7a37dcaf 100644 --- a/src/objc/abstract/MCOAbstractPart.mm +++ b/src/objc/abstract/MCOAbstractPart.mm @@ -27,6 +27,12 @@ return _part; } +- (id) init +{ + MCAssert(0); + return nil; +} + - (id) initWithMCPart:(mailcore::AbstractPart *)part { self = [super init]; @@ -39,7 +45,7 @@ - (void) dealloc { - _part->release(); + MC_SAFE_RELEASE(_part); [super dealloc]; } diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 8fafabf3..5ec21422 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -33,6 +33,8 @@ typedef enum { MCOAuthTypeSASLNTLM = 1 << 6, /** Kerberos 4 authentication.*/ MCOAuthTypeSASLKerberosV4 = 1 << 7, + /** OAuth2 authentication.*/ + MCOAuthTypeXOAuth2 = 1 << 8, } MCOAuthType; /** It's the IMAP flags of the folder.*/ @@ -324,4 +326,28 @@ typedef enum { MCOErrorInvalidAccount, } MCOErrorCode; +/** Here's the list of connection log types.*/ +typedef enum { + /** Received data.*/ + MCOConnectionLogTypeReceived, + /** Sent data.*/ + MCOConnectionLogTypeSent, + /** Sent private data. It can be a password.*/ + MCOConnectionLogTypeSentPrivate, + /** Parse error.*/ + MCOConnectionLogTypeErrorParse, + /** Error while receiving data. The data passed to the log will be nil.*/ + MCOConnectionLogTypeErrorReceived, + /** Error while sending dataThe data passed to the log will be nil.*/ + MCOConnectionLogTypeErrorSent, +} MCOConnectionLogType; + +/** + It's a network traffic logger. + @param connectionID is the identifier of the underlaying network socket. + @param type is the type of the log. + @param data is the data related to the log. + */ +typedef void (^MCOConnectionLogger)(void * connectionID, MCOConnectionLogType type, NSData * data); + #endif diff --git a/src/objc/abstract/MCOMessageHeader.mm b/src/objc/abstract/MCOMessageHeader.mm index 6729894d..427131b0 100644 --- a/src/objc/abstract/MCOMessageHeader.mm +++ b/src/objc/abstract/MCOMessageHeader.mm @@ -67,6 +67,12 @@ return self; } +- (void) dealloc +{ + _nativeHeader->release(); + [super dealloc]; +} + + (MCOMessageHeader *) messageHeaderWithMCMessageHeader:(mailcore::MessageHeader *)header { if (header == NULL) diff --git a/src/objc/imap/MCOIMAPAppendMessageOperation.mm b/src/objc/imap/MCOIMAPAppendMessageOperation.mm index 16463016..c281b925 100644 --- a/src/objc/imap/MCOIMAPAppendMessageOperation.mm +++ b/src/objc/imap/MCOIMAPAppendMessageOperation.mm @@ -57,6 +57,8 @@ typedef void (^CompletionType)(NSError *error, uint32_t createdUID); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], 0); } + [_completionBlock release]; + _completionBlock = nil; } - (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum diff --git a/src/objc/imap/MCOIMAPCapabilityOperation.mm b/src/objc/imap/MCOIMAPCapabilityOperation.mm index 048475c9..42952378 100644 --- a/src/objc/imap/MCOIMAPCapabilityOperation.mm +++ b/src/objc/imap/MCOIMAPCapabilityOperation.mm @@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * capabilities); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPCopyMessagesOperation.mm b/src/objc/imap/MCOIMAPCopyMessagesOperation.mm index 8f7bf501..d14bcc84 100644 --- a/src/objc/imap/MCOIMAPCopyMessagesOperation.mm +++ b/src/objc/imap/MCOIMAPCopyMessagesOperation.mm @@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * destUids); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], 0); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPFetchContentOperation.mm b/src/objc/imap/MCOIMAPFetchContentOperation.mm index 984751c0..d5d4757d 100644 --- a/src/objc/imap/MCOIMAPFetchContentOperation.mm +++ b/src/objc/imap/MCOIMAPFetchContentOperation.mm @@ -57,6 +57,8 @@ typedef void (^CompletionType)(NSError *error, NSData * data); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } - (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum diff --git a/src/objc/imap/MCOIMAPFetchFoldersOperation.mm b/src/objc/imap/MCOIMAPFetchFoldersOperation.mm index 53017c90..02b7d880 100644 --- a/src/objc/imap/MCOIMAPFetchFoldersOperation.mm +++ b/src/objc/imap/MCOIMAPFetchFoldersOperation.mm @@ -58,6 +58,8 @@ typedef void (^CompletionType)(NSError *error, NSArray *folder); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm index e43a46e5..6892ab1b 100644 --- a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm +++ b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm @@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, NSArray * messages, MCOIndexSet * } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil, nil); } + [_completionBlock release]; + _completionBlock = nil; } - (void) itemProgress:(unsigned int)current maximum:(unsigned int)maximum diff --git a/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm b/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm index aaa02c96..861298bf 100644 --- a/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm +++ b/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm @@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, NSDictionary * namespaces); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPFolderInfoOperation.mm b/src/objc/imap/MCOIMAPFolderInfoOperation.mm index 37b1a649..61766073 100644 --- a/src/objc/imap/MCOIMAPFolderInfoOperation.mm +++ b/src/objc/imap/MCOIMAPFolderInfoOperation.mm @@ -61,6 +61,8 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderInfo *info); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPFolderStatusOperation.mm b/src/objc/imap/MCOIMAPFolderStatusOperation.mm index c7f5370c..2420e0b9 100644 --- a/src/objc/imap/MCOIMAPFolderStatusOperation.mm +++ b/src/objc/imap/MCOIMAPFolderStatusOperation.mm @@ -55,6 +55,8 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderStatus *status); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPIdentityOperation.mm b/src/objc/imap/MCOIMAPIdentityOperation.mm index acc5ea10..f02fbba5 100644 --- a/src/objc/imap/MCOIMAPIdentityOperation.mm +++ b/src/objc/imap/MCOIMAPIdentityOperation.mm @@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, NSDictionary * serverIdentity); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPIdleOperation.mm b/src/objc/imap/MCOIMAPIdleOperation.mm index 86419b75..d43bf818 100644 --- a/src/objc/imap/MCOIMAPIdleOperation.mm +++ b/src/objc/imap/MCOIMAPIdleOperation.mm @@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()]); } + [_completionBlock release]; + _completionBlock = nil; } - (void) interruptIdle diff --git a/src/objc/imap/MCOIMAPOperation.mm b/src/objc/imap/MCOIMAPOperation.mm index 7b98c6bd..0b6d48e0 100644 --- a/src/objc/imap/MCOIMAPOperation.mm +++ b/src/objc/imap/MCOIMAPOperation.mm @@ -38,6 +38,8 @@ typedef void (^CompletionType)(NSError *error); NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()]; _completionBlock(error); + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPSearchOperation.mm b/src/objc/imap/MCOIMAPSearchOperation.mm index 92f57b62..730c73a0 100644 --- a/src/objc/imap/MCOIMAPSearchOperation.mm +++ b/src/objc/imap/MCOIMAPSearchOperation.mm @@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * searchResult); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 1b394eff..0358f7ad 100644 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -90,6 +90,15 @@ */ @property (nonatomic, assign) unsigned int maximumConnections; +/** + Sets logger callback. The network traffic will be sent to this block. + + [session setConnectionLogger:^(void * connectionID, MCOConnectionLogType type, NSData * data) { + ... + }]; +*/ +@property (nonatomic, copy) MCOConnectionLogger connectionLogger; + /** @name Folder Operations */ /** diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index a8df8aed..43f366e6 100644 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -22,8 +22,32 @@ using namespace mailcore; +@interface MCOIMAPSession () + +- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data; + +@end + +class MCOIMAPConnectionLoggerBridge : public Object, public ConnectionLogger { +public: + MCOIMAPConnectionLoggerBridge(MCOIMAPSession * session) + { + mSession = session; + } + + virtual void log(void * context, void * sender, ConnectionLogType logType, Data * data) + { + [mSession _logWithSender:sender connectionType:(MCOConnectionLogType)logType data:MCO_TO_OBJC(data)]; + } + +private: + MCOIMAPSession * mSession; +}; + @implementation MCOIMAPSession { IMAPAsyncSession * _session; + MCOConnectionLogger _connectionLogger; + MCOIMAPConnectionLoggerBridge * _loggerBridge; } #define nativeType mailcore::IMAPAsyncSession @@ -35,13 +59,16 @@ using namespace mailcore; - (id)init { self = [super init]; - if (self) { - _session = new IMAPAsyncSession(); - } + + _session = new IMAPAsyncSession(); + _loggerBridge = new MCOIMAPConnectionLoggerBridge(self); + return self; } - (void)dealloc { + MC_SAFE_RELEASE(_loggerBridge); + [_connectionLogger release]; _session->release(); [super dealloc]; } @@ -59,6 +86,24 @@ MCO_OBJC_SYNTHESIZE_SCALAR(char, char, setDelimiter, delimiter) MCO_OBJC_SYNTHESIZE_SCALAR(BOOL, BOOL, setAllowsFolderConcurrentAccessEnabled, allowsFolderConcurrentAccessEnabled) MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, maximumConnections) +- (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger +{ + [_connectionLogger release]; + _connectionLogger = [connectionLogger copy]; + + if (_connectionLogger != nil) { + _session->setConnectionLogger(_loggerBridge); + } + else { + _session->setConnectionLogger(NULL); + } +} + +- (MCOConnectionLogger) connectionLogger +{ + return _connectionLogger; +} + #pragma mark - Operations #define MCO_TO_OBJC_OP(op) [self _objcOperationFromNativeOp:op]; @@ -303,4 +348,9 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma return MCO_TO_OBJC_OP(coreOp); } +- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data +{ + _connectionLogger(sender, logType, data); +} + @end diff --git a/src/objc/pop/MCOPOPFetchHeaderOperation.mm b/src/objc/pop/MCOPOPFetchHeaderOperation.mm index 1d2c35c6..ab467a76 100644 --- a/src/objc/pop/MCOPOPFetchHeaderOperation.mm +++ b/src/objc/pop/MCOPOPFetchHeaderOperation.mm @@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, MCOMessageHeader * header); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } @end diff --git a/src/objc/pop/MCOPOPFetchMessageOperation.mm b/src/objc/pop/MCOPOPFetchMessageOperation.mm index 40740961..02bad3ad 100644 --- a/src/objc/pop/MCOPOPFetchMessageOperation.mm +++ b/src/objc/pop/MCOPOPFetchMessageOperation.mm @@ -90,6 +90,8 @@ private: } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } - (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum diff --git a/src/objc/pop/MCOPOPFetchMessagesOperation.mm b/src/objc/pop/MCOPOPFetchMessagesOperation.mm index dcb35845..2fe9b31f 100644 --- a/src/objc/pop/MCOPOPFetchMessagesOperation.mm +++ b/src/objc/pop/MCOPOPFetchMessagesOperation.mm @@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, NSArray * messages); } else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } + [_completionBlock release]; + _completionBlock = nil; } diff --git a/src/objc/pop/MCOPOPOperation.mm b/src/objc/pop/MCOPOPOperation.mm index 9b58f84d..5f4d1f59 100644 --- a/src/objc/pop/MCOPOPOperation.mm +++ b/src/objc/pop/MCOPOPOperation.mm @@ -41,6 +41,8 @@ typedef void (^CompletionType)(NSError *error); NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()]; _completionBlock(error); + [_completionBlock release]; + _completionBlock = nil; } - (void) setSession:(MCOPOPSession *)session diff --git a/src/objc/pop/MCOPOPSession.h b/src/objc/pop/MCOPOPSession.h index 6ecca042..4f98421c 100644 --- a/src/objc/pop/MCOPOPSession.h +++ b/src/objc/pop/MCOPOPSession.h @@ -53,6 +53,15 @@ See MCOConnectionType for more information.*/ /** When set to YES, the connection will fail if the certificate is incorrect.*/ @property (nonatomic, assign, getter=isCheckCertificateEnabled) BOOL checkCertificateEnabled; +/** + Sets logger callback. The network traffic will be sent to this block. + + [session setConnectionLogger:^(void * connectionID, MCOConnectionLogType type, NSData * data) { + ... + }]; + */ +@property (nonatomic, copy) MCOConnectionLogger connectionLogger; + /** @name Operations */ /** diff --git a/src/objc/pop/MCOPOPSession.mm b/src/objc/pop/MCOPOPSession.mm index 11f7cad6..42c76646 100644 --- a/src/objc/pop/MCOPOPSession.mm +++ b/src/objc/pop/MCOPOPSession.mm @@ -16,8 +16,34 @@ #import "MCOPOPFetchMessagesOperation.h" #import "MCOPOPOperation+Private.h" +using namespace mailcore; + +@interface MCOPOPSession () + +- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data; + +@end + +class MCOPOPConnectionLoggerBridge : public Object, public ConnectionLogger { +public: + MCOPOPConnectionLoggerBridge(MCOPOPSession * session) + { + mSession = session; + } + + virtual void log(void * context, void * sender, ConnectionLogType logType, Data * data) + { + [mSession _logWithSender:sender connectionType:(MCOConnectionLogType)logType data:MCO_TO_OBJC(data)]; + } + +private: + MCOPOPSession * mSession; +}; + @implementation MCOPOPSession { mailcore::POPAsyncSession * _session; + MCOConnectionLogger _connectionLogger; + MCOPOPConnectionLoggerBridge * _loggerBridge; } #define nativeType mailcore::POPAsyncSession @@ -34,13 +60,16 @@ - (id)init { self = [super init]; - if (self) { - _session = new mailcore::POPAsyncSession(); - } + + _session = new mailcore::POPAsyncSession(); + _loggerBridge = new MCOPOPConnectionLoggerBridge(self); + return self; } - (void)dealloc { + MC_SAFE_RELEASE(_loggerBridge); + [_connectionLogger release]; _session->release(); [super dealloc]; } @@ -54,6 +83,24 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOConnectionType, mailcore::ConnectionType, setConne MCO_OBJC_SYNTHESIZE_SCALAR(NSTimeInterval, time_t, setTimeout, timeout) MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) +- (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger +{ + [_connectionLogger release]; + _connectionLogger = [connectionLogger copy]; + + if (_connectionLogger != nil) { + _session->setConnectionLogger(_loggerBridge); + } + else { + _session->setConnectionLogger(NULL); + } +} + +- (MCOConnectionLogger) connectionLogger +{ + return _connectionLogger; +} + #pragma mark - Operations @@ -111,4 +158,9 @@ MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) return OPAQUE_OPERATION(coreOp); } +- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data +{ + _connectionLogger(sender, logType, data); +} + @end diff --git a/src/objc/smtp/MCOSMTPOperation.mm b/src/objc/smtp/MCOSMTPOperation.mm index cd52ad13..9d96613f 100644 --- a/src/objc/smtp/MCOSMTPOperation.mm +++ b/src/objc/smtp/MCOSMTPOperation.mm @@ -41,6 +41,8 @@ typedef void (^CompletionType)(NSError *error); NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()]; _completionBlock(error); + [_completionBlock release]; + _completionBlock = NULL; } - (void) setSession:(MCOSMTPSession *)session diff --git a/src/objc/smtp/MCOSMTPSendOperation.mm b/src/objc/smtp/MCOSMTPSendOperation.mm index e41a9f5a..8a7d5b04 100644 --- a/src/objc/smtp/MCOSMTPSendOperation.mm +++ b/src/objc/smtp/MCOSMTPSendOperation.mm @@ -80,16 +80,16 @@ private: [self start]; } +// This method needs to be duplicated from MCOSMTPOperation since _completionBlock +// references the instance of this subclass and not the one from MCOSMTPOperation. - (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()]); - } + NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()]; + _completionBlock(error); + [_completionBlock release]; + _completionBlock = NULL; } - (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum diff --git a/src/objc/smtp/MCOSMTPSession.h b/src/objc/smtp/MCOSMTPSession.h index 08189bed..44d37942 100644 --- a/src/objc/smtp/MCOSMTPSession.h +++ b/src/objc/smtp/MCOSMTPSession.h @@ -64,6 +64,15 @@ */ @property (nonatomic, assign, getter=isUseHeloIPEnabled) BOOL useHeloIPEnabled; +/** + Sets logger callback. The network traffic will be sent to this block. + + [session setConnectionLogger:^(void * connectionID, MCOConnectionLogType type, NSData * data) { + ... + }]; + */ +@property (nonatomic, copy) MCOConnectionLogger connectionLogger; + /** @name Operations */ /** diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm index de6b54cd..1538d53a 100644 --- a/src/objc/smtp/MCOSMTPSession.mm +++ b/src/objc/smtp/MCOSMTPSession.mm @@ -17,8 +17,34 @@ #import "MCOAddress.h" #import "MCOSMTPOperation+Private.h" +using namespace mailcore; + +@interface MCOSMTPSession () + +- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data; + +@end + +class MCOSMTPConnectionLoggerBridge : public Object, public ConnectionLogger { +public: + MCOSMTPConnectionLoggerBridge(MCOSMTPSession * session) + { + mSession = session; + } + + virtual void log(void * context, void * sender, ConnectionLogType logType, Data * data) + { + [mSession _logWithSender:sender connectionType:(MCOConnectionLogType)logType data:MCO_TO_OBJC(data)]; + } + +private: + MCOSMTPSession * mSession; +}; + @implementation MCOSMTPSession { mailcore::SMTPAsyncSession * _session; + MCOConnectionLogger _connectionLogger; + MCOSMTPConnectionLoggerBridge * _loggerBridge; } #define nativeType mailcore::SMTPAsyncSession @@ -30,13 +56,16 @@ - (id)init { self = [super init]; - if (self) { - _session = new mailcore::SMTPAsyncSession(); - } + + _session = new mailcore::SMTPAsyncSession(); + _loggerBridge = new MCOSMTPConnectionLoggerBridge(self); + return self; } - (void)dealloc { + MC_SAFE_RELEASE(_loggerBridge); + [_connectionLogger release]; _session->release(); [super dealloc]; } @@ -51,6 +80,24 @@ MCO_OBJC_SYNTHESIZE_SCALAR(NSTimeInterval, time_t, setTimeout, timeout) MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) MCO_OBJC_SYNTHESIZE_BOOL(setUseHeloIPEnabled, useHeloIPEnabled) +- (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger +{ + [_connectionLogger release]; + _connectionLogger = [connectionLogger copy]; + + if (_connectionLogger != nil) { + _session->setConnectionLogger(_loggerBridge); + } + else { + _session->setConnectionLogger(NULL); + } +} + +- (MCOConnectionLogger) connectionLogger +{ + return _connectionLogger; +} + #pragma mark - Operations - (MCOSMTPSendOperation *) sendOperationWithData:(NSData *)messageData @@ -69,4 +116,9 @@ MCO_OBJC_SYNTHESIZE_BOOL(setUseHeloIPEnabled, useHeloIPEnabled) return result; } +- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data +{ + _connectionLogger(sender, logType, data); +} + @end |