1 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
2
3 This file is part of the Trojita Qt IMAP e-mail client,
4 http://trojita.flaska.net/
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of
9 the License or (at your option) version 3 or any later version
10 accepted by the membership of KDE e.V. (or its successor approved
11 by the membership of KDE e.V.), which shall act as a proxy
12 defined in Section 14 of version 3 of the license.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "Sendmail.h"
23
24 namespace MSA
25 {
26
Sendmail(QObject * parent,const QString & command,const QStringList & args)27 Sendmail::Sendmail(QObject *parent, const QString &command, const QStringList &args):
28 AbstractMSA(parent), command(command), args(args)
29 {
30 proc = new QProcess(this);
31 connect(proc, &QProcess::started, this, &Sendmail::handleStarted);
32 connect(proc, static_cast<void (QProcess::*)(int)>(&QProcess::finished), this, &Sendmail::handleFinished);
33 connect(proc, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), this, &Sendmail::handleError);
34 connect(proc, &QIODevice::bytesWritten, this, &Sendmail::handleBytesWritten);
35 }
36
~Sendmail()37 Sendmail::~Sendmail()
38 {
39 proc->kill();
40 proc->waitForFinished();
41 }
42
sendMail(const QByteArray & from,const QList<QByteArray> & to,const QByteArray & data)43 void Sendmail::sendMail(const QByteArray &from, const QList<QByteArray> &to, const QByteArray &data)
44 {
45 // first +1 for the process startup
46 // second +1 for waiting for the result
47 emit progressMax(data.size() + 2);
48 emit progress(0);
49 QStringList myArgs = args;
50 myArgs << QStringLiteral("-f") << QString::fromUtf8(from);
51 for (QList<QByteArray>::const_iterator it = to.begin(); it != to.end(); ++it) {
52 // On posix systems, process args are bytearrays, not strings--- but QProcess
53 // takes strings.
54 myArgs << QString::fromUtf8(*it);
55 }
56 writtenSoFar = 0;
57 emit connecting();
58 proc->start(command, myArgs);
59 dataToSend = data;
60 }
61
cancel()62 void Sendmail::cancel()
63 {
64 proc->terminate();
65 }
66
handleStarted()67 void Sendmail::handleStarted()
68 {
69 // The process has started already -> +1
70 emit progress(1);
71
72 emit sending();
73 proc->write(dataToSend);
74 proc->closeWriteChannel();
75 }
76
handleError(QProcess::ProcessError e)77 void Sendmail::handleError(QProcess::ProcessError e)
78 {
79 Q_UNUSED(e);
80 emit error(tr("The sendmail process has failed: %1").arg(proc->errorString()));
81 }
82
handleBytesWritten(qint64 bytes)83 void Sendmail::handleBytesWritten(qint64 bytes)
84 {
85 writtenSoFar += bytes;
86 // +1 due to starting at one
87 emit progress(writtenSoFar + 1);
88 }
89
handleFinished(const int exitCode)90 void Sendmail::handleFinished(const int exitCode)
91 {
92 // that's the last one
93 emit progressMax(dataToSend.size() + 2);
94
95 if (exitCode == 0) {
96 emit sent();
97 return;
98 }
99
100 QByteArray allStdout = proc->readAllStandardOutput();
101 QByteArray allStderr = proc->readAllStandardError();
102 emit error(tr("The sendmail process has failed (%1):\n%2\n%3").arg(QString::number(exitCode), QString::fromUtf8(allStdout),
103 QString::fromUtf8(allStderr)));
104 }
105
SendmailFactory(const QString & command,const QStringList & args)106 SendmailFactory::SendmailFactory(const QString &command, const QStringList &args):
107 m_command(command), m_args(args)
108 {
109 }
110
~SendmailFactory()111 SendmailFactory::~SendmailFactory()
112 {
113 }
114
create(QObject * parent) const115 AbstractMSA *SendmailFactory::create(QObject *parent) const
116 {
117 return new Sendmail(parent, m_command, m_args);
118 }
119
120 }
121