Prepare release and bump version numbers to 2.17.0.2
[TortoiseGit.git] / src / TortoiseProc / SendMail.cpp
blobdb9aa985be345990381d45d45b910f4b7124381d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2016, 2018-2019, 2023 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "SendMail.h"
22 #include "HwSMTP.h"
23 #include "MailMsg.h"
24 #include "Git.h"
25 #include "WindowsCredentialsStore.h"
27 class CAppUtils;
29 CSendMail::CSendMail(const CString& To, const CString& CC, bool bAttachment)
30 : m_sSenderName(g_Git.GetUserName())
31 , m_sSenderMail(g_Git.GetUserEmail())
32 , m_sTo(To)
33 , m_sCC(CC)
34 , m_bAttachment(bAttachment)
38 CSendMail::~CSendMail()
42 int CSendMail::SendMail(const CTGitPath &item, CGitProgressList * instance, const CString& FromName, const CString& FromMail, const CString& To, const CString& CC, const CString &subject, const CString& body, CStringArray &attachments)
44 ASSERT(instance);
45 int retry = 0;
46 while (retry < 3)
48 if (instance->IsCancelled() == TRUE)
50 instance->ReportUserCanceled();
51 return -1;
54 instance->AddNotify(new CGitProgressList::NotificationData(item, IDS_SVNACTION_SENDMAIL_START), CColors::Modified);
56 CString error;
57 if (SendMail(FromName, FromMail, To, CC, subject, body, attachments, &error) == 0)
58 return 0;
60 instance->ReportError(error);
62 if (instance->IsCancelled() == FALSE) // do not retry/sleep if the user already canceled
64 ++retry;
65 if (retry < 3)
67 CString temp;
68 temp.LoadString(IDS_SVNACTION_SENDMAIL_RETRY);
69 instance->ReportNotification(temp);
70 Sleep(2000);
74 return -1;
77 int CSendMail::SendMail(const CString& FromName, const CString& FromMail, const CString& To, const CString& CC, const CString& subject, const CString& body, CStringArray &attachments, CString *errortext)
79 if (CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\SendMail\\DeliveryType", SEND_MAIL_MAPI) == SEND_MAIL_MAPI)
81 CMailMsg mapiSender;
82 BOOL bMAPIInit = mapiSender.MAPIInitialize();
83 if (!bMAPIInit)
85 if (errortext)
86 *errortext = mapiSender.GetLastErrorMsg();
87 return -1;
90 mapiSender.SetShowComposeDialog(TRUE);
91 mapiSender.SetFrom(FromMail, FromName);
92 mapiSender.SetTo(To);
93 if (!CC.IsEmpty())
94 mapiSender.SetCC(CC);
95 mapiSender.SetSubject(subject);
96 mapiSender.SetMessage(body);
97 for (int i = 0; i < attachments.GetSize(); ++i)
98 mapiSender.AddAttachment(attachments[i]);
100 BOOL bSend = mapiSender.Send();
101 if (bSend == TRUE)
102 return 0;
103 else
105 if (errortext)
106 *errortext = mapiSender.GetLastErrorMsg();
107 return -1;
110 else
112 CString sender;
113 sender.Format(L"%s <%s>", static_cast<LPCWSTR>(CHwSMTP::GetEncodedHeader(FromName)), static_cast<LPCWSTR>(FromMail));
115 CHwSMTP mail;
116 if (CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\SendMail\\DeliveryType", SEND_MAIL_SMTP_CONFIGURED) == SEND_MAIL_SMTP_CONFIGURED)
118 CString recipients(To);
119 if (!CC.IsEmpty())
120 recipients += L";" + CC;
121 CCredentials credentials;
122 CWindowsCredentialsStore::GetCredential(L"TortoiseGit:SMTP-Credentials", credentials);
123 if (mail.SendEmail(static_cast<CString>(CRegString(L"Software\\TortoiseGit\\TortoiseProc\\SendMail\\Address", L"")), &credentials, static_cast<BOOL>(CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\SendMail\\AuthenticationRequired", FALSE)), sender, recipients, subject, body, &attachments, CC, static_cast<DWORD>(CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\SendMail\\Port", 25)), sender, To, static_cast<DWORD>(CRegDWORD(L"Software\\TortoiseGit\\TortoiseProc\\SendMail\\Encryption", 0))) == TRUE)
124 return 0;
125 else
127 if (errortext)
128 *errortext = mail.GetLastErrorText();
129 return -1;
132 else if (mail.SendSpeedEmail(sender, To, subject, body, &attachments, CC, sender))
133 return 0;
134 else
136 if (errortext)
137 *errortext = mail.GetLastErrorText();
138 return -1;
143 CSendMailCombineable::CSendMailCombineable(const CString& To, const CString& CC, const CString& subject, bool bAttachment, bool bCombine)
144 : CSendMail(To, CC, bAttachment)
145 , m_sSubject(subject)
146 , m_bCombine(bCombine)
150 CSendMailCombineable::~CSendMailCombineable()
154 int CSendMailCombineable::Send(const CTGitPathList& list, CGitProgressList* instance)
156 if (m_bCombine)
157 return SendAsCombinedMail(list, instance);
158 else
160 instance->SetItemCountTotal(list.GetCount() + 1);
161 for (int i = 0; i < list.GetCount(); ++i)
163 instance->SetItemProgress(i);
164 if (SendAsSingleMail(list[i], instance))
165 return -1;
167 instance->SetItemProgress(list.GetCount() + 1);
170 return 0;
173 int GetFileContents(CString &filename, CString &content)
175 CStdioFile file;
176 if (file.Open(filename, CFile::modeRead))
178 CString str;
179 while (file.ReadString(str))
181 content += str;
182 str.Empty();
183 content += L"\r\n";
185 return 0;
187 else
188 return -1;
191 int CSendMailCombineable::SendAsSingleMail(const CTGitPath& path, CGitProgressList* instance)
193 ASSERT(instance);
195 CString pathfile(path.GetWinPathString());
197 CString body;
198 CStringArray attachments;
199 if (m_bAttachment)
200 attachments.Add(pathfile);
201 else if (GetFileContents(pathfile, body))
203 instance->ReportError(L"Could not open " + pathfile);
204 return -2;
207 return SendMail(path, instance, m_sSenderName, m_sSenderMail, m_sTo, m_sCC, m_sSubject, body, attachments);
210 int CSendMailCombineable::SendAsCombinedMail(const CTGitPathList &list, CGitProgressList* instance)
212 ASSERT(instance);
214 CStringArray attachments;
215 CString body;
216 for (int i = 0; i < list.GetCount(); ++i)
218 if (m_bAttachment)
219 attachments.Add(list[i].GetWinPathString());
220 else
222 CString filename(list[i].GetWinPathString());
223 body += filename + L":\n";
224 if (GetFileContents(filename, body))
226 instance->ReportError(L"Could not open " + filename);
227 return -2;
229 body += L'\n';
232 return SendMail(CTGitPath(), instance, m_sSenderName, m_sSenderMail, m_sTo, m_sCC, m_sSubject, body, attachments);