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