OSDN Git Service

Send email to multi person success and add CC and TO list
[tortoisegit/TortoiseGitJp.git] / src / Utils / HwSMTP.cpp
index c628191..ec51322 100644 (file)
@@ -7,7 +7,7 @@
 #include "HwSMTP.h"\r
 #include "CBase64.h"\r
 #include "SpeedPostEmail.h"\r
-\r
+#include "Windns.h"\r
 #include <Afxmt.h>\r
 \r
 #ifdef _DEBUG\r
@@ -29,14 +29,16 @@ public:
                BOOL bMustAuth,\r
                LPCTSTR lpszAddrFrom,\r
                LPCTSTR lpszAddrTo,\r
-               LPCTSTR lpszSenderName,\r
+               LPCTSTR lpszFromName,\r
                LPCTSTR lpszReceiverName,\r
                LPCTSTR lpszSubject,\r
                LPCTSTR lpszBody,\r
                LPCTSTR lpszCharSet,\r
                CStringArray *pStrAryAttach,\r
-               CStringArray *pStrAryCC,\r
-               UINT nSmtpSrvPort\r
+               LPCTSTR pStrAryCC,\r
+               UINT nSmtpSrvPort,\r
+               LPCTSTR pSender,\r
+               LPCTSTR pToList\r
                )\r
        {\r
                m_csSmtpSrvHost = GET_SAFE_STRING(lpszSmtpSrvHost);\r
@@ -45,15 +47,18 @@ public:
                m_bMustAuth = bMustAuth;\r
                m_csAddrFrom = GET_SAFE_STRING(lpszAddrFrom);\r
                m_csAddrTo = GET_SAFE_STRING(lpszAddrTo);\r
-               m_csSenderName = GET_SAFE_STRING(lpszSenderName);\r
+               m_csFromName = GET_SAFE_STRING(lpszFromName);\r
                m_csReceiverName = GET_SAFE_STRING(lpszReceiverName);\r
                m_csSubject = GET_SAFE_STRING(lpszSubject);\r
                m_csBody = GET_SAFE_STRING(lpszBody);\r
                m_csCharSet = GET_SAFE_STRING(lpszCharSet);\r
+               m_StrCC = GET_SAFE_STRING(pStrAryCC);\r
+               m_csSender = GET_SAFE_STRING(pSender);\r
+               m_csToList = GET_SAFE_STRING(pToList);\r
+\r
                if ( pStrAryAttach )\r
                        m_StrAryAttach.Append ( *pStrAryAttach );\r
-               if ( pStrAryCC )\r
-                       m_StrAryCC.Append ( *pStrAryCC );\r
+               \r
                m_nSmtpSrvPort = nSmtpSrvPort;\r
                m_hThread = NULL;\r
        }\r
@@ -65,14 +70,16 @@ public:
        BOOL m_bMustAuth;\r
        CString m_csAddrFrom;\r
        CString m_csAddrTo;\r
-       CString m_csSenderName;\r
+       CString m_csFromName;\r
        CString m_csReceiverName;\r
        CString m_csSubject;\r
        CString m_csBody;\r
        CString m_csCharSet;\r
        CStringArray m_StrAryAttach;\r
-       CStringArray m_StrAryCC;\r
+       CString m_StrCC;\r
        UINT m_nSmtpSrvPort;\r
+       CString m_csSender;\r
+       CString m_csToList;\r
 \r
        HANDLE m_hThread;\r
 };\r
@@ -96,6 +103,116 @@ CHwSMTP::~CHwSMTP()
 {\r
 }\r
 \r
