416 lines
12 KiB
C++
Executable File
416 lines
12 KiB
C++
Executable File
#include "wxinc.h"
|
|
#include "xvt.h"
|
|
|
|
#include "smapi.h"
|
|
#include <wx/tokenzr.h>
|
|
#include <wx/file.h>
|
|
#include <wx/filename.h>
|
|
#include <wx/mimetype.h>
|
|
#include <fstream>
|
|
|
|
static wxString GetMailParam(const char* key, const char* def = "")
|
|
{
|
|
static wxString ini; // C:\campo\dati\config\user.ini
|
|
|
|
if (ini.IsEmpty())
|
|
{
|
|
wxString cu = "ADMIN";
|
|
for (int i = __argc-1; i > 1; i--)
|
|
{
|
|
wxString u = __argv[i]; u.MakeUpper();
|
|
if (u.StartsWith("/U") || u.StartsWith("-U"))
|
|
{
|
|
cu = u.Mid(2);
|
|
break;
|
|
}
|
|
}
|
|
|
|
char study[_MAX_PATH]; xvt_sys_get_profile_string(NULL, "Main", "Study", "", study, sizeof(study));
|
|
ini = study;
|
|
if (!wxEndsWithPathSeparator(ini))
|
|
ini += wxFILE_SEP_PATH;
|
|
ini += "config\\"; ini += cu; ini += ".ini";
|
|
}
|
|
wxString val; const size_t sz = _MAX_PATH;
|
|
xvt_sys_get_profile_string(ini, "Mail", key, def, val.GetWriteBuf(sz), sz);
|
|
val.UngetWriteBuf();
|
|
return val;
|
|
}
|
|
|
|
static bool GetMailParams(wxString& smtp, wxString& port, wxString& user, wxString& pass, wxString& from)
|
|
{
|
|
smtp = GetMailParam("Server", "MAPI");
|
|
port = GetMailParam("Port");
|
|
user = GetMailParam("User");
|
|
pass = GetMailParam("Password");
|
|
wxString f = user;
|
|
if (f.find('@') < 0)
|
|
{ f += "@"; f += smtp.AfterFirst('.'); }
|
|
from = GetMailParam("From", f);
|
|
|
|
return !smtp.IsEmpty() && !pass.IsEmpty();
|
|
}
|
|
|
|
static bool has_power_mail()
|
|
{
|
|
return GetMailParam("Powershell") == "X";
|
|
}
|
|
|
|
short xvt_mail_installed()
|
|
{
|
|
short bInstalled = 0;
|
|
|
|
if (::GetProfileInt(_T("MAIL"), _T("MAPI"), 0) != 0 &&
|
|
SearchPath(NULL, _T("MAPI32.DLL"), NULL, 0, NULL, NULL) != 0)
|
|
bInstalled |= 0x1;
|
|
|
|
if (xvt_fsys_file_exists("servers/mailsend.exe") || has_power_mail())
|
|
{
|
|
wxString smtp, port, user, pass, from;
|
|
GetMailParams(smtp, port, user, pass, from);
|
|
if (!pass.IsEmpty() && smtp != "MAPI")
|
|
bInstalled |= 0x2;
|
|
}
|
|
|
|
return bInstalled;
|
|
}
|
|
|
|
static void AppendQuotedString(wxString& cmd, const char* key, const wxString& value)
|
|
{
|
|
if (!value.IsEmpty())
|
|
cmd << " -" << key << " \"" << value << "\"";
|
|
}
|
|
|
|
static void AppendAttachment(wxString& cmd, const wxString& fname, bool att = true)
|
|
{
|
|
if (wxFileName::FileExists(fname))
|
|
{
|
|
char ext[_MAX_EXT] = { 0 };
|
|
xvt_fsys_parse_pathname (fname, NULL, NULL, NULL, ext, NULL);
|
|
wxString mime = ext;
|
|
wxFileType* ft = wxTheMimeTypesManager->GetFileTypeFromExtension(mime);
|
|
if (ft != NULL)
|
|
{
|
|
wxArrayString aMime;
|
|
if (ft->GetMimeTypes(aMime))
|
|
mime = aMime[0];
|
|
}
|
|
|
|
if (att)
|
|
{
|
|
wxString a; a << fname << "," << mime << ",a";
|
|
AppendQuotedString(cmd, "attach", a);
|
|
}
|
|
else
|
|
{
|
|
wxString a; a << fname << "," << mime << ",i";
|
|
AppendQuotedString(cmd, "attach", a);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN xvt_mail_send(const char* to, const char* cc, const char* ccn,
|
|
const char* subject, const char* msg,
|
|
const char* attach, short flags)
|
|
{
|
|
bool ui = (flags & 0x1) != 0;
|
|
|
|
wxStringTokenizer tokTo(to, _T(";"));
|
|
wxMailMessage Msg(subject, tokTo.GetNextToken(), msg);
|
|
|
|
if (flags & 0x2)
|
|
Msg.m_query_receipt = true;
|
|
|
|
while (tokTo.HasMoreTokens())
|
|
Msg.AddTo(tokTo.GetNextToken());
|
|
if (Msg.m_to[0].IsEmpty())
|
|
{
|
|
Msg.m_to[0] = " "; // Il destinatario "" fa piantare MAPI con errore 25
|
|
ui = true; // Forza user interface in assenza di recipient
|
|
}
|
|
|
|
if (attach && *attach)
|
|
{
|
|
wxStringTokenizer tokAttach(attach, _T(";"));
|
|
while (tokAttach.HasMoreTokens())
|
|
Msg.AddAttachment(tokAttach.GetNextToken());
|
|
}
|
|
|
|
if (cc && *cc)
|
|
{
|
|
wxStringTokenizer Tok(cc, _T(";"));
|
|
while (Tok.HasMoreTokens())
|
|
Msg.AddCc(Tok.GetNextToken());
|
|
}
|
|
|
|
if (ccn && *ccn)
|
|
{
|
|
wxStringTokenizer Tok(ccn, _T(";"));
|
|
while (Tok.HasMoreTokens())
|
|
Msg.AddBcc(Tok.GetNextToken());
|
|
}
|
|
|
|
const short mail_inst = xvt_mail_installed();
|
|
|
|
BOOLEAN ok = FALSE;
|
|
|
|
wxString server, port, user, password, from;
|
|
if ((mail_inst & 0x2) && GetMailParams(server, port, user, password, from))
|
|
{
|
|
wxString cmd = "servers/mailsend.exe";
|
|
AppendQuotedString(cmd, "smtp", server);
|
|
if (!port.IsEmpty())
|
|
{
|
|
cmd += " -port ";
|
|
cmd += port;
|
|
}
|
|
AppendQuotedString(cmd, "from", from);
|
|
|
|
if ((flags | 0x2) && from.Find("@") > 0)
|
|
{
|
|
//AppendQuotedString(cmd, "rt", from);
|
|
AppendQuotedString(cmd, "rrr", from);
|
|
}
|
|
|
|
// Lista dei destinatari
|
|
for (size_t i = 0; i < Msg.m_to.size(); i++)
|
|
AppendQuotedString(cmd, "to", Msg.m_to[i]);
|
|
|
|
// Lista dei destinatari in copia
|
|
for (size_t i = 0; i < Msg.m_cc.size(); i++)
|
|
AppendQuotedString(cmd, "cc", Msg.m_cc[i]);
|
|
if (cmd.Find("-cc") < 0)
|
|
cmd += " +cc"; // In assenza di destinatari in copia aggiungo +cc
|
|
|
|
// Lista dei destinatari in copia nascosta
|
|
for (size_t i = 0; i < Msg.m_bcc.size(); i++)
|
|
AppendQuotedString(cmd, "bc", Msg.m_bcc[i]);
|
|
if (from.Find("@") > 0)
|
|
{
|
|
wxString strMyself; strMyself << "c " << from;
|
|
if (cmd.Find(strMyself) < 0)
|
|
AppendQuotedString(cmd, "bc", from); // Aggiungo me stesso ai destinatari nascosti
|
|
}
|
|
if (cmd.Find("-bc") < 0)
|
|
cmd += " +bc"; // In assenza di destinatari nascosti aggiungo +bc
|
|
|
|
AppendQuotedString(cmd, "sub", Msg.m_subject);
|
|
AppendQuotedString(cmd, "user", user);
|
|
AppendQuotedString(cmd, "pass", password);
|
|
|
|
AppendQuotedString(cmd, "enc-type", "base64");
|
|
|
|
if (!Msg.m_attachments.IsEmpty())
|
|
{
|
|
for (size_t a = 0; a < Msg.m_attachments.size(); a++)
|
|
{
|
|
const wxString& fn = Msg.m_attachments[a];
|
|
if (wxFileName::FileExists(fn))
|
|
AppendAttachment(cmd, fn);
|
|
}
|
|
}
|
|
|
|
wxString ftmp;
|
|
if (Msg.m_body.IsEmpty())
|
|
{
|
|
if (cmd.Find("-M ") < 0)
|
|
{
|
|
wxString m; m << "Cordiali saluti\n" << from;
|
|
m.Trim();
|
|
AppendQuotedString(cmd, "M", m);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wxStringTokenizer tok(Msg.m_body, "\n");
|
|
Msg.m_body.Trim();
|
|
if (Msg.m_body.Find("\n") < 0)
|
|
AppendQuotedString(cmd, "M", Msg.m_body);
|
|
else
|
|
{
|
|
DIRECTORY tmp; xvt_fsys_get_temp_dir(&tmp);
|
|
xvt_fsys_build_pathname(ftmp.GetWriteBuf(_MAX_PATH), NULL, tmp.path, "msgbody", "html", NULL);
|
|
ftmp.UngetWriteBuf();
|
|
wxFile file(ftmp, wxFile::write);
|
|
file.Write("<html><body>\n");
|
|
Msg.m_body.Replace("\n", "<br>");
|
|
file.Write(Msg.m_body);
|
|
file.Write("\n</body><html>\n");
|
|
file.Close();
|
|
AppendAttachment(cmd, ftmp, false);
|
|
}
|
|
}
|
|
|
|
const wxString strLog = "mailsend.log";
|
|
xvt_fsys_remove_file(strLog);
|
|
AppendQuotedString(cmd, "log", strLog);
|
|
|
|
int nRetry = wxAtoi(GetMailParam("Retry", "2"));
|
|
if (nRetry <= 0) nRetry = 2;
|
|
|
|
ok = FALSE;
|
|
for (int r = 0; r < nRetry && !ok; r++)
|
|
{
|
|
if (r > 0)
|
|
{
|
|
const int nSeconds = 5*r;
|
|
WINDOW w = xvt_dm_progress_create(TASK_WIN, "MailSend retrying...", nSeconds, TRUE);
|
|
for (int s = 1; s <= nSeconds; s++)
|
|
{
|
|
xvt_sys_sleep(1000);
|
|
xvt_dm_progress_set_status(w, s, nSeconds);
|
|
}
|
|
xvt_dm_progress_destroy(w);
|
|
}
|
|
wxExecute(cmd, wxEXEC_SYNC);
|
|
wxFile fLog(strLog, wxFile::read);
|
|
const wxFileOffset flen = fLog.Length();
|
|
if (flen > 0)
|
|
{
|
|
char* buff = (char*)calloc(flen+8, 1); // zero filled buffer
|
|
fLog.Read(buff, flen);
|
|
if (wxStrstr(buff, "Mail sent successfully"))
|
|
ok = TRUE;
|
|
delete [] buff;
|
|
}
|
|
}
|
|
} else
|
|
if (mail_inst & 1)
|
|
{
|
|
xvt_fsys_save_dir();
|
|
ok = Msg.Send(wxEmptyString, ui);
|
|
xvt_fsys_restore_dir();
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_powermail_send(const char* to, const char* cc, const char* ccn,
|
|
const char* subject, const char* msg,
|
|
const char* attach, short flags, const char* usr)
|
|
{
|
|
wxString server, port, user, password, from;
|
|
// Controllo che Windows sia almeno 8 e che riesca a ricevere i parametri E-mail
|
|
if(xvt_sys_get_os_version() < XVT_WS_WIN_7 || !GetMailParams(server, port, user, password, from))
|
|
xvt_mail_send(to, cc, ccn, subject, msg, attach, flags);
|
|
|
|
DIRECTORY tmp; xvt_fsys_get_temp_dir(&tmp);
|
|
// Per togliere il rischio di sovrapposizioni vado nella cartella dell'utente
|
|
wxString userTemp; userTemp << tmp.path << "\\" << usr;
|
|
|
|
wxString powerFile;
|
|
static int powerNumber = 0;
|
|
wxString powerName = "powermail_"; powerName << ++powerNumber;
|
|
xvt_fsys_build_pathname(powerFile.GetWriteBuf(_MAX_PATH), NULL, userTemp, powerName, "ps1", NULL);
|
|
powerFile.UngetWriteBuf();
|
|
|
|
// Creo il file
|
|
wxFile file(powerFile, wxFile::write);
|
|
|
|
// Parsing port tokens
|
|
/* Token dictionary (all case insensitive):
|
|
* 465/587/... port
|
|
* -SSL Enable ssl/tls
|
|
* -nbcc No Blind Carbon Copy
|
|
*/
|
|
wxStringTokenizer portTok(port, " ");
|
|
wxString port_number;
|
|
bool ssl = false, bcc = true;
|
|
|
|
while(portTok.HasMoreTokens())
|
|
{
|
|
wxString tok = portTok.GetNextToken();
|
|
if (tok[0] >= '0' && tok[0] <= '9')
|
|
port_number = tok;
|
|
if (tok.Upper() == "-SSL")
|
|
ssl = true;
|
|
if (tok.Upper() == "-NBCC")
|
|
bcc = false;
|
|
}
|
|
|
|
// Hard code and no play makes Tolla a dull programmer
|
|
file.Write("$Server = \""); file.Write(server); file.Write("\";\n");
|
|
|
|
file.Write("$Port = \""); file.Write(port_number); file.Write("\";\n");
|
|
file.Write("$SSL = ");
|
|
|
|
if(ssl)
|
|
file.Write("$true");
|
|
else
|
|
file.Write("$false");
|
|
|
|
file.Write("\n");
|
|
file.Write("$Username = \""); file.Write(user); file.Write("\";\n");
|
|
file.Write("$Password = \""); file.Write(password); file.Write("\";\n");
|
|
file.Write("$From = \""); file.Write(from); file.Write("\";\n");
|
|
file.Write("$To = \""); file.Write(to); file.Write("\";\n");
|
|
file.Write("$Subject = \""); file.Write(subject); file.Write("\";\n");
|
|
file.Write("$Body = \""); file.Write(msg); file.Write("\";\n");
|
|
file.Write(
|
|
"$message = new-object Net.Mail.MailMessage;\n"
|
|
"$message.From = $From\n"
|
|
"$message.To.Add($To);\n");
|
|
|
|
if (bcc)
|
|
file.Write("$message.Bcc.Add($From);\n");
|
|
|
|
file.Write(
|
|
"$message.Subject = $Subject;\n"
|
|
"$message.Body = $Body;\n"
|
|
);
|
|
|
|
// Aggiungo a schiena gli allegati
|
|
if (attach && *attach)
|
|
{
|
|
wxStringTokenizer tokAttach(attach, _T(";"));
|
|
int i = 0;
|
|
while (tokAttach.HasMoreTokens())
|
|
{
|
|
wxString attachmentLine;
|
|
attachmentLine << "$attach" << ++i << "= New-Object Net.Mail.Attachment(\""
|
|
<< tokAttach.GetNextToken() << "\");\n" << "$message.Attachments.Add("
|
|
<< "$attach" << i << ");\n";
|
|
file.Write(attachmentLine);
|
|
}
|
|
}
|
|
|
|
file.Write(
|
|
"$smtp = new-object Net.Mail.SmtpClient($Server, $Port);\n"
|
|
"$smtp.EnableSSL = $SSL;\n"
|
|
"$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);\n"
|
|
"$exitCode = 1\n"
|
|
"try\n"
|
|
"{\n"
|
|
" $smtp.send($message);\n"
|
|
" write-host \"E-Mail sent\" ; \n"
|
|
" exit 1\n"
|
|
"}\n"
|
|
"catch\n"
|
|
"{\n"
|
|
" write-host \"E-Mail not sent\" ; \n"
|
|
" $exitCode = 0\n"
|
|
"}\n"
|
|
"$host.SetShouldExit($exitCode);\n"
|
|
);
|
|
file.Close();
|
|
|
|
wxString command;
|
|
command << R"(PowerShell -ExecutionPolicy ByPass -NonInteractive -NoProfile -Command "&{)" << powerFile << R"(; exit $LastExitCode }")";
|
|
|
|
BOOLEAN sys_command = (BOOLEAN)system(command);
|
|
if (!sys_command)
|
|
{
|
|
std::ofstream fout;
|
|
wxString error_file;
|
|
error_file << userTemp << "\\" << "error_mail.txt";
|
|
fout.open(error_file, std::ios_base::out);
|
|
if (fout.is_open())
|
|
{
|
|
fout << command << "\n";
|
|
fout.close();
|
|
}
|
|
}
|
|
return sys_command;
|
|
}
|