Make sure buffer is large enough for the nul terminator
[TortoiseGit.git] / src / TortoiseProc / SendMail.cpp
blob5fcda390eda5e464e443528ee2d6d8c12ae327e4
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013, 2015 - 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"
26 class CAppUtils;
28 CSendMail::CSendMail(CString &To, 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;
37 CSendMail::~CSendMail(void)
41 int CSendMail::SendMail(const CTGitPath &item, CGitProgressList * instance, CString &FromName, CString &FromMail, CString &To, CString &CC, CString &subject, CString &body, CStringArray &attachments)
43 ASSERT(instance);
44 int retry = 0;
45 while (retry < 3)
47 if (instance->IsCancelled() == TRUE)
49 instance->ReportUserCanceled();
50 return -1;
53 instance->AddNotify(new CGitProgressList::NotificationData(item, IDS_SVNACTION_SENDMAIL_START), CColors::Modified);
55 CString error;
56 if (SendMail(FromName, FromMail, To, CC, subject, body, attachments, &error) == 0)
57 return 0;
59 instance->ReportError(error);
61 if (instance->IsCancelled() == FALSE) // do not retry/sleep if the user already canceled
63 ++retry;
64 if (retry < 3)
66 CString temp;
67 temp.LoadString(IDS_SVNACTION_SENDMAIL_RETRY);
68 instance->ReportNotification(temp);
69 Sleep(2000);
73 return -1;
76 int CSendMail::SendMail(CString &FromName, CString &FromMail, CString &To, CString &CC, CString &subject, CString &body, CStringArray &attachments, CString *errortext)
78 if (CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\DeliveryType"), 1) == 1)
80 CMailMsg mapiSender;
81 BOOL bMAPIInit = mapiSender.MAPIInitialize();
82 if (!bMAPIInit)
84 if (errortext)
85 *errortext = mapiSender.GetLastErrorMsg();
86 return -1;
89 mapiSender.SetShowComposeDialog(TRUE);
90 mapiSender.SetFrom(FromMail, FromName);
91 mapiSender.SetTo(To);
92 if (!CC.IsEmpty())
93 mapiSender.SetCC(CC);
94 mapiSender.SetSubject(subject);
95 mapiSender.SetMessage(body);
96 for (int i = 0; i < attachments.GetSize(); ++i)
97 mapiSender.AddAttachment(attachments[i]);
99 BOOL bSend = mapiSender.Send();
100 if (bSend == TRUE)
101 return 0;
102 else
104 if (errortext)
105 *errortext = mapiSender.GetLastErrorMsg();
106 return -1;
109 else
111 CString sender;
112 sender.Format(_T("%s <%s>"), FromName, FromMail);
114 CHwSMTP mail;
115 if (CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\DeliveryType"), 2) == 2)
117 CString recipients(To);
118 if (!CC.IsEmpty())
119 recipients += L";" + CC;
120 if (mail.SendEmail((CString)CRegString(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\Address"), _T("")), (CString)CRegString(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\Username"), _T("")), (CString)CRegString(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\Password"), _T("")), (BOOL)CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\AuthenticationRequired"), FALSE), sender, recipients, subject, body, nullptr, &attachments, CC, (DWORD)CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\Port"), 25), sender, To, (DWORD)CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\Encryption"), 0)) == TRUE)
121 return 0;
122 else
124 if (errortext)
125 *errortext = mail.GetLastErrorText();
126 return -1;
129 else if (mail.SendSpeedEmail(sender, To, subject, body, nullptr, &attachments, CC, sender))
130 return 0;
131 else
133 if (errortext)
134 *errortext = mail.GetLastErrorText();
135 return -1;
140 CSendMailCombineable::CSendMailCombineable(CString &To, CString &CC, CString &subject, bool bAttachment, bool bCombine)
141 : CSendMail(To, CC, bAttachment)
142 , m_sSubject(subject)
143 , m_bCombine(bCombine)
147 CSendMailCombineable::~CSendMailCombineable()
151 int CSendMailCombineable::Send(CTGitPathList &list, CGitProgressList * instance)
153 if (m_bCombine)
155 return SendAsCombinedMail(list, instance);
157 else
159 instance->SetItemCountTotal(list.GetCount() + 1);
160 for (int i = 0; i < list.GetCount(); ++i)
162 instance->SetItemProgress(i);
163 if (SendAsSingleMail((CTGitPath &)list[i], instance))
164 return -1;
166 instance->SetItemProgress(list.GetCount() + 1);
169 return 0;
172 int GetFileContents(CString &filename, CString &content)
174 CStdioFile file;
175 if (file.Open(filename, CFile::modeRead))
177 CString str;
178 while (file.ReadString(str))
180 content += str;
181 str.Empty();
182 content += _T("\n");
184 return 0;
186 else
187 return -1;
190 int CSendMailCombineable::SendAsSingleMail(CTGitPath &path, CGitProgressList * instance)
192 ASSERT(instance);
194 CString pathfile(path.GetWinPathString());
196 CString body;
197 CStringArray attachments;
198 if (m_bAttachment)
199 attachments.Add(pathfile);
200 else if (GetFileContents(pathfile, body))
202 instance->ReportError(_T("Could not open ") + pathfile);
203 return -2;
206 return SendMail(path, instance, m_sSenderName, m_sSenderMail, m_sTo, m_sCC, m_sSubject, body, attachments);
209 int CSendMailCombineable::SendAsCombinedMail(CTGitPathList &list, CGitProgressList * instance)
211 ASSERT(instance);
213 CStringArray attachments;
214 CString body;
215 for (int i = 0; i < list.GetCount(); ++i)
217 if (m_bAttachment)
219 attachments.Add(list[i].GetWinPathString());
221 else
223 CString filename(list[i].GetWinPathString());
224 body += filename + _T(":\n");
225 if (GetFileContents(filename, body))
227 instance->ReportError(_T("Could not open ") + filename);
228 return -2;
230 body += _T("\n");
233 return SendMail(CTGitPath(), instance, m_sSenderName, m_sSenderMail, m_sTo, m_sCC, m_sSubject, body, attachments);