+void CHwSMTP::GetNameAddress(CString &in, CString &name,CString &address)\r
+{\r
+       int start,end;\r
+       start=in.Find(_T('<'));\r
+       end=in.Find(_T('>'));\r
+\r
+       if(start >=0 && end >=0)\r
+       {\r
+               name=in.Left(start);\r
+               address=in.Mid(start+1,end-start-1);\r
+       }\r
+       else\r
+               address=in;\r
+}\r
+\r
+CString CHwSMTP::GetServerAddress(CString &email)\r
+{\r
+       CString str;\r
+       int start,end;\r
+       \r
+       start = email.Find(_T("<"));\r
+       end = email.Find(_T(">"));\r
+\r
+       if(start>=0 && end >=0)\r
+       {\r
+               str=email.Mid(start+1,end-start-1);\r
+       }\r
+       else\r
+       {\r
+               str=email;\r
+       }\r
+\r
+       start = str.Find(_T('@'));\r
+       return str.Mid(start+1);\r
+\r
+}\r
+\r
+BOOL CHwSMTP::SendSpeedEmail\r
+               (\r
+                       LPCTSTR lpszAddrFrom,\r
+                       LPCTSTR lpszAddrTo,\r
+                       LPCTSTR lpszSubject,\r
+                       LPCTSTR lpszBody,\r
+                       LPCTSTR lpszCharSet,                                            // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"\r
+                       CStringArray *pStrAryAttach,\r
+                       LPCTSTR pStrAryCC,\r
+                       UINT    nSmtpSrvPort,\r
+                       LPCTSTR pSend \r
+               )\r
+{\r
+\r
+       BOOL ret=true;\r
+       CString To;\r
+       To += GET_SAFE_STRING(lpszAddrTo);\r
+       To += _T(";");\r
+       To += GET_SAFE_STRING(pStrAryCC);\r
+\r
+       std::map<CString,std::vector<CString>> Address;\r
+\r
+       int start = 0;\r
+       while( start >= 0 )\r
+       {\r
+               CString one= To.Tokenize(_T(";"),start);\r
+               one=one.Trim();\r
+               if(one.IsEmpty())\r
+                       continue;\r
+               \r
+               CString addr;\r
+               addr = GetServerAddress(one);\r
+               if(addr.IsEmpty())\r
+                       continue;\r
+               \r
+               \r
+               Address[addr].push_back(one);           \r
+\r
+       }\r
+\r
+       std::map<CString,std::vector<CString>>::iterator itr1  =  Address.begin();\r
+    for(  ;  itr1  !=  Address.end();  ++itr1 )\r
+    {\r
+        PDNS_RECORD pDnsRecord; \r
+\r
+               DnsQuery(itr1->first ,\r
+                                   DNS_TYPE_MX,DNS_QUERY_BYPASS_CACHE,\r
+                                           NULL,                   //Contains DNS server IP address.\r
+                        &pDnsRecord,                //Resource record that contains the response.\r
+                        NULL\r
+                                               ); \r
+               \r
+               CString to;\r
+               to.Empty();\r
+               for(int i=0;i<itr1->second.size();i++)\r
+               {\r
+                       to+=itr1->second[i];\r
+                       to+=_T(";");\r
+               }\r
+               if(to.IsEmpty())\r
+                       continue;\r
+\r
+               if(!SendEmail(pDnsRecord->Data.MX.pNameExchange,NULL,NULL,false,\r
+                               lpszAddrFrom,to,lpszSubject,lpszBody,lpszCharSet,pStrAryAttach,pStrAryCC,\r
+                               25,pSend,lpszAddrTo))\r
+                       ret = false;\r
+\r
+               //SendEmail(itr1.first,NULL,NULL,false,lpszAddrFrom,,lpszFromname);\r
+               DnsRecordListFree(pDnsRecord,DnsFreeRecordList);\r
+    }  \r
+\r
+       return ret;\r
+}\r
 BOOL CHwSMTP::SendEmail (\r
                LPCTSTR lpszSmtpSrvHost,\r
                LPCTSTR lpszUserName,\r
@@ -103,19 +220,21 @@ BOOL CHwSMTP::SendEmail (
                BOOL bMustAuth,\r
                LPCTSTR lpszAddrFrom,\r
                LPCTSTR lpszAddrTo,\r
-               LPCTSTR lpszSenderName,\r
-               LPCTSTR lpszReceiverName,\r
                LPCTSTR lpszSubject,\r
                LPCTSTR lpszBody,\r
                LPCTSTR lpszCharSet,                                            // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"\r
                CStringArray *pStrAryAttach/*=NULL*/,\r
-               CStringArray *pStrAryCC/*=NULL*/,\r
-               UINT nSmtpSrvPort/*=25*/\r
+               LPCTSTR pStrAryCC/*=NULL*/,\r
+               UINT nSmtpSrvPort,/*=25*/\r
+               LPCTSTR pSender,\r
+               LPCTSTR pToList\r
                )\r
 {\r
-       TRACE ( _T("·¢ËÍÓʼþ£º%s, %s, %s\n"), lpszAddrTo, lpszReceiverName, lpszBody );\r
+       TRACE ( _T("·¢ËÍÓʼþ£º%s,  %s\n"), lpszAddrTo, lpszBody );\r
        m_StrAryAttach.RemoveAll();\r
-       m_StrAryCC.RemoveAll();\r
+\r
+       m_StrCC += GET_SAFE_STRING(pStrAryCC);\r
+\r
        m_csSmtpSrvHost = GET_SAFE_STRING ( lpszSmtpSrvHost );\r
        if ( m_csSmtpSrvHost.GetLength() <= 0 )\r
        {\r
@@ -133,18 +252,21 @@ BOOL CHwSMTP::SendEmail (
 \r
        m_csAddrFrom = GET_SAFE_STRING ( lpszAddrFrom );\r
        m_csAddrTo = GET_SAFE_STRING ( lpszAddrTo );\r
-       m_csSenderName = GET_SAFE_STRING ( lpszSenderName );\r
-       m_csReceiverName = GET_SAFE_STRING ( lpszReceiverName );\r
+//     m_csFromName = GET_SAFE_STRING ( lpszFromName );\r
+//     m_csReceiverName = GET_SAFE_STRING ( lpszReceiverName );\r
        m_csSubject = GET_SAFE_STRING ( lpszSubject );\r
        m_csBody = GET_SAFE_STRING ( lpszBody );\r
+       \r
+       this->m_csSender = GET_SAFE_STRING(pSender);\r
+       this->m_csToList = GET_SAFE_STRING(pToList);\r
+\r
        m_nSmtpSrvPort = nSmtpSrvPort;\r
+\r
        if ( lpszCharSet && lstrlen(lpszCharSet) > 0 )\r
                m_csCharSet.Format ( _T("\r\n\tcharset=\"%s\"\r\n"), lpszCharSet );\r
 \r
        if      (\r
-                       m_csAddrFrom.GetLength() <= 0 || m_csAddrTo.GetLength() <= 0 ||\r
-                       m_csSenderName.GetLength() <= 0 || m_csReceiverName.GetLength() <= 0 ||\r
-                       m_csSubject.GetLength() <= 0 || m_csBody.GetLength() <= 0\r
+                       m_csAddrFrom.GetLength() <= 0 || m_csAddrTo.GetLength() <= 0 \r
                )\r
        {\r
                m_csLastError.Format ( _T("Parameter Error!") );\r
@@ -158,12 +280,8 @@ BOOL CHwSMTP::SendEmail (
        if ( m_StrAryAttach.GetSize() < 1 )\r
                m_csMIMEContentType = _T( "text/plain");\r
 \r
-       if ( pStrAryCC )\r
-       {\r
-               m_StrAryCC.Append ( *pStrAryCC );\r
-       }       \r
-\r
        // ´´½¨Socket\r
+       m_SendSock.Close();\r
        if ( !m_SendSock.Create () )\r
        {\r
                m_csLastError.Format ( _T("Create socket failed!") );\r
@@ -347,21 +465,39 @@ BOOL CHwSMTP::auth()
 BOOL CHwSMTP::SendHead()\r
 {\r
        CString str;\r
-       str.Format( _T("MAIL From: <%s>\r\n"), m_csAddrFrom );\r
+       CString name,addr;\r
+       GetNameAddress(m_csAddrFrom,name,addr);\r
+\r
+       str.Format( _T("MAIL From: <%s>\r\n"), addr );\r
        if ( !Send ( str  ) ) return FALSE;\r
 \r
        if ( !GetResponse ( _T("250") ) ) return FALSE;\r
        \r
-       str.Format(_T("RCPT TO: <%s>\r\n"), m_csAddrTo );\r
-       if ( !Send ( str ) ) return FALSE;\r
-       if ( !GetResponse ( _T("250") ) ) return FALSE;\r
+       int start=0;\r
+       while(start>=0)\r
+       {\r
+               CString one=m_csAddrTo.Tokenize(_T(";"),start);\r
+               one=one.Trim();\r
+               if(one.IsEmpty())\r
+                       continue;\r
 \r
+               \r
+               GetNameAddress(one,name,addr);\r
+               \r
+               str.Format(_T("RCPT TO: <%s>\r\n"), addr );\r
+               if ( !Send ( str ) ) return FALSE;\r
+               if ( !GetResponse ( _T("250") ) ) return FALSE;\r
+       }\r
+\r
+#if 0\r
        for ( int i=0; i<m_StrAryCC.GetSize(); i++ )\r
        {\r
                str.Format(_T("RCPT TO: <%s>\r\n"), m_StrAryCC.GetAt(i)  );\r
                if ( !Send ( str ) ) return FALSE;\r
                if ( !GetResponse ( _T("250") ) ) return FALSE;\r
        }\r
+#endif\r
+\r
        if ( !Send ( CString(_T("DATA\r\n") ) ) ) return FALSE;\r
        if ( !GetResponse ( CString(_T("354") )) ) return FALSE;        \r
 \r
@@ -378,7 +514,22 @@ BOOL CHwSMTP::SendSubject()
                csSubject += GetCompatibleString(FormatDateTime (tNow, _T("%a, %d %b %y %H:%M:%S %Z")).GetBuffer(0),FALSE);\r
        }\r
        csSubject += _T("\r\n");\r
-       csSubject += FormatString ( _T("From: %s\r\nTo: %s\r\n"), m_csSenderName, m_csReceiverName );\r
+       csSubject += FormatString ( _T("From: %s\r\n"), this->m_csAddrFrom);\r
+       \r
+       csSubject += FormatString ( _T("CC: %s\r\n"), this->m_StrCC);\r
+       \r
+       if(m_csSender.IsEmpty())\r
+               m_csSender =  this->m_csAddrFrom;\r
+       \r
+       csSubject += FormatString ( _T("Sender: %s\r\n"), this->m_csSender);\r
+       \r
+       if(this->m_csToList.IsEmpty())\r
+               m_csToList = m_csReceiverName;\r
+       \r
+       csSubject += FormatString ( _T("To: %s\r\n"), this->m_csToList);\r
+\r
+       CString m_csToList;\r
+\r
        csSubject += FormatString ( _T("Subject: %s\r\n"), m_csSubject );\r
        csSubject += FormatString ( _T("X-Mailer: TortoiseGit\r\nMIME-Version: 1.0\r\nContent-Type: %s; %s boundary=%s\r\n\r\n") , \r
                m_csMIMEContentType, m_csCharSet, m_csPartBoundary );\r
@@ -512,14 +663,13 @@ DWORD WINAPI ThreadProc_SendEmail( LPVOID lpParameter )
                pEMailObject->m_bMustAuth,\r
                pEMailObject->m_csAddrFrom,\r
                pEMailObject->m_csAddrTo,\r
-               pEMailObject->m_csSenderName,\r
-               pEMailObject->m_csReceiverName,\r
                pEMailObject->m_csSubject,\r
                pEMailObject->m_csBody,\r
                pEMailObject->m_csCharSet,\r
                &pEMailObject->m_StrAryAttach,\r
-               &pEMailObject->m_StrAryCC,\r
-               pEMailObject->m_nSmtpSrvPort\r
+               pEMailObject->m_StrCC,\r
+               pEMailObject->m_nSmtpSrvPort,\r
+               pEMailObject->m_csSender\r
                );\r
        if ( !bRet)\r
        {\r
@@ -551,14 +701,16 @@ BOOL SendEmail (
                                BOOL bMustAuth,\r
                                LPCTSTR lpszAddrFrom,\r
                                LPCTSTR lpszAddrTo,\r
-                               LPCTSTR lpszSenderName,\r
+                               LPCTSTR lpszFromName,\r
                                LPCTSTR lpszReceiverName,\r
                                LPCTSTR lpszSubject,\r
                                LPCTSTR lpszBody,\r
                                LPCTSTR lpszCharSet/*=NULL*/,\r
                                CStringArray *pStrAryAttach/*=NULL*/,\r
-                               CStringArray *pStrAryCC/*=NULL*/,\r
-                               UINT nSmtpSrvPort/*=25*/\r
+                               LPCTSTR pStrAryCC/*=NULL*/,\r
+                               UINT nSmtpSrvPort/*=25*/,\r
+                               LPCTSTR lpszSender,\r
+                               LPCTSTR lpszToList\r
                                )\r
 {\r
        if ( !lpszSmtpSrvHost || lstrlen(lpszSmtpSrvHost) < 1 ||\r
@@ -576,14 +728,16 @@ BOOL SendEmail (
                bMustAuth,\r
                lpszAddrFrom,\r
                lpszAddrTo,\r
-               lpszSenderName,\r
+               lpszFromName,\r
                lpszReceiverName,\r
                lpszSubject,\r
                lpszBody,\r
                lpszCharSet,\r
                pStrAryAttach,\r
                pStrAryCC,\r
-               nSmtpSrvPort\r
+               nSmtpSrvPort,\r
+               lpszSender,\r
+               lpszToList\r
                );\r
        if ( !pEMailObject ) return FALSE;\r
 \r