[kde-doc-english] [kdepimlibs] kioslave: Move in kmailtransport
Montel Laurent
montel at kde.org
Sun Apr 3 09:20:47 UTC 2016
Git commit e3de1cd898629152863db943d3c844c955fba763 by Montel Laurent.
Committed on 03/04/2016 at 09:20.
Pushed by mlaurent into branch 'master'.
Move in kmailtransport
M +0 -1 kioslave/docs/CMakeLists.txt
D +0 -3 kioslave/docs/smtp/CMakeLists.txt
D +0 -23 kioslave/docs/smtp/index.docbook
M +0 -1 kioslave/src/CMakeLists.txt
D +0 -44 kioslave/src/smtp/CMakeLists.txt
D +0 -2 kioslave/src/smtp/Messages.sh
D +0 -11 kioslave/src/smtp/TODO
D +0 -124 kioslave/src/smtp/capabilities.cpp
D +0 -87 kioslave/src/smtp/capabilities.h
D +0 -653 kioslave/src/smtp/command.cpp
D +0 -331 kioslave/src/smtp/command.h
D +0 -33 kioslave/src/smtp/compliance.txt
D +0 -88 kioslave/src/smtp/kioslavesession.cpp
D +0 -52 kioslave/src/smtp/kioslavesession.h
D +0 -196 kioslave/src/smtp/request.cpp
D +0 -180 kioslave/src/smtp/request.h
D +0 -169 kioslave/src/smtp/response.cpp
D +0 -173 kioslave/src/smtp/response.h
D +0 -654 kioslave/src/smtp/smtp.cpp
D +0 -126 kioslave/src/smtp/smtp.h
D +0 -16 kioslave/src/smtp/smtp.protocol
D +0 -16 kioslave/src/smtp/smtps.protocol
D +0 -61 kioslave/src/smtp/smtpsessioninterface.cpp
D +0 -96 kioslave/src/smtp/smtpsessioninterface.h
D +0 -67 kioslave/src/smtp/tests/CMakeLists.txt
D +0 -120 kioslave/src/smtp/tests/fakesession.h
D +0 -206 kioslave/src/smtp/tests/interactivesmtpserver.cpp
D +0 -81 kioslave/src/smtp/tests/interactivesmtpserver.h
D +0 -83 kioslave/src/smtp/tests/requesttest.cpp
D +0 -35 kioslave/src/smtp/tests/requesttest.h
D +0 -26 kioslave/src/smtp/tests/test_capabilities.cpp
D +0 -677 kioslave/src/smtp/tests/test_commands.cpp
D +0 -90 kioslave/src/smtp/tests/test_headergeneration.cpp
D +0 -106 kioslave/src/smtp/tests/test_responseparser.cpp
D +0 -32 kioslave/src/smtp/tests/test_responseparser.h
D +0 -127 kioslave/src/smtp/transactionstate.cpp
D +0 -230 kioslave/src/smtp/transactionstate.h
http://commits.kde.org/kdepimlibs/e3de1cd898629152863db943d3c844c955fba763
diff --git a/kioslave/docs/CMakeLists.txt b/kioslave/docs/CMakeLists.txt
index 987626e..3b660ba 100644
--- a/kioslave/docs/CMakeLists.txt
+++ b/kioslave/docs/CMakeLists.txt
@@ -1,4 +1,3 @@
add_subdirectory(ldap)
add_subdirectory(pop3)
-add_subdirectory(smtp)
add_subdirectory(sieve)
diff --git a/kioslave/docs/smtp/CMakeLists.txt b/kioslave/docs/smtp/CMakeLists.txt
deleted file mode 100644
index 11d31fa..0000000
--- a/kioslave/docs/smtp/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-########### install files ###############
-kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en SUBDIR kioslave5/smtp)
-
diff --git a/kioslave/docs/smtp/index.docbook b/kioslave/docs/smtp/index.docbook
deleted file mode 100644
index 1939851..0000000
--- a/kioslave/docs/smtp/index.docbook
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE article PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN"
-"dtd/kdedbx45.dtd" [
-<!ENTITY % addindex "IGNORE">
-<!ENTITY % English "INCLUDE" > <!-- change language only here -->
-]>
-
-<article lang="&language;" id="smtp">
-<title>smtp</title>
-<articleinfo>
-<authorgroup>
-<author>&Ferdinand.Gassauer; &Ferdinand.Gassauer.mail;</author>
-<!-- TRANS:ROLES_OF_TRANSLATORS -->
-</authorgroup>
-</articleinfo>
-<para>
-A protocol to send mail from the client workstation to the mail server.
-</para>
-
-<para> See : <ulink url="http://cr.yp.to/smtp.html">Simple Mail Transfer Protocol </ulink>.
-</para>
-
-</article>
diff --git a/kioslave/src/CMakeLists.txt b/kioslave/src/CMakeLists.txt
index b630c8f..7811950 100644
--- a/kioslave/src/CMakeLists.txt
+++ b/kioslave/src/CMakeLists.txt
@@ -2,7 +2,6 @@
remove_definitions(-DQT_NO_CAST_FROM_BYTEARRAY)
add_subdirectory(ldap)
add_subdirectory(sieve)
-add_subdirectory(smtp)
add_subdirectory( pop3 )
diff --git a/kioslave/src/smtp/CMakeLists.txt b/kioslave/src/smtp/CMakeLists.txt
deleted file mode 100644
index 3f809a2..0000000
--- a/kioslave/src/smtp/CMakeLists.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-if (BUILD_TESTING)
-add_subdirectory(tests)
-endif()
-set(smtp_optional_includes)
-set(smtp_optional_libs)
-
-if (Sasl2_FOUND)
- set(smtp_optional_includes ${smtp_optional_includes} ${Sasl2_INCLUDE_DIRS})
- set(smtp_optional_libs ${smtp_optional_libs} ${Sasl2_LIBRARIES})
-endif()
-
-
-include_directories( ${smtp_optional_includes} )
-
-
-########### next target ###############
-
-set(kio_smtp_PART_SRCS
- smtp.cpp
- request.cpp
- response.cpp
- capabilities.cpp
- command.cpp
- transactionstate.cpp
- smtpsessioninterface.cpp
- kioslavesession.cpp
-)
-
-ecm_qt_declare_logging_category(kio_smtp_PART_SRCS HEADER smtp_debug.h IDENTIFIER SMTP_LOG CATEGORY_NAME log_smtp)
-
-add_library(kio_smtp MODULE ${kio_smtp_PART_SRCS})
-
-
-target_link_libraries(kio_smtp KF5::KIOCore KF5::I18n Qt5::Network ${smtp_optional_libs})
-set_target_properties(kio_smtp PROPERTIES OUTPUT_NAME "smtp")
-
-install(TARGETS kio_smtp DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kio/ )
-
-########### install files ###############
-
-install( FILES smtp.protocol smtps.protocol DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
-
diff --git a/kioslave/src/smtp/Messages.sh b/kioslave/src/smtp/Messages.sh
deleted file mode 100644
index c0be647..0000000
--- a/kioslave/src/smtp/Messages.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#! /usr/bin/env bash
-$XGETTEXT *.cpp -o $podir/kio_smtp.pot
diff --git a/kioslave/src/smtp/TODO b/kioslave/src/smtp/TODO
deleted file mode 100644
index cad79f1..0000000
--- a/kioslave/src/smtp/TODO
+++ /dev/null
@@ -1,11 +0,0 @@
-1. Double check the error handling and review error message in various
- failure modes.
-2. Implement the CHUNKING extension (rfc 3030; as soon as I find an
- SMTP server that supports it).
-3. Better error message (translated standard meanings of the known
- response codes, ENHANCEDSTATUSCODES extension (rfc2034)).
-4. (KIO) MultiPutJob to support pipelining across messages.
-5. Ged rid of slave's header generation after checking who on earth
- uses that...
-
-and further refactoring to make the code pleasant to look at ;-)
diff --git a/kioslave/src/smtp/capabilities.cpp b/kioslave/src/smtp/capabilities.cpp
deleted file mode 100644
index 061f740..0000000
--- a/kioslave/src/smtp/capabilities.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- c++ -*-
- capabilities.cc
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#include "capabilities.h"
-#include "response.h"
-
-namespace KioSMTP
-{
-
-Capabilities Capabilities::fromResponse(const Response &ehlo)
-{
- Capabilities c;
-
- // first, check whether the response was valid and indicates success:
- if (!ehlo.isOk()
- || ehlo.code() / 10 != 25 // ### restrict to 250 only?
- || ehlo.lines().empty()) {
- return c;
- }
-
- QCStringList l = ehlo.lines();
-
- for (QCStringList::const_iterator it = ++l.constBegin(); it != l.constEnd(); ++it) {
- c.add(QString::fromLatin1(*it));
- }
-
- return c;
-}
-
-void Capabilities::add(const QString &cap, bool replace)
-{
- QStringList tokens = cap.toUpper().split(QLatin1Char(' '));
- if (tokens.empty()) {
- return;
- }
- QString name = tokens.front();
- tokens.pop_front();
- add(name, tokens, replace);
-}
-
-void Capabilities::add(const QString &name, const QStringList &args, bool replace)
-{
- if (replace) {
- mCapabilities[name] = args;
- } else {
- mCapabilities[name] += args;
- }
-}
-
-QString Capabilities::createSpecialResponse(bool tls) const
-{
- QStringList result;
- if (tls) {
- result.push_back(QStringLiteral("STARTTLS"));
- }
- result += saslMethodsQSL();
- if (have("PIPELINING")) {
- result.push_back(QStringLiteral("PIPELINING"));
- }
- if (have("8BITMIME")) {
- result.push_back(QStringLiteral("8BITMIME"));
- }
- if (have("SIZE")) {
- bool ok = false;
- unsigned int size = 0;
- if (!mCapabilities[QStringLiteral("SIZE")].isEmpty()) {
- size = mCapabilities[QStringLiteral("SIZE")].front().toUInt(&ok);
- }
- if (ok && !size) {
- result.push_back(QStringLiteral("SIZE=*")); // any size
- } else if (ok) {
- result.push_back(QStringLiteral("SIZE=%1").arg(size)); // fixed max
- } else {
- result.push_back(QStringLiteral("SIZE")); // indetermined
- }
- }
- return result.join(QStringLiteral(" "));
-}
-
-QStringList Capabilities::saslMethodsQSL() const
-{
- QStringList result;
- for (QMap<QString, QStringList>::const_iterator it = mCapabilities.begin();
- it != mCapabilities.end(); ++it) {
- if (it.key() == QLatin1String("AUTH")) {
- result += it.value();
- } else if (it.key().startsWith(QLatin1String("AUTH="))) {
- result.push_back(it.key().mid(qstrlen("AUTH=")));
- result += it.value();
- }
- }
- result.removeDuplicates();
- return result;
-}
-
-} // namespace KioSMTP
diff --git a/kioslave/src/smtp/capabilities.h b/kioslave/src/smtp/capabilities.h
deleted file mode 100644
index b501c95..0000000
--- a/kioslave/src/smtp/capabilities.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- c++ -*-
- capabilities.h
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#ifndef __KIOSMTP_CAPABILITIES_H__
-#define __KIOSMTP_CAPABILITIES_H__
-
-#include <QMap>
-
-#include <QStringList>
-
-namespace KioSMTP
-{
-
-class Response;
-
-class Capabilities
-{
-public:
- Capabilities()
- {
- }
-
- static Capabilities fromResponse(const Response &response);
-
- void add(const QString &cap, bool replace = false);
- void add(const QString &name, const QStringList &args, bool replace = false);
- void clear()
- {
- mCapabilities.clear();
- }
-
- bool have(const QString &cap) const
- {
- return mCapabilities.find(cap.toUpper()) != mCapabilities.end();
- }
- bool have(const QByteArray &cap) const
- {
- return have(QString::fromLatin1(cap));
- }
- bool have(const char *cap) const
- {
- return have(QString::fromLatin1(cap));
- }
-
- QString asMetaDataString() const;
-
- QString authMethodMetaData() const;
-
- QString createSpecialResponse(bool tls) const;
-
- QStringList saslMethodsQSL() const;
-private:
-
- QMap<QString, QStringList> mCapabilities;
-};
-
-} // namespace KioSMTP
-
-#endif // __KIOSMTP_CAPABILITIES_H__
diff --git a/kioslave/src/smtp/command.cpp b/kioslave/src/smtp/command.cpp
deleted file mode 100644
index 410f3b3..0000000
--- a/kioslave/src/smtp/command.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/* -*- c++ -*-
- command.cc
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#include "command.h"
-#include "smtp_debug.h"
-
-#include "smtpsessioninterface.h"
-#include "response.h"
-#include "transactionstate.h"
-
-#include <KLocalizedString>
-#include <kio/slavebase.h> // for test_commands, where SMTPProtocol is not derived from TCPSlaveBase
-
-#include <QtCore/QUrl>
-
-#include <assert.h>
-
-namespace KioSMTP
-{
-
-static const sasl_callback_t callbacks[] = {
- { SASL_CB_ECHOPROMPT, NULL, NULL },
- { SASL_CB_NOECHOPROMPT, NULL, NULL },
- { SASL_CB_GETREALM, NULL, NULL },
- { SASL_CB_USER, NULL, NULL },
- { SASL_CB_AUTHNAME, NULL, NULL },
- { SASL_CB_PASS, NULL, NULL },
- { SASL_CB_CANON_USER, NULL, NULL },
- { SASL_CB_LIST_END, NULL, NULL }
-};
-
-//
-// Command (base class)
-//
-
-Command::Command(SMTPSessionInterface *smtp, int flags)
- : mSMTP(smtp)
- , mComplete(false)
- , mNeedResponse(false)
- , mFlags(flags)
-{
- assert(smtp);
-}
-
-Command::~Command()
-{
-}
-
-bool Command::processResponse(const Response &r, TransactionState *ts)
-{
- Q_UNUSED(ts)
- mComplete = true;
- mNeedResponse = false;
- return r.isOk();
-}
-
-void Command::ungetCommandLine(const QByteArray &cmdLine, TransactionState *ts)
-{
- Q_UNUSED(cmdLine)
- Q_UNUSED(ts)
- mComplete = false;
-}
-
-Command *Command::createSimpleCommand(int which, SMTPSessionInterface *smtp)
-{
- switch (which) {
- case STARTTLS:
- return new StartTLSCommand(smtp);
- case DATA:
- return new DataCommand(smtp);
- case NOOP:
- return new NoopCommand(smtp);
- case RSET:
- return new RsetCommand(smtp);
- case QUIT:
- return new QuitCommand(smtp);
- default:
- return 0;
- }
-}
-
-//
-// relay methods:
-//
-
-void Command::parseFeatures(const Response &r)
-{
- mSMTP->parseFeatures(r);
-}
-
-int Command::startSsl()
-{
- return mSMTP->startSsl();
-}
-
-bool Command::haveCapability(const char *cap) const
-{
- return mSMTP->haveCapability(cap);
-}
-
-//
-// EHLO / HELO
-//
-
-QByteArray EHLOCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mNeedResponse = true;
- mComplete = mEHLONotSupported;
- const char *cmd = mEHLONotSupported ? "HELO " : "EHLO ";
- return cmd + QUrl::toAce(mHostname) + "\r\n"; //krazy:exclude=qclasses
-}
-
-bool EHLOCommand::processResponse(const Response &r, TransactionState *ts)
-{
- Q_UNUSED(ts)
- mNeedResponse = false;
- // "command not {recognized,implemented}" response:
- if (r.code() == 500 || r.code() == 502) {
- if (mEHLONotSupported) { // HELO failed...
- mSMTP->error(KIO::ERR_INTERNAL_SERVER,
- i18n("The server rejected both EHLO and HELO commands "
- "as unknown or unimplemented.\n"
- "Please contact the server's system administrator."));
- return false;
- }
- mEHLONotSupported = true; // EHLO failed, but that's ok.
- return true;
- }
- mComplete = true;
- if (r.code() / 10 == 25) { // 25x: success
- parseFeatures(r);
- return true;
- }
- mSMTP->error(KIO::ERR_UNKNOWN,
- i18n("Unexpected server response to %1 command.\n%2",
- (mEHLONotSupported ? QStringLiteral("HELO") : QStringLiteral("EHLO")),
- r.errorMessage()));
- return false;
-}
-
-//
-// STARTTLS - rfc 3207
-//
-
-QByteArray StartTLSCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mComplete = true;
- mNeedResponse = true;
- return "STARTTLS\r\n";
-}
-
-bool StartTLSCommand::processResponse(const Response &r, TransactionState *ts)
-{
- Q_UNUSED(ts)
- mNeedResponse = false;
- if (r.code() != 220) {
- mSMTP->error(r.errorCode(),
- i18n("Your SMTP server does not support TLS. "
- "Disable TLS, if you want to connect "
- "without encryption."));
- return false;
- }
-
- if (startSsl()) {
- return true;
- } else {
- //qCDebug(SMTP_LOG) << "TLS negotiation failed!";
- mSMTP->informationMessageBox(
- i18n("Your SMTP server claims to "
- "support TLS, but negotiation "
- "was unsuccessful.\nYou can "
- "disable TLS in the SMTP account settings dialog."),
- i18n("Connection Failed"));
- return false;
- }
-}
-
-#define SASLERROR mSMTP->error(KIO::ERR_COULD_NOT_AUTHENTICATE, \
- i18n("An error occurred during authentication: %1", \
- QString::fromUtf8( sasl_errdetail( conn ) )));
-
-//
-// AUTH - rfc 2554
-//
-AuthCommand::AuthCommand(SMTPSessionInterface *smtp,
- const char *mechanisms,
- const QString &aFQDN,
- KIO::AuthInfo &ai)
- : Command(smtp, CloseConnectionOnError | OnlyLastInPipeline)
- , mAi(&ai)
- , mFirstTime(true)
-{
- mMechusing = 0;
- int result;
- conn = 0;
- client_interact = 0;
- mOut = 0;
- mOutlen = 0;
- mOneStep = false;
-
- const QByteArray ba = aFQDN.toLatin1();
- result = sasl_client_new("smtp", ba.constData(),
- 0, 0, callbacks, 0, &conn);
- if (result != SASL_OK) {
- SASLERROR
- return;
- }
- do {
- result = sasl_client_start(conn, mechanisms,
- &client_interact, &mOut, &mOutlen, &mMechusing);
-
- if (result == SASL_INTERACT) {
- if (!saslInteract(client_interact)) {
- return;
- };
- }
- } while (result == SASL_INTERACT);
- if (result != SASL_CONTINUE && result != SASL_OK) {
- SASLERROR
- return;
- }
- if (result == SASL_OK) {
- mOneStep = true;
- }
- qCDebug(SMTP_LOG) << "Mechanism: " << mMechusing << " one step: " << mOneStep;
-}
-
-AuthCommand::~AuthCommand()
-{
- if (conn) {
- qCDebug(SMTP_LOG) << "dispose sasl connection";
- sasl_dispose(&conn);
- conn = 0;
- }
-}
-
-bool AuthCommand::saslInteract(void *in)
-{
- qCDebug(SMTP_LOG) << "saslInteract: ";
- sasl_interact_t *interact = (sasl_interact_t *) in;
-
- //some mechanisms do not require username && pass, so don't need a popup
- //window for getting this info
- for (; interact->id != SASL_CB_LIST_END; interact++) {
- if (interact->id == SASL_CB_AUTHNAME ||
- interact->id == SASL_CB_PASS) {
-
- if (mAi->username.isEmpty() || mAi->password.isEmpty()) {
- if (!mSMTP->openPasswordDialog(*mAi)) {
- mSMTP->error(KIO::ERR_ABORTED, i18n("No authentication details supplied."));
- return false;
- }
- }
- break;
- }
- }
-
- interact = (sasl_interact_t *) in;
- while (interact->id != SASL_CB_LIST_END) {
- switch (interact->id) {
- case SASL_CB_USER:
- case SASL_CB_AUTHNAME: {
- qCDebug(SMTP_LOG) << "SASL_CB_[USER|AUTHNAME]: " << mAi->username;
- const QByteArray baUserName = mAi->username.toUtf8();
- interact->result = strdup(baUserName.constData());
- interact->len = strlen((const char *) interact->result);
- break;
- }
- case SASL_CB_PASS: {
- qCDebug(SMTP_LOG) << "SASL_CB_PASS: [HIDDEN]";
- const QByteArray baPassword = mAi->password.toUtf8();
- interact->result = strdup(baPassword.constData());
- interact->len = strlen((const char *) interact->result);
- break;
- }
- default:
- interact->result = NULL;
- interact->len = 0;
- break;
- }
- interact++;
- }
- return true;
-}
-
-bool AuthCommand::doNotExecute(const TransactionState *ts) const
-{
- Q_UNUSED(ts)
- return !mMechusing;
-}
-
-void AuthCommand::ungetCommandLine(const QByteArray &s, TransactionState *ts)
-{
- Q_UNUSED(ts)
- mUngetSASLResponse = s;
- mComplete = false;
-}
-
-QByteArray AuthCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mNeedResponse = true;
- QByteArray cmd;
-
- QByteArray challenge;
- if (!mUngetSASLResponse.isNull()) {
- // implement un-ungetCommandLine
- cmd = mUngetSASLResponse;
- mUngetSASLResponse = 0;
- } else if (mFirstTime) {
- QString firstCommand = QLatin1String("AUTH ") + QString::fromLatin1(mMechusing);
-
- challenge = QByteArray::fromRawData(mOut, mOutlen).toBase64();
- if (!challenge.isEmpty()) {
- firstCommand += QLatin1Char(' ');
- firstCommand += QString::fromLatin1(challenge.data(), challenge.size());
- }
- cmd = firstCommand.toLatin1();
-
- if (mOneStep) {
- mComplete = true;
- }
- } else {
-// qCDebug(SMTP_LOG) << "SS: '" << mLastChallenge << "'";
- challenge = QByteArray::fromBase64(mLastChallenge);
- int result;
- do {
- result = sasl_client_step(conn, challenge.isEmpty() ? 0 : challenge.data(),
- challenge.size(),
- &client_interact,
- &mOut, &mOutlen);
- if (result == SASL_INTERACT) {
- if (!saslInteract(client_interact)) {
- return "";
- };
- }
- } while (result == SASL_INTERACT);
- if (result != SASL_CONTINUE && result != SASL_OK) {
- qCDebug(SMTP_LOG) << "sasl_client_step failed with: " << result;
- SASLERROR
- return "";
- }
- cmd = QByteArray::fromRawData(mOut, mOutlen).toBase64();
-
-// qCDebug(SMTP_LOG) << "CC: '" << cmd << "'";
- mComplete = (result == SASL_OK);
- }
- cmd += "\r\n";
- return cmd;
-}
-
-bool AuthCommand::processResponse(const Response &r, TransactionState *ts)
-{
- Q_UNUSED(ts)
- if (!r.isOk()) {
- if (mFirstTime) {
- if (haveCapability("AUTH")) {
- QString chooseADifferentMsg(i18n("Choose a different authentication method."));
- mSMTP->error(KIO::ERR_COULD_NOT_LOGIN,
- (mMechusing ? i18n("Your SMTP server does not support %1.", QString::fromLatin1(mMechusing))
- : i18n("Your SMTP server does not support (unspecified method)."))
- + QLatin1Char('\n') + chooseADifferentMsg + QLatin1Char('\n') + r.errorMessage());
- } else {
- mSMTP->error(KIO::ERR_COULD_NOT_LOGIN,
- i18n("Your SMTP server does not support authentication.\n"
- "%1", r.errorMessage()));
- }
- } else {
- mSMTP->error(KIO::ERR_COULD_NOT_LOGIN,
- i18n("Authentication failed.\n"
- "Most likely the password is wrong.\n"
- "%1", r.errorMessage()));
- }
- return false;
- }
- mFirstTime = false;
- mLastChallenge = r.lines().at(0); // ### better join all lines with \n?
- mNeedResponse = false;
- return true;
-}
-
-//
-// MAIL FROM:
-//
-
-QByteArray MailFromCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mComplete = true;
- mNeedResponse = true;
- QByteArray cmdLine = "MAIL FROM:<" + mAddr + '>';
- if (m8Bit && haveCapability("8BITMIME")) {
- cmdLine += " BODY=8BITMIME";
- }
- if (mSize && haveCapability("SIZE")) {
- cmdLine += " SIZE=" + QByteArray().setNum(mSize);
- }
- return cmdLine + "\r\n";
-}
-
-bool MailFromCommand::processResponse(const Response &r, TransactionState *ts)
-{
- assert(ts);
- mNeedResponse = false;
-
- if (r.code() == 250) {
- return true;
- }
-
- ts->setMailFromFailed(QString::fromLatin1(mAddr), r);
- return false;
-}
-
-//
-// RCPT TO:
-//
-
-QByteArray RcptToCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mComplete = true;
- mNeedResponse = true;
- return "RCPT TO:<" + mAddr + ">\r\n";
-}
-
-bool RcptToCommand::processResponse(const Response &r, TransactionState *ts)
-{
- assert(ts);
- mNeedResponse = false;
-
- if (r.code() == 250) {
- ts->setRecipientAccepted();
- return true;
- }
-
- ts->addRejectedRecipient(QString::fromLatin1(mAddr), r.errorMessage());
- return false;
-}
-
-//
-// DATA (only initial processing!)
-//
-
-QByteArray DataCommand::nextCommandLine(TransactionState *ts)
-{
- assert(ts);
- mComplete = true;
- mNeedResponse = true;
- ts->setDataCommandIssued(true);
- return "DATA\r\n";
-}
-
-void DataCommand::ungetCommandLine(const QByteArray &cmd, TransactionState *ts)
-{
- Q_UNUSED(cmd)
- assert(ts);
- mComplete = false;
- ts->setDataCommandIssued(false);
-}
-
-bool DataCommand::processResponse(const Response &r, TransactionState *ts)
-{
- assert(ts);
- mNeedResponse = false;
-
- if (r.code() == 354) {
- ts->setDataCommandSucceeded(true, r);
- return true;
- }
-
- ts->setDataCommandSucceeded(false, r);
- return false;
-}
-
-//
-// DATA (data transfer)
-//
-void TransferCommand::ungetCommandLine(const QByteArray &cmd, TransactionState *ts)
-{
- Q_UNUSED(ts)
- if (cmd.isEmpty()) {
- return; // don't change state when we can't detect the unget in
- }
- // the next nextCommandLine !!
- mWasComplete = mComplete;
- mComplete = false;
- mNeedResponse = false;
- mUngetBuffer = cmd;
-}
-
-bool TransferCommand::doNotExecute(const TransactionState *ts) const
-{
- assert(ts);
- return ts->failed();
-}
-
-QByteArray TransferCommand::nextCommandLine(TransactionState *ts)
-{
- assert(ts); // let's rely on it ( at least for the moment )
- assert(!isComplete());
- assert(!ts->failed());
-
- static const QByteArray dotCRLF = ".\r\n";
- static const QByteArray CRLFdotCRLF = "\r\n.\r\n";
-
- if (!mUngetBuffer.isEmpty()) {
- const QByteArray ret = mUngetBuffer;
- mUngetBuffer = 0;
- if (mWasComplete) {
- mComplete = true;
- mNeedResponse = true;
- }
- return ret; // don't prepare(), it's slave-generated or already prepare()d
- }
-
- // normal processing:
-
- qCDebug(SMTP_LOG) << "requesting data";
- mSMTP->dataReq();
- QByteArray ba;
- int result = mSMTP->readData(ba);
- qCDebug(SMTP_LOG) << "got " << result << " bytes";
- if (result > 0) {
- return prepare(ba);
- } else if (result < 0) {
- ts->setFailedFatally(KIO::ERR_INTERNAL,
- i18n("Could not read data from application."));
- mComplete = true;
- mNeedResponse = true;
- return 0;
- }
- mComplete = true;
- mNeedResponse = true;
- return mLastChar == '\n' ? dotCRLF : CRLFdotCRLF;
-}
-
-bool TransferCommand::processResponse(const Response &r, TransactionState *ts)
-{
- mNeedResponse = false;
- assert(ts);
- ts->setComplete();
- if (!r.isOk()) {
- ts->setFailed();
- mSMTP->error(r.errorCode(),
- i18n("The message content was not accepted.\n"
- "%1", r.errorMessage()));
- return false;
- }
- return true;
-}
-
-static QByteArray dotstuff_lf2crlf(const QByteArray &ba, char &last)
-{
- QByteArray result(ba.size() * 2 + 1, 0); // worst case: repeated "[.]\n"
- const char *s = ba.data();
- const char *const send = ba.data() + ba.size();
- char *d = result.data();
-
- while (s < send) {
- const char ch = *s++;
- if (ch == '\n' && last != '\r') {
- *d++ = '\r'; // lf2crlf
- } else if (ch == '.' && last == '\n') {
- *d++ = '.'; // dotstuff
- }
- last = *d++ = ch;
- }
-
- result.truncate(d - result.data());
- return result;
-}
-
-QByteArray TransferCommand::prepare(const QByteArray &ba)
-{
- if (ba.isEmpty()) {
- return 0;
- }
- if (mSMTP->lf2crlfAndDotStuffingRequested()) {
- qCDebug(SMTP_LOG) << "performing dotstuffing and LF->CRLF transformation";
- return dotstuff_lf2crlf(ba, mLastChar);
- } else {
- mLastChar = ba[ba.size() - 1];
- return ba;
- }
-}
-
-//
-// NOOP
-//
-
-QByteArray NoopCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mComplete = true;
- mNeedResponse = true;
- return "NOOP\r\n";
-}
-
-//
-// RSET
-//
-
-QByteArray RsetCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mComplete = true;
- mNeedResponse = true;
- return "RSET\r\n";
-}
-
-//
-// QUIT
-//
-
-QByteArray QuitCommand::nextCommandLine(TransactionState *ts)
-{
- Q_UNUSED(ts)
- mComplete = true;
- mNeedResponse = true;
- return "QUIT\r\n";
-}
-
-} // namespace KioSMTP
diff --git a/kioslave/src/smtp/command.h b/kioslave/src/smtp/command.h
deleted file mode 100644
index a0b6a9c..0000000
--- a/kioslave/src/smtp/command.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/* -*- c++ -*-
- command.h
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#ifndef __KIOSMTP_COMMAND_H__
-#define __KIOSMTP_COMMAND_H__
-
-extern "C" {
-#include <sasl/sasl.h>
-}
-
-#include <kio/authinfo.h>
-
-namespace KioSMTP
-{
-
-class Response;
-class TransactionState;
-class SMTPSessionInterface;
-
-/**
- * @short Represents an SMTP command
- *
- * Semantics: A command consists of a series of "command lines"
- * (though that's stretching it a bit for @ref TransferJob and @ref
- * AuthCommand) and responses. There's typically one response for
- * one command line and the command is completed.
- *
- * However, some commands consist of a dialog (command line,
- * response, command line, response,...) where each successive
- * command line is dependant on the previously received response
- * (and thus those commands are not pipelinable). That's why each
- * command signals completion by having it's @ref #isComplete()
- * method return true @em after the last command line to be sent,
- * but @em before the last response to receive. @ref AuthCommand is
- * the principal representative of this kind of command. Because
- * @ref EHLOCommand automatically falls back to HELO in case EHLO
- * isn't supported, it is also of this kind. If completion is
- * signalled before the first command line is issued, it is not to
- * be executed at all.
- *
- * Other commands need to send multiple "command lines" before
- * receiving a single (final) response. @ref TransferCommand is the
- * only representative of this kind of "command". That's why each
- * command signals whether it now expects a response before being
- * able to issue the next command line (if any) by having it's @ref
- * #needsResponse() method return true.
- *
- * Commands whose @ref #nextCommandLine() does not support being
- * called multiple times in a row without changing command state,
- * must reimplement @ref #ungetCommandLine().
- **/
-class Command
-{
-public:
- enum Flags {
- OnlyLastInPipeline = 1,
- OnlyFirstInPipeline = 2,
- CloseConnectionOnError = 4
- };
-
- explicit Command(SMTPSessionInterface *smtp, int flags = 0);
- virtual ~Command();
-
- enum Type {
- STARTTLS,
- DATA,
- NOOP,
- RSET,
- QUIT
- };
-
- static Command *createSimpleCommand(int which, SMTPSessionInterface *smtp);
-
- virtual QByteArray nextCommandLine(TransactionState *ts = 0) = 0;
- /* Reimplement this if your @ref #nextCommandLine() implementation
- changes state other than @ref mComplete. The default
- implementation just resets @ref mComplete to false. */
- virtual void ungetCommandLine(const QByteArray &cmdLine, TransactionState *ts = 0);
- /* Reimplement this if your command need more sophisicated
- response processing than just checking for @ref
- Response::isOk(). The default implementation sets @ref
- mComplete to true, @ref mNeedResponse to false and returns
- whether the response isOk(). */
- virtual bool processResponse(const Response &response, TransactionState *ts = 0);
-
- virtual bool doNotExecute(const TransactionState *ts) const
- {
- Q_UNUSED(ts)
- return false;
- }
-
- bool isComplete() const
- {
- return mComplete;
- }
-
- /**
- * @return whether the command expects a response now. Some
- * commands (most notably AUTH) may consist of a series of
- * commands and associated responses until they are
- * complete. Others (most notably @ref TransferCommand usually
- * send multiple "command lines" before expecting a response.
- */
- bool needsResponse() const
- {
- return mNeedResponse;
- }
-
- /**
- * @return whether an error in executing this command is so fatal
- * that closing the connection is the only option
- */
- bool closeConnectionOnError() const
- {
- return mFlags & CloseConnectionOnError;
- }
- bool mustBeLastInPipeline() const
- {
- return mFlags & OnlyLastInPipeline;
- }
- bool mustBeFirstInPipeline() const
- {
- return mFlags & OnlyFirstInPipeline;
- }
-
-protected:
- SMTPSessionInterface *mSMTP;
- bool mComplete;
- bool mNeedResponse;
- const int mFlags;
-
-protected:
- // only relay methods to enable access to slave-protected methods
- // for subclasses of Command:
- void parseFeatures(const Response &r);
- int startSsl();
- bool haveCapability(const char *cap) const;
-};
-
-class EHLOCommand : public Command
-{
-public:
- EHLOCommand(SMTPSessionInterface *smtp, const QString &hostname)
- : Command(smtp, CloseConnectionOnError | OnlyLastInPipeline)
- , mEHLONotSupported(false)
- , mHostname(hostname.trimmed())
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
- bool processResponse(const Response &response, TransactionState *ts) Q_DECL_OVERRIDE;
-private:
- bool mEHLONotSupported;
- QString mHostname;
-};
-
-class StartTLSCommand : public Command
-{
-public:
- StartTLSCommand(SMTPSessionInterface *smtp)
- : Command(smtp, CloseConnectionOnError | OnlyLastInPipeline)
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
- bool processResponse(const Response &response, TransactionState *ts) Q_DECL_OVERRIDE;
-};
-
-class AuthCommand : public Command
-{
-public:
- AuthCommand(SMTPSessionInterface *smtp, const char *mechanisms,
- const QString &aFQDN, KIO::AuthInfo &ai);
- ~AuthCommand();
- bool doNotExecute(const TransactionState *ts) const Q_DECL_OVERRIDE;
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
- void ungetCommandLine(const QByteArray &cmdLine, TransactionState *ts) Q_DECL_OVERRIDE;
- bool processResponse(const Response &response, TransactionState *ts) Q_DECL_OVERRIDE;
-private:
- bool saslInteract(void *in);
-
- sasl_conn_t *conn;
- sasl_interact_t *client_interact;
- const char *mOut;
- uint mOutlen;
- bool mOneStep;
-
- const char *mMechusing;
- KIO::AuthInfo *mAi;
- QByteArray mLastChallenge;
- QByteArray mUngetSASLResponse;
- bool mFirstTime;
-};
-
-class MailFromCommand : public Command
-{
-public:
- MailFromCommand(SMTPSessionInterface *smtp, const QByteArray &addr,
- bool eightBit = false, unsigned int size = 0)
- : Command(smtp)
- , mAddr(addr)
- , m8Bit(eightBit)
- , mSize(size)
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
- bool processResponse(const Response &response, TransactionState *ts) Q_DECL_OVERRIDE;
-private:
- QByteArray mAddr;
- bool m8Bit;
- unsigned int mSize;
-};
-
-class RcptToCommand : public Command
-{
-public:
- RcptToCommand(SMTPSessionInterface *smtp, const QByteArray &addr)
- : Command(smtp)
- , mAddr(addr)
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
- bool processResponse(const Response &response, TransactionState *ts) Q_DECL_OVERRIDE;
-private:
- QByteArray mAddr;
-};
-
-/** Handles only the initial intermediate response and compltetes at
- the point where the mail contents need to be sent */
-class DataCommand : public Command
-{
-public:
- DataCommand(SMTPSessionInterface *smtp)
- : Command(smtp, OnlyLastInPipeline)
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
- void ungetCommandLine(const QByteArray &cmd, TransactionState *ts) Q_DECL_OVERRIDE;
- bool processResponse(const Response &response, TransactionState *ts) Q_DECL_OVERRIDE;
-};
-
-/** Handles the data transfer following a successful DATA command */
-class TransferCommand : public Command
-{
-public:
- TransferCommand(SMTPSessionInterface *smtp, const QByteArray &initialBuffer)
- : Command(smtp, OnlyFirstInPipeline)
- , mUngetBuffer(initialBuffer)
- , mLastChar('\n')
- , mWasComplete(false)
- {
- }
-
- bool doNotExecute(const TransactionState *ts) const Q_DECL_OVERRIDE;
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
- void ungetCommandLine(const QByteArray &cmd, TransactionState *ts) Q_DECL_OVERRIDE;
- bool processResponse(const Response &response, TransactionState *ts) Q_DECL_OVERRIDE;
-private:
- QByteArray prepare(const QByteArray &ba);
- QByteArray mUngetBuffer;
- char mLastChar;
- bool mWasComplete; // ... before ungetting
-};
-
-class NoopCommand : public Command
-{
-public:
- NoopCommand(SMTPSessionInterface *smtp)
- : Command(smtp, OnlyLastInPipeline)
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
-};
-
-class RsetCommand : public Command
-{
-public:
- RsetCommand(SMTPSessionInterface *smtp)
- : Command(smtp, CloseConnectionOnError)
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
-};
-
-class QuitCommand : public Command
-{
-public:
- QuitCommand(SMTPSessionInterface *smtp)
- : Command(smtp, CloseConnectionOnError | OnlyLastInPipeline)
- {
- }
-
- QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
-};
-
-} // namespace KioSMTP
-
-#endif // __KIOSMTP_COMMAND_H__
diff --git a/kioslave/src/smtp/compliance.txt b/kioslave/src/smtp/compliance.txt
deleted file mode 100644
index b6b9874..0000000
--- a/kioslave/src/smtp/compliance.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-The SMTP kioslave currently conforms to the following SMTP-related RFCs:
-
-Base Spec:
-2821 Simple Mail Transfer Protocol. J. Klensin, Ed.. April 2001.
- (Format: TXT=192504 bytes) (Obsoletes RFC0821, RFC0974, RFC1869)
- (Status: PROPOSED STANDARD)
-
-Encryption/Auth:
-3207 SMTP Service Extension for Secure SMTP over Transport Layer
- Security. P. Hoffman. February 2002. (Format: TXT=18679 bytes)
- (Obsoletes RFC2487) (Status: PROPOSED STANDARD)
-
-2554 SMTP Service Extension for Authentication. J. Myers. March 1999.
- (Format: TXT=20534 bytes) (Status: PROPOSED STANDARD)
-(with all SASL mechanisms supported by KDESasl)
-
-General:
-1652 SMTP Service Extension for 8bit-MIMEtransport. J. Klensin, N.
- Freed, M. Rose, E. Stefferud, D. Crocker. July 1994. (Format:
- TXT=11842 bytes) (Obsoletes RFC1426) (Status: DRAFT STANDARD)
-
-1870 SMTP Service Extension for Message Size Declaration. J. Klensin,
- N. Freed, K. Moore. November 1995. (Format: TXT=18226 bytes)
- (Obsoletes RFC1653) (Also STD0010) (Status: STANDARD)
-
-2920 SMTP Service Extension for Command Pipelining. N. Freed.
- September 2000. (Format: TXT=17065 bytes) (Obsoletes RFC2197) (Also
- STD0060) (Status: STANDARD)
-
-Known shortcomings:
-- Doesn't enforce the CRLF lineending convention on user-supplied data.
-- Due to the lack of a Mulit_Put_ in the KIO infrastructure, pipelining
- across messages isn't supported.
diff --git a/kioslave/src/smtp/kioslavesession.cpp b/kioslave/src/smtp/kioslavesession.cpp
deleted file mode 100644
index 3c770bd..0000000
--- a/kioslave/src/smtp/kioslavesession.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- Copyright (c) 2010 Volker Krause <vkrause at kde.org>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#include "kioslavesession.h"
-
-using namespace KioSMTP;
-
-KioSMTP::KioSlaveSession::KioSlaveSession(SMTPProtocol *protocol)
- : m_protocol(protocol)
-{
-}
-
-void KioSMTP::KioSlaveSession::error(int id, const QString &msg)
-{
- m_protocol->error(id, msg);
-}
-
-void KioSlaveSession::informationMessageBox(const QString &msg, const QString &caption)
-{
- m_protocol->messageBox(KIO::SlaveBase::Information, msg, caption);
-}
-
-bool KioSMTP::KioSlaveSession::openPasswordDialog(KIO::AuthInfo &authInfo)
-{
- return m_protocol->openPasswordDialog(authInfo);
-}
-
-void KioSMTP::KioSlaveSession::dataReq()
-{
- m_protocol->dataReq();
-}
-
-int KioSMTP::KioSlaveSession::readData(QByteArray &ba)
-{
- return m_protocol->readData(ba);
-}
-
-bool KioSMTP::KioSlaveSession::startSsl()
-{
- return m_protocol->startSsl();
-}
-
-bool KioSlaveSession::eightBitMimeRequested() const
-{
- return m_protocol->metaData(QStringLiteral("8bitmime")) == QLatin1String("on");
-}
-
-bool KioSlaveSession::lf2crlfAndDotStuffingRequested() const
-{
- return m_protocol->metaData(QStringLiteral("lf2crlf+dotstuff")) == QLatin1String("slave");
-}
-
-bool KioSlaveSession::pipeliningRequested() const
-{
- return m_protocol->metaData(QStringLiteral("pipelining")) != QLatin1String("off");
-}
-
-QString KioSlaveSession::requestedSaslMethod() const
-{
- return m_protocol->metaData(QStringLiteral("sasl"));
-}
-
-KioSMTP::SMTPSessionInterface::TLSRequestState KioSMTP::KioSlaveSession::tlsRequested() const
-{
- if (m_protocol->metaData(QStringLiteral("tls")) == QLatin1String("off")) {
- return ForceNoTLS;
- }
- if (m_protocol->metaData(QStringLiteral("tls")) == QLatin1String("on")) {
- return ForceTLS;
- }
- return UseTLSIfAvailable;
-}
diff --git a/kioslave/src/smtp/kioslavesession.h b/kioslave/src/smtp/kioslavesession.h
deleted file mode 100644
index 13118c0..0000000
--- a/kioslave/src/smtp/kioslavesession.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (c) 2010 Volker Krause <vkrause at kde.org>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#ifndef KIOSMTP_KIOSLAVESESSION_H
-#define KIOSMTP_KIOSLAVESESSION_H
-
-#include "smtpsessioninterface.h"
-#include "smtp.h"
-
-namespace KioSMTP
-{
-
-class KioSlaveSession : public SMTPSessionInterface
-{
-public:
- explicit KioSlaveSession(SMTPProtocol *protocol);
- void error(int id, const QString &msg) Q_DECL_OVERRIDE;
- void informationMessageBox(const QString &msg, const QString &caption) Q_DECL_OVERRIDE;
- bool openPasswordDialog(KIO::AuthInfo &authInfo) Q_DECL_OVERRIDE;
- void dataReq() Q_DECL_OVERRIDE;
- int readData(QByteArray &ba) Q_DECL_OVERRIDE;
- bool startSsl() Q_DECL_OVERRIDE;
-
- QString requestedSaslMethod() const Q_DECL_OVERRIDE;
- bool eightBitMimeRequested() const Q_DECL_OVERRIDE;
- bool lf2crlfAndDotStuffingRequested() const Q_DECL_OVERRIDE;
- bool pipeliningRequested() const Q_DECL_OVERRIDE;
- TLSRequestState tlsRequested() const Q_DECL_OVERRIDE;
-
-private:
- SMTPProtocol *m_protocol;
-};
-
-}
-
-#endif
diff --git a/kioslave/src/smtp/request.cpp b/kioslave/src/smtp/request.cpp
deleted file mode 100644
index 509bd95..0000000
--- a/kioslave/src/smtp/request.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- c++ -*-
- request.cc
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#include "request.h"
-#include "smtp_debug.h"
-
-#include <QUrl>
-#include <QtCore/QUrl>
-#include <qdebug.h>
-
-#include <assert.h>
-
-namespace KioSMTP
-{
-
-Request Request::fromURL(const QUrl &url)
-{
- Request request;
-
- const QStringList query = url.query().split(QLatin1Char('&'));
-#ifndef NDEBUG
- qCDebug(SMTP_LOG) << "Parsing request from query:\n" << query.join(QStringLiteral("\n"));
-#endif
- for (QStringList::const_iterator it = query.begin(); it != query.end(); ++it) {
- int equalsPos = (*it).indexOf(QLatin1Char('='));
- if (equalsPos <= 0) {
- continue;
- }
-
- const QString key = (*it).left(equalsPos).toLower();
- const QString value = QUrl::fromPercentEncoding((*it).mid(equalsPos + 1).toLatin1()); //krazy:exclude=qclasses
-
- if (key == QLatin1String("to")) {
- request.addTo(value);
- } else if (key == QLatin1String("cc")) {
- request.addCc(value);
- } else if (key == QLatin1String("bcc")) {
- request.addBcc(value);
- } else if (key == QLatin1String("headers")) {
- request.setEmitHeaders(value == QLatin1String("0"));
- request.setEmitHeaders(false); // ### ???
- } else if (key == QLatin1String("subject")) {
- request.setSubject(value);
- } else if (key == QLatin1String("from")) {
- request.setFromAddress(value);
- } else if (key == QLatin1String("profile")) {
- request.setProfileName(value);
- } else if (key == QLatin1String("hostname")) {
- request.setHeloHostname(value);
- } else if (key == QLatin1String("body")) {
- request.set8BitBody(value.toUpper() == QLatin1String("8BIT"));
- } else if (key == QLatin1String("size")) {
- request.setSize(value.toUInt());
- } else {
- qCWarning(SMTP_LOG) << "while parsing query: unknown query item \""
- << key << "\" with value \"" << value << "\"" << endl;
- }
- }
-
- return request;
-}
-
-QByteArray Request::heloHostnameCString() const
-{
- return QUrl::toAce(heloHostname()); //krazy:exclude=qclasses
-}
-
-static bool isUsAscii(const QString &s)
-{
- for (int i = 0; i < s.length(); ++i) {
- if (s[i].unicode() > 127) {
- return false;
- }
- }
- return true;
-}
-
-static inline bool isSpecial(char ch)
-{
- static const QByteArray specials = "()<>[]:;@\\,.\"";
- return specials.indexOf(ch) >= 0;
-}
-
-static inline bool needsQuoting(char ch)
-{
- return ch == '\\' || ch == '"' || ch == '\n';
-}
-
-static inline QByteArray rfc2047Encode(const QString &s)
-{
- QByteArray r = s.trimmed().toUtf8().toBase64();
- return "=?utf-8?b?" + r + "?="; // use base64 since that always gives a valid encoded-word
-}
-
-static QByteArray quote(const QString &s)
-{
- assert(isUsAscii(s));
-
- QByteArray r(s.length() * 2, 0);
- bool needsQuotes = false;
-
- unsigned int j = 0;
- for (int i = 0; i < s.length(); ++i) {
- char ch = s[i].toLatin1();
- if (isSpecial(ch)) {
- if (needsQuoting(ch)) {
- r[j++] = '\\';
- }
- needsQuotes = true;
- }
- r[j++] = ch;
- }
- r.truncate(j);
-
- if (needsQuotes) {
- return '"' + r + '"';
- } else {
- return r;
- }
-}
-
-static QByteArray formatFromAddress(const QString &fromRealName, const QString &fromAddress)
-{
- if (fromRealName.isEmpty()) {
- return fromAddress.toLatin1(); // no real name: return "joe at user.org"
- }
-
- // return "Joe User <joe at user.org>", "\"User, Joe\" <joe at user.org>"
- // or "=?utf-8?q?Joe_User?= <joe at user.org>", depending on real name's nature.
- QByteArray r = isUsAscii(fromRealName) ? quote(fromRealName) : rfc2047Encode(fromRealName);
- return r + " <" + fromAddress.toLatin1() + '>';
-}
-
-static QByteArray formatSubject(QString s)
-{
- if (isUsAscii(s)) {
- return s.remove(QLatin1Char('\n')).toLatin1(); // don't break header folding,
- } else {
- // so remove any line break
- // that happen to be around
- return rfc2047Encode(s);
- }
-}
-
-QByteArray Request::headerFields(const QString &fromRealName) const
-{
- if (!emitHeaders()) {
- return 0;
- }
-
- assert(hasFromAddress()); // should have been checked for by
- // caller (MAIL FROM comes before DATA)
-
- QByteArray result = "From: " + formatFromAddress(fromRealName, fromAddress()) + "\r\n";
-
- if (!subject().isEmpty()) {
- result += "Subject: " + formatSubject(subject()) + "\r\n";
- }
- if (!to().empty()) {
- result += QByteArray("To: ") + to().join(QStringLiteral(",\r\n\t") /* line folding */).toLatin1() + "\r\n";
- }
- if (!cc().empty()) {
- result += QByteArray("Cc: ") + cc().join(QStringLiteral(",\r\n\t") /* line folding */).toLatin1() + "\r\n";
- }
- return result;
-}
-
-} // namespace KioSMTP
diff --git a/kioslave/src/smtp/request.h b/kioslave/src/smtp/request.h
deleted file mode 100644
index cd399d3..0000000
--- a/kioslave/src/smtp/request.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* -*- c++ -*-
- request.h
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#ifndef __KIOSMTP_REQUEST_H__
-#define __KIOSMTP_REQUEST_H__
-
-#include <QStringList>
-#include <QByteArray>
-
-class QUrl;
-
-namespace KioSMTP
-{
-
-class Request
-{
-public:
- Request()
- : mSubject(QStringLiteral("missing subject"))
- , mEmitHeaders(true)
- , m8Bit(false)
- , mSize(0)
- {
- }
-
- static Request fromURL(const QUrl &url);
-
- QString profileName() const
- {
- return mProfileName;
- }
- void setProfileName(const QString &profileName)
- {
- mProfileName = profileName;
- }
- bool hasProfile() const
- {
- return !profileName().isNull();
- }
-
- QString subject() const
- {
- return mSubject;
- }
- void setSubject(const QString &subject)
- {
- mSubject = subject;
- }
-
- QString fromAddress() const
- {
- return mFromAddress;
- }
- void setFromAddress(const QString &fromAddress)
- {
- mFromAddress = fromAddress;
- }
- bool hasFromAddress() const
- {
- return !mFromAddress.isEmpty();
- }
-
- QStringList recipients() const
- {
- return to() + cc() + bcc();
- }
- bool hasRecipients() const
- {
- return !to().empty() || !cc().empty() || !bcc().empty();
- }
-
- QStringList to() const
- {
- return mTo;
- }
- QStringList cc() const
- {
- return mCc;
- }
- QStringList bcc() const
- {
- return mBcc;
- }
- void addTo(const QString &to)
- {
- mTo.push_back(to);
- }
- void addCc(const QString &cc)
- {
- mCc.push_back(cc);
- }
- void addBcc(const QString &bcc)
- {
- mBcc.push_back(bcc);
- }
-
- QString heloHostname() const
- {
- return mHeloHostname;
- }
- QByteArray heloHostnameCString() const;
- void setHeloHostname(const QString &hostname)
- {
- mHeloHostname = hostname;
- }
-
- bool emitHeaders() const
- {
- return mEmitHeaders;
- }
- void setEmitHeaders(bool emitHeaders)
- {
- mEmitHeaders = emitHeaders;
- }
-
- bool is8BitBody() const
- {
- return m8Bit;
- }
- void set8BitBody(bool a8Bit)
- {
- m8Bit = a8Bit;
- }
-
- unsigned int size() const
- {
- return mSize;
- }
- void setSize(unsigned int size)
- {
- mSize = size;
- }
-
- /**
- * If @ref #emitHeaders() is true, returns the rfc2822
- * serialization of the header fields "To", "Cc", "Subject" and
- * "From", as determined by the respective settings. If @ref
- * #emitHeaders() is false, returns a null string.
- */
- QByteArray headerFields(const QString &fromRealName = QString()) const;
-
-private:
- QStringList mTo, mCc, mBcc;
- QString mProfileName, mSubject, mFromAddress, mHeloHostname;
- bool mEmitHeaders;
- bool m8Bit;
- unsigned int mSize;
-};
-
-} // namespace KioSMTP
-
-#endif // __KIOSMTP_REQUEST_H__
diff --git a/kioslave/src/smtp/response.cpp b/kioslave/src/smtp/response.cpp
deleted file mode 100644
index e0a730f..0000000
--- a/kioslave/src/smtp/response.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- c++ -*-
- response.cc
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#include "response.h"
-
-#include <KLocalizedString>
-#include <kio/global.h>
-
-#include <QByteArray>
-
-namespace KioSMTP
-{
-
-void Response::parseLine(const char *line, int len)
-{
-
- if (!isWellFormed()) {
- return; // don't bother
- }
-
- if (isComplete()) {
- // if the response is already complete, there can't be another line
- mValid = false;
- }
-
- if (len > 1 && line[len - 1] == '\n' && line[len - 2] == '\r') {
- len -= 2;
- }
-
- if (len < 3) {
- // can't be valid - too short
- mValid = false;
- mWellFormed = false;
- return;
- }
-
- bool ok = false;
- unsigned int code = QByteArray(line, 3).toUInt(&ok);
- if (!ok || code < 100 || code > 559) {
- // not a number or number out of range
- mValid = false;
- if (!ok || code < 100) {
- mWellFormed = false;
- }
- return;
- }
- if (mCode && code != mCode) {
- // different codes in one response are not allowed.
- mValid = false;
- return;
- }
- mCode = code;
-
- if (len == 3 || line[3] == ' ') {
- mSawLastLine = true;
- } else if (line[3] != '-') {
- // code must be followed by either SP or hyphen (len == 3 is
- // also accepted since broken servers exist); all else is
- // invalid
- mValid = false;
- mWellFormed = false;
- return;
- }
-
- mLines.push_back(len > 4 ? QByteArray(line + 4, len - 4).trimmed() : QByteArray());
-}
-
-// hackishly fixing QCStringList flaws...
-static QByteArray join(char sep, const QCStringList &list)
-{
- if (list.empty()) {
- return QByteArray();
- }
- QByteArray result = list.front();
- for (QCStringList::const_iterator it = ++list.begin(); it != list.end(); ++it) {
- result += sep + *it;
- }
- return result;
-}
-
-QString Response::errorMessage() const
-{
- QString msg;
- if (lines().count() > 1) {
- msg = i18n("The server responded:\n%1", QString::fromLatin1(join('\n', lines())));
- } else {
- msg = i18n("The server responded: \"%1\"", QString::fromLatin1(lines().at(0)));
- }
- if (first() == 4) {
- msg += QLatin1Char('\n') + i18n("This is a temporary failure. You may try again later.");
- }
- return msg;
-}
-
-int Response::errorCode() const
-{
- switch (code()) {
- case 421: // Service not available, closing transmission channel
- case 454: // TLS not available due to temporary reason
- // Temporary authentication failure
- case 554: // Transaction failed / No SMTP service here / No valid recipients
- return KIO::ERR_SERVICE_NOT_AVAILABLE;
-
- case 451: // Requested action aborted: local error in processing
- return KIO::ERR_INTERNAL_SERVER;
-
- case 452: // Requested action not taken: insufficient system storage
- case 552: // Requested mail action aborted: exceeded storage allocation
- return KIO::ERR_DISK_FULL;
-
- case 500: // Syntax error, command unrecognized
- case 501: // Syntax error in parameters or arguments
- case 502: // Command not implemented
- case 503: // Bad sequence of commands
- case 504: // Command parameter not implemented
- return KIO::ERR_INTERNAL;
-
- case 450: // Requested mail action not taken: mailbox unavailable
- case 550: // Requested action not taken: mailbox unavailable
- case 551: // User not local; please try <forward-path>
- case 553: // Requested action not taken: mailbox name not allowed
- return KIO::ERR_DOES_NOT_EXIST;
-
- case 530: // {STARTTLS,Authentication} required
- case 538: // Encryption required for requested authentication mechanism
- case 534: // Authentication mechanism is too weak
- return KIO::ERR_UPGRADE_REQUIRED;
-
- case 432: // A password transition is needed
- return KIO::ERR_COULD_NOT_AUTHENTICATE;
-
- default:
- if (isPositive()) {
- return 0;
- } else {
- return KIO::ERR_UNKNOWN;
- }
- }
-}
-
-} // namespace KioSMTP
diff --git a/kioslave/src/smtp/response.h b/kioslave/src/smtp/response.h
deleted file mode 100644
index b182377..0000000
--- a/kioslave/src/smtp/response.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* -*- c++ -*-
- response.h
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#ifndef __KIOSMTP_RESPONSE_H__
-#define __KIOSMTP_RESPONSE_H__
-
-#include <QList>
-#include <QString>
-typedef QList<QByteArray> QCStringList;
-
-class QString;
-
-namespace KioSMTP
-{
-
-class Response
-{
-public:
- Response()
- : mCode(0)
- , mValid(true)
- , mSawLastLine(false)
- , mWellFormed(true)
- {
- }
-
- void parseLine(const char *line)
- {
- parseLine(line, qstrlen(line));
- }
- void parseLine(const char *line, int len);
-
- /** Return an internationalized error message according to the
- * response's code. */
- QString errorMessage() const;
- /** Translate the SMTP error code into a KIO one */
- int errorCode() const;
-
- enum Reply {
- UnknownReply = -1,
- PositivePreliminary = 1,
- PositiveCompletion = 2,
- PositiveIntermediate = 3,
- TransientNegative = 4,
- PermanentNegative = 5
- };
-
- enum Category {
- UnknownCategory = -1,
- SyntaxError = 0,
- Information = 1,
- Connections = 2,
- MailSystem = 5
- };
-
- unsigned int code() const
- {
- return mCode;
- }
- unsigned int first() const
- {
- return code() / 100;
- }
- unsigned int second() const
- {
- return (code() % 100) / 10;
- }
- unsigned int third() const
- {
- return code() % 10;
- }
-
- bool isPositive() const
- {
- return first() <= 3 && first() >= 1;
- }
- bool isNegative() const
- {
- return first() == 4 || first() == 5;
- }
- bool isUnknown() const
- {
- return !isPositive() && !isNegative();
- }
-
- QCStringList lines() const
- {
- return mLines;
- }
-
- bool isValid() const
- {
- return mValid;
- }
- bool isComplete() const
- {
- return mSawLastLine;
- }
-
- /** Shortcut method.
- * @return true iff the response is valid, complete and positive
- */
- bool isOk() const
- {
- return isValid() && isComplete() && isPositive();
- }
-
- /** Indicates whether the response was well-formed, meaning it
- * obeyed the syntax of smtp responses. That the response
- * nevertheless is not valid may be caused by e.g. different
- * response codes in a multilie response. A non-well-formed
- * response is never valid.
- */
- bool isWellFormed() const
- {
- return mWellFormed;
- }
-
- void clear()
- {
- *this = Response();
- }
-
-#ifdef KIOSMTP_COMPARATORS
- bool operator==(const Response &other) const
- {
- return mCode == other.mCode &&
- mValid == other.mValid &&
- mSawLastLine == other.mSawLastLine &&
- mWellFormed == other.mWellFormed &&
- mLines == other.mLines;
- }
-#endif
-
-private:
- unsigned int mCode;
- QCStringList mLines;
- bool mValid;
- bool mSawLastLine;
- bool mWellFormed;
-};
-
-} // namespace KioSMTP
-
-#endif // __KIOSMTP_RESPONSE_H__
diff --git a/kioslave/src/smtp/smtp.cpp b/kioslave/src/smtp/smtp.cpp
deleted file mode 100644
index e6e6dd0..0000000
--- a/kioslave/src/smtp/smtp.cpp
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * Copyright (c) 2000, 2001 Alex Zepeda <zipzippy at sonic.net>
- * Copyright (c) 2001 Michael H�kel <Michael at Haeckel.Net>
- * Copyright (c) 2002 Aaron J. Seigo <aseigo at olympusproject.org>
- * Copyright (c) 2003 Marc Mutz <mutz at kde.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include "smtp.h"
-#include "smtp_debug.h"
-
-extern "C" {
-#include <sasl/sasl.h>
-}
-
-#include "../common.h"
-#include "request.h"
-#include "response.h"
-#include "transactionstate.h"
-#include "command.h"
-#include "kioslavesession.h"
-using KioSMTP::Capabilities;
-using KioSMTP::Command;
-using KioSMTP::EHLOCommand;
-using KioSMTP::AuthCommand;
-using KioSMTP::MailFromCommand;
-using KioSMTP::RcptToCommand;
-using KioSMTP::DataCommand;
-using KioSMTP::TransferCommand;
-using KioSMTP::Request;
-using KioSMTP::Response;
-using KioSMTP::TransactionState;
-using KioSMTP::SMTPSessionInterface;
-
-#include <kemailsettings.h>
-
-#include <qdebug.h>
-#include <kio/slaveinterface.h>
-#include <KLocalizedString>
-#include <QUrl>
-
-#include <QHostInfo>
-#include <QDataStream>
-
-#include <memory>
-using std::unique_ptr;
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <netdb.h>
-
-extern "C" {
- Q_DECL_EXPORT int kdemain(int argc, char **argv);
-}
-
-int kdemain(int argc, char **argv)
-{
- QCoreApplication app(argc, argv);
- app.setApplicationName(QStringLiteral("kio_smtp"));
-
- if (argc != 4) {
- fprintf(stderr,
- "Usage: kio_smtp protocol domain-socket1 domain-socket2\n");
- exit(-1);
- }
-
- if (!initSASL()) {
- exit(-1);
- }
- SMTPProtocol slave(argv[2], argv[3], qstricmp(argv[1], "smtps") == 0);
- slave.dispatchLoop();
- sasl_done();
- return 0;
-}
-
-SMTPProtocol::SMTPProtocol(const QByteArray &pool, const QByteArray &app,
- bool useSSL)
- : TCPSlaveBase(useSSL ? "smtps" : "smtp", pool, app, useSSL)
- , m_sOldPort(0)
- , m_opened(false)
- , m_sessionIface(new KioSMTP::KioSlaveSession(this))
-{
- //qCDebug(SMTP_LOG) << "SMTPProtocol::SMTPProtocol";
-}
-
-SMTPProtocol::~SMTPProtocol()
-{
- //qCDebug(SMTP_LOG) << "SMTPProtocol::~SMTPProtocol";
- smtp_close();
- delete m_sessionIface;
-}
-
-void SMTPProtocol::openConnection()
-{
-
- // Don't actually call smtp_open() yet. Just pretend that we are connected.
- // We can't call smtp_open() here, as that does EHLO, and the EHLO command
- // needs the fake hostname. However, we only get the fake hostname in put(), so
- // we call smtp_open() there.
- connected();
-}
-
-void SMTPProtocol::closeConnection()
-{
- smtp_close();
-}
-
-void SMTPProtocol::special(const QByteArray &aData)
-{
- QDataStream s(aData);
- int what;
- s >> what;
- if (what == 'c') {
- const QString response = m_sessionIface->capabilities().createSpecialResponse(
- (isUsingSsl() && !isAutoSsl())
- || m_sessionIface->haveCapability("STARTTLS"));
- infoMessage(response);
- } else if (what == 'N') {
- if (!execute(Command::NOOP)) {
- return;
- }
- } else {
- error(KIO::ERR_INTERNAL, i18n("The application sent an invalid request."));
- return;
- }
- finished();
-}
-
-// Usage: smtp://smtphost:port/send?to=user@host.com&subject=blah
-// If smtphost is the name of a profile, it'll use the information
-// provided by that profile. If it's not a profile name, it'll use it as
-// nature intended.
-// One can also specify in the query:
-// headers=0 (turns off header generation)
-// to=emailaddress
-// cc=emailaddress
-// bcc=emailaddress
-// subject=text
-// profile=text (this will override the "host" setting)
-// hostname=text (used in the HELO)
-// body={7bit,8bit} (default: 7bit; 8bit activates the use of the 8BITMIME SMTP extension)
-void SMTPProtocol::put(const QUrl &url, int permissions, KIO::JobFlags)
-{
- Request request = Request::fromURL(url); // parse settings from URL's query
-
- KEMailSettings mset;
- QUrl open_url = url;
- if (!request.hasProfile()) {
- //qCDebug(SMTP_LOG) << "kio_smtp: Profile is null";
- bool hasProfile = mset.profiles().contains(open_url.host());
- if (hasProfile) {
- mset.setProfile(open_url.host());
- open_url.setHost(mset.getSetting(KEMailSettings::OutServer));
- m_sUser = mset.getSetting(KEMailSettings::OutServerLogin);
- m_sPass = mset.getSetting(KEMailSettings::OutServerPass);
-
- if (m_sUser.isEmpty()) {
- m_sUser.clear();
- }
- if (m_sPass.isEmpty()) {
- m_sPass.clear();
- }
- open_url.setUserName(m_sUser);
- open_url.setPassword(m_sPass);
- m_sServer = open_url.host();
- m_port = open_url.port();
- } else {
- mset.setProfile(mset.defaultProfileName());
- }
- } else {
- mset.setProfile(request.profileName());
- }
-
- // Check KEMailSettings to see if we've specified an E-Mail address
- // if that worked, check to see if we've specified a real name
- // and then format accordingly (either: emailaddress at host.com or
- // Real Name <emailaddress at host.com>)
- if (!request.hasFromAddress()) {
- const QString from = mset.getSetting(KEMailSettings::EmailAddress);
- if (!from.isNull()) {
- request.setFromAddress(from);
- } else if (request.emitHeaders()) {
- error(KIO::ERR_NO_CONTENT, i18n("The sender address is missing."));
- return;
- }
- }
-
- if (!smtp_open(request.heloHostname())) {
- error(KIO::ERR_SERVICE_NOT_AVAILABLE,
- i18n("SMTPProtocol::smtp_open failed (%1)", // ### better error message?
- open_url.path()));
- return;
- }
-
- if (request.is8BitBody()
- && !m_sessionIface->haveCapability("8BITMIME") && !m_sessionIface->eightBitMimeRequested()) {
- error(KIO::ERR_SERVICE_NOT_AVAILABLE,
- i18n("Your server (%1) does not support sending of 8-bit messages.\n"
- "Please use base64 or quoted-printable encoding.", m_sServer));
- return;
- }
-
- queueCommand(new MailFromCommand(m_sessionIface, request.fromAddress().toLatin1(),
- request.is8BitBody(), request.size()));
-
- // Loop through our To and CC recipients, and send the proper
- // SMTP commands, for the benefit of the server.
- const QStringList recipients = request.recipients();
- for (QStringList::const_iterator it = recipients.begin(); it != recipients.end(); ++it) {
- queueCommand(new RcptToCommand(m_sessionIface, (*it).toLatin1()));
- }
-
- queueCommand(Command::DATA);
- queueCommand(new TransferCommand(m_sessionIface, request.headerFields(mset.getSetting(KEMailSettings::RealName))));
-
- TransactionState ts;
- if (!executeQueuedCommands(&ts)) {
- if (ts.errorCode()) {
- error(ts.errorCode(), ts.errorMessage());
- }
- } else {
- finished();
- }
-}
-
-void SMTPProtocol::setHost(const QString &host, quint16 port,
- const QString &user, const QString &pass)
-{
- m_sServer = host;
- m_port = port;
- m_sUser = user;
- m_sPass = pass;
-}
-
-bool SMTPProtocol::sendCommandLine(const QByteArray &cmdline)
-{
- //kDebug( cmdline.length() < 4096, 7112) << "C: " << cmdline.data();
- //kDebug( cmdline.length() >= 4096, 7112) << "C: <" << cmdline.length() << " bytes>";
- if (cmdline.length() < 4096) {
- qCDebug(SMTP_LOG) << "C: >>" << cmdline.trimmed().data() << "<<";
- } else {
- qCDebug(SMTP_LOG) << "C: <" << cmdline.length() << " bytes>";
- }
- ssize_t numWritten, cmdline_len = cmdline.length();
- if ((numWritten = write(cmdline.data(), cmdline_len)) != cmdline_len) {
- qCDebug(SMTP_LOG) << "Tried to write " << cmdline_len << " bytes, but only "
- << numWritten << " were written!" << endl;
- error(KIO::ERR_SLAVE_DEFINED, i18n("Writing to socket failed."));
- return false;
- }
- return true;
-}
-
-Response SMTPProtocol::getResponse(bool *ok)
-{
-
- if (ok) {
- *ok = false;
- }
-
- Response response;
- char buf[2048];
-
- int recv_len = 0;
- do {
- // wait for data...
- if (!waitForResponse(600)) {
- error(KIO::ERR_SERVER_TIMEOUT, m_sServer);
- return response;
- }
-
- // ...read data...
- recv_len = readLine(buf, sizeof(buf) - 1);
- if (recv_len < 1 && !isConnected()) {
- error(KIO::ERR_CONNECTION_BROKEN, m_sServer);
- return response;
- }
-
- qCDebug(SMTP_LOG) << "S: >>" << QByteArray(buf, recv_len).trimmed().data() << "<<";
- // ...and parse lines...
- response.parseLine(buf, recv_len);
-
- // ...until the response is complete or the parser is so confused
- // that it doesn't think a RSET would help anymore:
- } while (!response.isComplete() && response.isWellFormed());
-
- if (!response.isValid()) {
- error(KIO::ERR_NO_CONTENT, i18n("Invalid SMTP response (%1) received.", response.code()));
- return response;
- }
-
- if (ok) {
- *ok = true;
- }
-
- return response;
-}
-
-bool SMTPProtocol::executeQueuedCommands(TransactionState *ts)
-{
- assert(ts);
-
- if (m_sessionIface->canPipelineCommands()) {
- qDebug() << "using pipelining";
- }
-
- while (!mPendingCommandQueue.isEmpty()) {
- QByteArray cmdline = collectPipelineCommands(ts);
- if (ts->failedFatally()) {
- smtp_close(false); // _hard_ shutdown
- return false;
- }
- if (ts->failed()) {
- break;
- }
- if (cmdline.isEmpty()) {
- continue;
- }
- if (!sendCommandLine(cmdline) ||
- !batchProcessResponses(ts) ||
- ts->failedFatally()) {
- smtp_close(false); // _hard_ shutdown
- return false;
- }
- }
-
- if (ts->failed()) {
- if (!execute(Command::RSET)) {
- smtp_close(false);
- }
- return false;
- }
- return true;
-}
-
-QByteArray SMTPProtocol::collectPipelineCommands(TransactionState *ts)
-{
- assert(ts);
-
- QByteArray cmdLine;
- unsigned int cmdLine_len = 0;
-
- while (!mPendingCommandQueue.isEmpty()) {
-
- Command *cmd = mPendingCommandQueue.head();
-
- if (cmd->doNotExecute(ts)) {
- delete mPendingCommandQueue.dequeue();
- if (cmdLine_len) {
- break;
- } else {
- continue;
- }
- }
-
- if (cmdLine_len && cmd->mustBeFirstInPipeline()) {
- break;
- }
-
- if (cmdLine_len && !m_sessionIface->canPipelineCommands()) {
- break;
- }
-
- while (!cmd->isComplete() && !cmd->needsResponse()) {
- const QByteArray currentCmdLine = cmd->nextCommandLine(ts);
- if (ts->failedFatally()) {
- return cmdLine;
- }
- const unsigned int currentCmdLine_len = currentCmdLine.length();
-
- cmdLine_len += currentCmdLine_len;
- cmdLine += currentCmdLine;
-
- // If we are executing the transfer command, don't collect the whole
- // command line (which may be several MBs) before sending it, but instead
- // send the data each time we have collected 32 KB of the command line.
- //
- // This way, the progress information in clients like KMail works correctly,
- // because otherwise, the TransferCommand would read the whole data from the
- // job at once, then sending it. The progress update on the client however
- // happens when sending data to the job, not when this slave writes the data
- // to the socket. Therefore that progress update is incorrect.
- //
- // 32 KB seems to be a sensible limit. Additionally, a job can only transfer
- // 32 KB at once anyway.
- if (dynamic_cast<TransferCommand *>(cmd) != 0 &&
- cmdLine_len >= 32 * 1024) {
- return cmdLine;
- }
- }
-
- mSentCommandQueue.enqueue(mPendingCommandQueue.dequeue());
-
- if (cmd->mustBeLastInPipeline()) {
- break;
- }
- }
-
- return cmdLine;
-}
-
-bool SMTPProtocol::batchProcessResponses(TransactionState *ts)
-{
- assert(ts);
-
- while (!mSentCommandQueue.isEmpty()) {
-
- Command *cmd = mSentCommandQueue.head();
- assert(cmd->isComplete());
-
- bool ok = false;
- Response r = getResponse(&ok);
- if (!ok) {
- return false;
- }
- cmd->processResponse(r, ts);
- if (ts->failedFatally()) {
- return false;
- }
-
- delete mSentCommandQueue.dequeue();
- }
-
- return true;
-}
-
-void SMTPProtocol::queueCommand(int type)
-{
- queueCommand(Command::createSimpleCommand(type, m_sessionIface));
-}
-
-bool SMTPProtocol::execute(int type, TransactionState *ts)
-{
- unique_ptr<Command> cmd(Command::createSimpleCommand(type, m_sessionIface));
- if (!cmd.get()) {
- qCritical() << "Command::createSimpleCommand( " << type << " ) returned null!";
- }
- return execute(cmd.get(), ts);
-}
-
-// ### fold into pipelining engine? How? (execute() is often called
-// ### when command queues are _not_ empty!)
-bool SMTPProtocol::execute(Command *cmd, TransactionState *ts)
-{
-
- if (!cmd) {
- qCritical() << "SMTPProtocol::execute() called with no command to run!";
- }
-
- if (cmd->doNotExecute(ts)) {
- return true;
- }
-
- do {
- while (!cmd->isComplete() && !cmd->needsResponse()) {
- const QByteArray cmdLine = cmd->nextCommandLine(ts);
- if (ts && ts->failedFatally()) {
- smtp_close(false);
- return false;
- }
- if (cmdLine.isEmpty()) {
- continue;
- }
- if (!sendCommandLine(cmdLine)) {
- smtp_close(false);
- return false;
- }
- }
-
- bool ok = false;
- Response r = getResponse(&ok);
- if (!ok) {
- // Only close without sending QUIT if the responce was incomplete
- // rfc5321 forbidds a client from closing a connection without sending
- // QUIT (section 4.1.1.10)
- if (r.isComplete()) {
- smtp_close();
- } else {
- smtp_close(false);
- }
- return false;
- }
- if (!cmd->processResponse(r, ts)) {
- if ((ts && ts->failedFatally()) ||
- cmd->closeConnectionOnError() ||
- !execute(Command::RSET)) {
- smtp_close(false);
- }
- return false;
- }
- } while (!cmd->isComplete());
-
- return true;
-}
-
-bool SMTPProtocol::smtp_open(const QString &fakeHostname)
-{
- if (m_opened &&
- m_sOldPort == m_port &&
- m_sOldServer == m_sServer &&
- m_sOldUser == m_sUser &&
- (fakeHostname.isNull() || m_hostname == fakeHostname)) {
- return true;
- }
-
- smtp_close();
- if (!connectToHost(isAutoSsl() ? QStringLiteral("smtps") : QStringLiteral("smtp"), m_sServer, m_port)) {
- return false; // connectToHost has already send an error message.
- }
- m_opened = true;
-
- bool ok = false;
- Response greeting = getResponse(&ok);
- if (!ok || !greeting.isOk()) {
- if (ok) {
- error(KIO::ERR_COULD_NOT_LOGIN,
- i18n("The server (%1) did not accept the connection.\n"
- "%2", m_sServer, greeting.errorMessage()));
- }
- smtp_close();
- return false;
- }
-
- if (!fakeHostname.isNull()) {
- m_hostname = fakeHostname;
- } else {
- // FIXME: We need a way to find the FQDN again. Also change in servertest then.
- m_hostname = QHostInfo::localHostName();
- if (m_hostname.isEmpty()) {
- m_hostname = QStringLiteral("localhost.invalid");
- } else if (!m_hostname.contains(QLatin1Char('.'))) {
- m_hostname += QLatin1String(".localnet");
- }
- }
-
- EHLOCommand ehloCmdPreTLS(m_sessionIface, m_hostname);
- if (!execute(&ehloCmdPreTLS)) {
- smtp_close();
- return false;
- }
-
- if ((m_sessionIface->haveCapability("STARTTLS") /*### && canUseTLS()*/ && m_sessionIface->tlsRequested() != SMTPSessionInterface::ForceNoTLS)
- || m_sessionIface->tlsRequested() == SMTPSessionInterface::ForceTLS) {
- // For now we're gonna force it on.
-
- if (execute(Command::STARTTLS)) {
-
- // re-issue EHLO to refresh the capability list (could be have
- // been faked before TLS was enabled):
- EHLOCommand ehloCmdPostTLS(m_sessionIface, m_hostname);
- if (!execute(&ehloCmdPostTLS)) {
- smtp_close();
- return false;
- }
- }
- }
- // Now we try and login
- if (!authenticate()) {
- smtp_close();
- return false;
- }
-
- m_sOldPort = m_port;
- m_sOldServer = m_sServer;
- m_sOldUser = m_sUser;
- m_sOldPass = m_sPass;
-
- return true;
-}
-
-bool SMTPProtocol::authenticate()
-{
- // return with success if the server doesn't support SMTP-AUTH or an user
- // name is not specified and metadata doesn't tell us to force it.
- if ((m_sUser.isEmpty() || !m_sessionIface->haveCapability("AUTH")) &&
- m_sessionIface->requestedSaslMethod().isEmpty()) {
- return true;
- }
-
- KIO::AuthInfo authInfo;
- authInfo.username = m_sUser;
- authInfo.password = m_sPass;
- authInfo.prompt = i18n("Username and password for your SMTP account:");
-
- QStringList strList;
-
- if (!m_sessionIface->requestedSaslMethod().isEmpty()) {
- strList.append(m_sessionIface->requestedSaslMethod());
- } else {
- strList = m_sessionIface->capabilities().saslMethodsQSL();
- }
-
- const QByteArray ba = strList.join(QStringLiteral(" ")).toLatin1();
- AuthCommand authCmd(m_sessionIface, ba.constData(), m_sServer, authInfo);
- bool ret = execute(&authCmd);
- m_sUser = authInfo.username;
- m_sPass = authInfo.password;
- return ret;
-}
-
-void SMTPProtocol::smtp_close(bool nice)
-{
- if (!m_opened) { // We're already closed
- return;
- }
-
- if (nice) {
- execute(Command::QUIT);
- }
- qCDebug(SMTP_LOG) << "closing connection";
- disconnectFromHost();
- m_sOldServer.clear();
- m_sOldUser.clear();
- m_sOldPass.clear();
-
- m_sessionIface->clearCapabilities();
- qDeleteAll(mPendingCommandQueue);
- mPendingCommandQueue.clear();
- qDeleteAll(mSentCommandQueue);
- mSentCommandQueue.clear();
-
- m_opened = false;
-}
-
-void SMTPProtocol::stat(const QUrl &url)
-{
- QString path = url.path();
- error(KIO::ERR_DOES_NOT_EXIST, url.path());
-}
diff --git a/kioslave/src/smtp/smtp.h b/kioslave/src/smtp/smtp.h
deleted file mode 100644
index febc3ab..0000000
--- a/kioslave/src/smtp/smtp.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- c++ -*-
- * Copyright (c) 2000, 2001 Alex Zepeda <zipzippy at sonic.net>
- * Copyright (c) 2001 Michael H�kel <Michael at Haeckel.Net>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _SMTP_H
-#define _SMTP_H
-
-#include <kio/tcpslavebase.h>
-
-#include "capabilities.h"
-
-#include <QQueue>
-#include <QByteArray>
-
-class QUrl;
-
-namespace KioSMTP
-{
-class Response;
-class TransactionState;
-class Command;
-class SMTPSessionInterface;
-class KioSlaveSession;
-}
-
-class SMTPProtocol : public KIO::TCPSlaveBase
-{
- friend class KioSMTP::KioSlaveSession;
-public:
- SMTPProtocol(const QByteArray &pool, const QByteArray &app, bool useSSL);
- virtual ~ SMTPProtocol();
-
- virtual void setHost(const QString &host, quint16 port,
- const QString &user, const QString &pass) Q_DECL_OVERRIDE;
-
- void special(const QByteArray &aData) Q_DECL_OVERRIDE;
- void put(const QUrl &url, int permissions, KIO::JobFlags flags) Q_DECL_OVERRIDE;
- void stat(const QUrl &url) Q_DECL_OVERRIDE;
- void openConnection() Q_DECL_OVERRIDE;
- void closeConnection() Q_DECL_OVERRIDE;
-
-protected:
-
- bool smtp_open(const QString &fakeHostName);
-
- /** Closes the connection. If @p nice is true (default), then QUIT
- is sent and it's reponse waited for. */
- void smtp_close(bool nice = true);
-
- /** Execute command @p cmd */
- bool execute(KioSMTP::Command *cmd, KioSMTP::TransactionState *ts = 0);
- /** Execute a command of type @p type */
- bool execute(int type, KioSMTP::TransactionState *ts = 0);
- /** Execute the queued commands. If something goes horribly wrong
- (sending command oline fails, getting response fails or some
- command raises the failedFatally() flag in @p ts, shuts down the
- connection with <code>smtp_close( false )</code>. If The
- transaction fails gracefully (<code>ts->failed()</code> is
- true), issues a RSET command.
-
- @return true if transaction succeeded, false otherwise.
- **/
- bool executeQueuedCommands(KioSMTP::TransactionState *ts);
-
- /** Parse a single response from the server. Single- vs. multiline
- responses are correctly detected.
-
- @param ok if not 0, returns whether response parsing was
- successful. Don't confuse this with negative responses
- (e.g. 5xx), which you can check for using
- @ref Response::isNegative()
- @return the @ref Response object representing the server response.
- **/
- KioSMTP::Response getResponse(bool *ok);
-
- bool authenticate();
-
- bool sendCommandLine(const QByteArray &cmd);
- QByteArray collectPipelineCommands(KioSMTP::TransactionState *ts);
- bool batchProcessResponses(KioSMTP::TransactionState *ts);
-
- void queueCommand(KioSMTP::Command *command)
- {
- mPendingCommandQueue.enqueue(command);
- }
- void queueCommand(int type);
-
- quint16 m_sOldPort;
- quint16 m_port;
- bool m_opened;
- QString m_sServer, m_sOldServer;
- QString m_sUser, m_sOldUser;
- QString m_sPass, m_sOldPass;
- QString m_hostname;
-
- typedef QQueue<KioSMTP::Command *> CommandQueue;
- CommandQueue mPendingCommandQueue;
- CommandQueue mSentCommandQueue;
- KioSMTP::SMTPSessionInterface *m_sessionIface;
-};
-
-#endif // _SMTP_H
diff --git a/kioslave/src/smtp/smtp.protocol b/kioslave/src/smtp/smtp.protocol
deleted file mode 100644
index c7bf05b..0000000
--- a/kioslave/src/smtp/smtp.protocol
+++ /dev/null
@@ -1,16 +0,0 @@
-[Protocol]
-exec=kf5/kio/smtp
-protocol=smtp
-Capabilities=SASL
-input=none
-output=filesystem
-listing=Name,Type,Size
-reading=false
-writing=true
-deleting=false
-source=true
-makedir=false
-linking=false
-moving=false
-X-DocPath=kioslave5/smtp/index.html
-Icon=mail-folder-outbox
diff --git a/kioslave/src/smtp/smtps.protocol b/kioslave/src/smtp/smtps.protocol
deleted file mode 100644
index 98222d7..0000000
--- a/kioslave/src/smtp/smtps.protocol
+++ /dev/null
@@ -1,16 +0,0 @@
-[Protocol]
-exec=kf5/kio/smtp
-protocol=smtps
-Capabilities=SASL
-input=none
-output=filesystem
-listing=Name,Type,Size
-reading=false
-writing=true
-deleting=false
-source=true
-makedir=false
-linking=false
-moving=false
-X-DocPath=kioslave5/smtp/index.html
-Icon=mail-folder-outbox
diff --git a/kioslave/src/smtp/smtpsessioninterface.cpp b/kioslave/src/smtp/smtpsessioninterface.cpp
deleted file mode 100644
index b0e33df..0000000
--- a/kioslave/src/smtp/smtpsessioninterface.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- Copyright (c) 2010 Volker Krause <vkrause at kde.org>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#include "smtpsessioninterface.h"
-
-using namespace KioSMTP;
-
-SMTPSessionInterface::~SMTPSessionInterface()
-{
-}
-
-void SMTPSessionInterface::parseFeatures(const KioSMTP::Response &ehloResponse)
-{
- m_capabilities = Capabilities::fromResponse(ehloResponse);
-}
-
-const Capabilities &KioSMTP::SMTPSessionInterface::capabilities() const
-{
- return m_capabilities;
-}
-
-void SMTPSessionInterface::clearCapabilities()
-{
- m_capabilities.clear();
-}
-
-bool SMTPSessionInterface::haveCapability(const char *cap) const
-{
- return m_capabilities.have(cap);
-}
-
-bool SMTPSessionInterface::canPipelineCommands() const
-{
- return haveCapability("PIPELINING") && pipeliningRequested();
-}
-
-bool KioSMTP::SMTPSessionInterface::eightBitMimeRequested() const
-{
- return false;
-}
-
-bool KioSMTP::SMTPSessionInterface::pipeliningRequested() const
-{
- return true;
-}
diff --git a/kioslave/src/smtp/smtpsessioninterface.h b/kioslave/src/smtp/smtpsessioninterface.h
deleted file mode 100644
index 0bb7b4f..0000000
--- a/kioslave/src/smtp/smtpsessioninterface.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- Copyright (c) 2010 Volker Krause <vkrause at kde.org>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#ifndef KIOSMTP_SMTPSESSIONINTERFACE_H
-#define KIOSMTP_SMTPSESSIONINTERFACE_H
-
-#include "capabilities.h"
-
-class QByteArray;
-class QString;
-
-namespace KIO
-{
-class AuthInfo;
-}
-
-namespace KioSMTP
-{
-
-class Response;
-
-/** Interface to the SMTP session for command classes.
- * There are sub-classes for the in-process mode, the KIO slave mode and for unit testing.
- * @since 4.6
- */
-class SMTPSessionInterface
-{
-public:
- /** TLS request state. */
- enum TLSRequestState {
- UseTLSIfAvailable,
- ForceTLS,
- ForceNoTLS
- };
-
- virtual ~SMTPSessionInterface();
- virtual bool startSsl() = 0;
-
- /** Parse capability response from the server. */
- void parseFeatures(const KioSMTP::Response &ehloResponse);
-
- /** Returns the server reported capabilities. */
- const Capabilities &capabilities() const;
-
- /** Clear the capabilities reported by the server (e.g. when reconnecting the session) */
- void clearCapabilities();
-
- /** This is a pure convenience wrapper around
- * @ref KioSMTP::Capabilities::have()
- */
- virtual bool haveCapability(const char *cap) const;
-
- /** @return true is pipelining is available and allowed by metadata */
- bool canPipelineCommands() const;
-
- virtual void error(int id, const QString &msg) = 0;
- /** Show information message box with message @p msg and caption @p caption. */
- virtual void informationMessageBox(const QString &msg, const QString &caption) = 0;
- virtual bool openPasswordDialog(KIO::AuthInfo &authInfo) = 0;
- virtual void dataReq() = 0;
- virtual int readData(QByteArray &ba) = 0;
-
- /** SASL method requested for authentication. */
- virtual QString requestedSaslMethod() const = 0;
- /** TLS requested for encryption. */
- virtual TLSRequestState tlsRequested() const = 0;
- /** LF2CRLF and dot stuffing requested. */
- virtual bool lf2crlfAndDotStuffingRequested() const = 0;
- /** 8bit MIME support requested. */
- virtual bool eightBitMimeRequested() const;
- /** Pipelining has been requested. */
- virtual bool pipeliningRequested() const;
-
-private :
- KioSMTP::Capabilities m_capabilities;
-};
-
-}
-
-#endif
diff --git a/kioslave/src/smtp/tests/CMakeLists.txt b/kioslave/src/smtp/tests/CMakeLists.txt
deleted file mode 100644
index e97ee9b..0000000
--- a/kioslave/src/smtp/tests/CMakeLists.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-include(ECMMarkAsTest)
-
-set(QT_REQUIRED_VERSION "5.4.0")
-find_package(Qt5Test ${QT_REQUIRED_VERSION} CONFIG REQUIRED)
-
-set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
-
-########### next target ###############
-
-set(test_responseparser_SRCS test_responseparser.cpp )
-
-add_executable( test_responseparser ${test_responseparser_SRCS} )
-add_test( test_responseparser test_responseparser )
-ecm_mark_as_test(smtp-responseparser)
-target_link_libraries(test_responseparser Qt5::Test KF5::I18n KF5::KIOCore)
-
-########### next target ###############
-
-set(test_headergeneration_SRCS test_headergeneration.cpp)
-ecm_qt_declare_logging_category(test_headergeneration_SRCS HEADER smtp_debug.h IDENTIFIER SMTP_LOG CATEGORY_NAME log_smtp)
-
-add_executable( test_headergeneration ${test_headergeneration_SRCS} )
-add_test( test_headergeneration test_headergeneration )
-ecm_mark_as_test(smtp-headergeneration)
-
-target_link_libraries(test_headergeneration Qt5::Test )
-
-
-########### next target ###############
-set(test_commands_SRCS test_commands.cpp )
-ecm_qt_declare_logging_category(test_commands_SRCS HEADER smtp_debug.h IDENTIFIER SMTP_LOG CATEGORY_NAME log_smtp)
-
-include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${Sasl2_INCLUDE_DIRS} ${kioslave_SOURCE_DIR}/src/)
-
-add_executable( test_commands ${test_commands_SRCS} )
-add_test( test_commands test_commands )
-ecm_mark_as_test(smtp-commands)
-target_link_libraries(test_commands KF5::KIOCore ${Sasl2_LIBRARIES} Qt5::Test KF5::I18n)
-
-
-########### next target ###############
-set(interactivesmtpserver_SRCS interactivesmtpserver.cpp )
-
-add_executable( interactivesmtpserver ${interactivesmtpserver_SRCS} )
-ecm_mark_as_test(smtp-interactivesmtpserver)
-target_link_libraries(interactivesmtpserver Qt5::Test Qt5::Widgets Qt5::Network)
-
-
-########### next target ###############
-set(test_capabilities_SRCS test_capabilities.cpp ../capabilities.cpp )
-
-include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${kioslave_SOURCE_DIR}/src/smtp)
-
-add_executable( test_capabilities ${test_capabilities_SRCS} )
-ecm_mark_as_test(test-capabilities)
-target_link_libraries(test_capabilities KF5::KIOCore)
-
-
-########### next target ###############
-set( test_request_source requesttest.cpp ../request.cpp )
-ecm_qt_declare_logging_category(test_request_source HEADER smtp_debug.h IDENTIFIER SMTP_LOG CATEGORY_NAME log_smtp)
-
-add_executable( requesttest ${test_request_source})
-add_test(requesttest requesttest)
-ecm_mark_as_test(requesttest)
-target_link_libraries( requesttest Qt5::Test Qt5::Gui)
-
diff --git a/kioslave/src/smtp/tests/fakesession.h b/kioslave/src/smtp/tests/fakesession.h
deleted file mode 100644
index 2b23f12..0000000
--- a/kioslave/src/smtp/tests/fakesession.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- Copyright (c) 2010 Volker Krause <vkrause at kde.org>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#ifndef KIOSMTP_FAKESESSION_H
-#define KIOSMTP_FAKESESSION_H
-
-#include "smtpsessioninterface.h"
-
-#include <QStringList>
-#include <kio/slavebase.h>
-
-namespace KioSMTP
-{
-
-class FakeSession : public SMTPSessionInterface
-{
-public:
- FakeSession()
- {
- clear();
- }
-
- //
- // public members to control the API emulation below:
- //
- bool startTLSReturnCode;
- bool usesTLS; // ### unused below, most likely something wrong in the tests...
- int lastErrorCode;
- QString lastErrorMessage;
- QString lastMessageBoxText;
- QByteArray nextData;
- int nextDataReturnCode;
- QStringList caps;
-
- bool eightBitMime;
- bool lf2crlfAndDotStuff;
- bool pipelining;
- QString saslMethod;
-
- void clear()
- {
- startTLSReturnCode = true;
- usesTLS = false;
- lastErrorCode = 0;
- lastErrorMessage.clear();
- lastMessageBoxText.clear();
- nextData.resize(0);
- nextDataReturnCode = -1;
- caps.clear();
-
- lf2crlfAndDotStuff = false;
- saslMethod.clear();
- }
-
- //
- // emulated API:
- //
- bool startSsl() Q_DECL_OVERRIDE {
- return startTLSReturnCode;
- }
- bool haveCapability(const char *cap) const Q_DECL_OVERRIDE
- {
- return caps.contains(QLatin1String(cap));
- }
- void error(int id, const QString &msg) Q_DECL_OVERRIDE {
- lastErrorCode = id;
- lastErrorMessage = msg;
- qWarning() << id << msg;
- }
- void informationMessageBox(const QString &msg, const QString &caption) Q_DECL_OVERRIDE {
- Q_UNUSED(caption);
- lastMessageBoxText = msg;
- }
- bool openPasswordDialog(KIO::AuthInfo &) Q_DECL_OVERRIDE {
- return true;
- }
- void dataReq() Q_DECL_OVERRIDE {
- /* noop */
- }
- int readData(QByteArray &ba) Q_DECL_OVERRIDE {
- ba = nextData;
- return nextDataReturnCode;
- }
-
- bool lf2crlfAndDotStuffingRequested() const Q_DECL_OVERRIDE
- {
- return lf2crlfAndDotStuff;
- }
- QString requestedSaslMethod() const Q_DECL_OVERRIDE
- {
- return saslMethod;
- }
- TLSRequestState tlsRequested() const Q_DECL_OVERRIDE
- {
- return SMTPSessionInterface::UseTLSIfAvailable;
- }
-};
-
-}
-
-#include "smtpsessioninterface.cpp"
-#include "capabilities.cpp"
-
-#endif
diff --git a/kioslave/src/smtp/tests/interactivesmtpserver.cpp b/kioslave/src/smtp/tests/interactivesmtpserver.cpp
deleted file mode 100644
index 95cf711..0000000
--- a/kioslave/src/smtp/tests/interactivesmtpserver.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/* -*- c++ -*-
- interactivesmtpserver.cc
-
- Code based on the serverSocket example by Jesper Pedersen.
-
- This file is part of the testsuite of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2004 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#include <QtCore/QString>
-#include <QtCore/QTextStream>
-#include <QApplication>
-#include <QLabel>
-#include <QLineEdit>
-#include <QPushButton>
-#include <QTextEdit>
-#include <QWidget>
-#include <QTcpSocket>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-
-#include "interactivesmtpserver.h"
-
-static const QHostAddress localhost(0x7f000001); // 127.0.0.1
-
-static QString err2str(QAbstractSocket::SocketError error)
-{
- switch (error) {
- case QAbstractSocket::ConnectionRefusedError: return QStringLiteral("Connection refused");
- case QAbstractSocket::HostNotFoundError: return QStringLiteral("Host not found");
- default: return QStringLiteral("Unknown error");
- }
-}
-
-static QString escape(QString s)
-{
- return s
- .replace(QLatin1Char('&'), QLatin1String("&"))
- .replace(QLatin1Char('>'), QLatin1String(">"))
- .replace(QLatin1Char('<'), QLatin1String("<"))
- .replace(QLatin1Char('"'), QLatin1String("""))
- ;
-}
-
-static QString trim(const QString &s)
-{
- if (s.endsWith(QLatin1String("\r\n"))) {
- return s.left(s.length() - 2);
- }
- if (s.endsWith(QLatin1String("\r")) || s.endsWith(QLatin1String("\n"))) {
- return s.left(s.length() - 1);
- }
- return s;
-}
-
-InteractiveSMTPServerWindow::~InteractiveSMTPServerWindow()
-{
- if (mSocket) {
- mSocket->close();
- if (mSocket->state() == QAbstractSocket::ClosingState)
- connect(mSocket, SIGNAL(disconnected()),
- mSocket, SLOT(deleteLater()));
- else {
- mSocket->deleteLater();
- }
- mSocket = 0;
- }
-}
-
-void InteractiveSMTPServerWindow::slotSendResponse()
-{
- const QString line = mLineEdit->text();
- mLineEdit->clear();
- QTextStream s(mSocket);
- s << line + QLatin1String("\r\n");
- slotDisplayServer(line);
-}
-
-InteractiveSMTPServer::InteractiveSMTPServer(QObject *parent)
- : QTcpServer(parent)
-{
- listen(localhost, 2525);
- setMaxPendingConnections(1);
-
- connect(this, SIGNAL(newConnection()), this, SLOT(newConnectionAvailable()));
-}
-
-void InteractiveSMTPServer::newConnectionAvailable()
-{
- InteractiveSMTPServerWindow *w = new InteractiveSMTPServerWindow(nextPendingConnection());
- w->show();
-}
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
-
- InteractiveSMTPServer server;
-
- qDebug("Server should now listen on localhost:2525");
- qDebug("Hit CTRL-C to quit.");
-
- return app.exec();
-}
-
-InteractiveSMTPServerWindow::InteractiveSMTPServerWindow(QTcpSocket *socket, QWidget *parent)
- : QWidget(parent), mSocket(socket)
-{
- QPushButton *but;
- Q_ASSERT(socket);
-
- QVBoxLayout *vlay = new QVBoxLayout(this);
-
- mTextEdit = new QTextEdit(this);
- vlay->addWidget(mTextEdit, 1);
- QWidget *mLayoutWidget = new QWidget;
- vlay->addWidget(mLayoutWidget);
-
- QHBoxLayout *hlay = new QHBoxLayout(mLayoutWidget);
-
- mLineEdit = new QLineEdit(this);
- mLabel = new QLabel(QStringLiteral("&Response:"), this);
- mLabel->setBuddy(mLineEdit);
- but = new QPushButton(QStringLiteral("&Send"), this);
- hlay->addWidget(mLabel);
- hlay->addWidget(mLineEdit, 1);
- hlay->addWidget(but);
-
- connect(mLineEdit, SIGNAL(returnPressed()), SLOT(slotSendResponse()));
- connect(but, SIGNAL(clicked()), SLOT(slotSendResponse()));
-
- but = new QPushButton(QStringLiteral("&Close Connection"), this);
- vlay->addWidget(but);
-
- connect(but, SIGNAL(clicked()), SLOT(slotConnectionClosed()));
-
- connect(socket, SIGNAL(disconnected()), SLOT(slotConnectionClosed()));
- connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
- SLOT(slotError(QAbstractSocket::SocketError)));
- connect(socket, SIGNAL(readyRead()), SLOT(slotReadyRead()));
-
- mLineEdit->setText(QStringLiteral("220 hi there"));
- mLineEdit->setFocus();
-}
-
-void InteractiveSMTPServerWindow::slotDisplayClient(const QString &s)
-{
- mTextEdit->append(QLatin1String("C:") + escape(s));
-}
-
-void InteractiveSMTPServerWindow::slotDisplayServer(const QString &s)
-{
- mTextEdit->append(QLatin1String("S:") + escape(s));
-}
-
-void InteractiveSMTPServerWindow::slotDisplayMeta(const QString &s)
-{
- mTextEdit->append(QLatin1String("<font color=\"red\">") + escape(s) + QLatin1String("</font>"));
-}
-
-void InteractiveSMTPServerWindow::slotReadyRead()
-{
- while (mSocket->canReadLine()) {
- slotDisplayClient(trim(QString::fromLatin1(mSocket->readLine())));
- }
-}
-
-void InteractiveSMTPServerWindow::slotError(QAbstractSocket::SocketError error)
-{
- slotDisplayMeta(QString::fromLatin1("E: %1").arg(err2str(error)));
-}
-
-void InteractiveSMTPServerWindow::slotConnectionClosed()
-{
- slotDisplayMeta(QStringLiteral("Connection closed by peer"));
-}
-
-void InteractiveSMTPServerWindow::slotCloseConnection()
-{
- mSocket->close();
-}
-
diff --git a/kioslave/src/smtp/tests/interactivesmtpserver.h b/kioslave/src/smtp/tests/interactivesmtpserver.h
deleted file mode 100644
index 72d2676..0000000
--- a/kioslave/src/smtp/tests/interactivesmtpserver.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef INTERACTIVESMTPSERVER_H
-#define INTERACTIVESMTPSERVER_H
-
-/* -*- c++ -*-
- interactivesmtpserver.h
-
- Code based on the serverSocket example by Jesper Pedersen.
-
- This file is part of the testsuite of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2004 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#include <QWidget>
-#include <QtNetwork/QTcpServer>
-
-class QLabel;
-class QLineEdit;
-class QTcpServer;
-class QTextEdit;
-
-class InteractiveSMTPServerWindow : public QWidget
-{
- Q_OBJECT
-public:
- InteractiveSMTPServerWindow(QTcpSocket *socket, QWidget *parent = Q_NULLPTR);
- ~InteractiveSMTPServerWindow();
-
-public Q_SLOTS:
- void slotSendResponse();
- void slotDisplayClient(const QString &s);
- void slotDisplayServer(const QString &s);
- void slotDisplayMeta(const QString &s);
- void slotReadyRead();
- void slotError(QAbstractSocket::SocketError error);
- void slotConnectionClosed();
- void slotCloseConnection();
-
-private:
- QTcpSocket *mSocket;
- QTextEdit *mTextEdit;
- QLineEdit *mLineEdit;
- QLabel *mLabel;
-};
-
-class InteractiveSMTPServer : public QTcpServer
-{
- Q_OBJECT
-
-public:
- InteractiveSMTPServer(QObject *parent = Q_NULLPTR);
- ~InteractiveSMTPServer() {}
-
-private Q_SLOTS:
- void newConnectionAvailable();
-};
-
-#endif
diff --git a/kioslave/src/smtp/tests/requesttest.cpp b/kioslave/src/smtp/tests/requesttest.cpp
deleted file mode 100644
index 92025c8..0000000
--- a/kioslave/src/smtp/tests/requesttest.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- Copyright (c) 2014 Montel Laurent <montel at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-#include "requesttest.h"
-#include "../request.h"
-#include <qtest.h>
-#include <QUrl>
-RequestTest::RequestTest(QObject *parent)
- : QObject(parent)
-{
-
-}
-
-RequestTest::~RequestTest()
-{
-
-}
-
-void RequestTest::shouldHaveDefaultValue()
-{
- KioSMTP::Request request;
- QVERIFY(request.to().isEmpty());
- QVERIFY(request.cc().isEmpty());
- QVERIFY(request.bcc().isEmpty());
- QVERIFY(request.emitHeaders());
- QVERIFY(!request.is8BitBody());
- QVERIFY(request.profileName().isEmpty());
- QVERIFY(request.fromAddress().isEmpty());
- QVERIFY(request.heloHostname().isEmpty());
- QCOMPARE(request.size(), static_cast<unsigned int>(0));
-}
-
-void RequestTest::shouldParseRequest_data()
-{
- QTest::addColumn<QUrl>("smtpurl");
- QTest::addColumn<QString>("to");
- QTest::addColumn<QString>("from");
- QTest::addColumn<QString>("cc");
- QTest::addColumn<QString>("bcc");
- QTest::addColumn<bool>("emitheaders");
- QTest::addColumn<unsigned int>("size");
- QTest::newRow("correct url") << QUrl(QStringLiteral("smtps://smtp.kde.org:465/send?headers=0&from=foo%40kde.org&to=foo%40kde.org&size=617"))
- << QStringLiteral("foo at kde.org")
- << QStringLiteral("foo at kde.org")
- << QString()
- << QString()
- << false
- << static_cast<unsigned int>(617);
-}
-
-void RequestTest::shouldParseRequest()
-{
- QFETCH(QUrl, smtpurl);
- QFETCH(QString, to);
- QFETCH(QString, from);
- QFETCH(QString, cc);
- QFETCH(QString, bcc);
- QFETCH(bool, emitheaders);
- QFETCH(unsigned int, size);
-
- KioSMTP::Request request = KioSMTP::Request::fromURL(smtpurl);
- QCOMPARE(request.to().join(QLatin1String(",")), to);
- QCOMPARE(request.cc().join(QLatin1String(",")), cc);
- QCOMPARE(request.fromAddress(), from);
- QCOMPARE(request.bcc().join(QLatin1String(",")), bcc);
- QCOMPARE(request.size(), size);
- QCOMPARE(request.emitHeaders(), emitheaders);
-}
-
-QTEST_MAIN(RequestTest)
diff --git a/kioslave/src/smtp/tests/requesttest.h b/kioslave/src/smtp/tests/requesttest.h
deleted file mode 100644
index 645d1bf..0000000
--- a/kioslave/src/smtp/tests/requesttest.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- Copyright (c) 2014 Montel Laurent <montel at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef REQUESTTEST_H
-#define REQUESTTEST_H
-
-#include <QObject>
-
-class RequestTest : public QObject
-{
- Q_OBJECT
-public:
- explicit RequestTest(QObject *parent = Q_NULLPTR);
- ~RequestTest();
-private Q_SLOTS:
- void shouldHaveDefaultValue();
- void shouldParseRequest_data();
- void shouldParseRequest();
-};
-
-#endif // REQUESTTEST_H
diff --git a/kioslave/src/smtp/tests/test_capabilities.cpp b/kioslave/src/smtp/tests/test_capabilities.cpp
deleted file mode 100644
index f0a275c..0000000
--- a/kioslave/src/smtp/tests/test_capabilities.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <assert.h>
-#include "capabilities.h"
-#include <QObject>
-
-using namespace KioSMTP;
-
-int main()
-{
- Capabilities c;
-
- const QString size_cap = QObject::tr("SIZE 12");
- c.add(size_cap);
- // Capability was added
- assert(c.have("SIZE"));
-
- const QString expected_response = QObject::tr("SIZE=12");
- const QString actual_response = c.createSpecialResponse(false);
- // SIZE actually handled
- assert(actual_response == expected_response);
-
- const QString auth_cap = QObject::tr("AUTH GSSAPI");
- c.add(auth_cap);
- c.add(auth_cap);
- // Duplicate methods was removed
- assert(c.saslMethodsQSL().length() == 1);
-}
diff --git a/kioslave/src/smtp/tests/test_commands.cpp b/kioslave/src/smtp/tests/test_commands.cpp
deleted file mode 100644
index 0338715..0000000
--- a/kioslave/src/smtp/tests/test_commands.cpp
+++ /dev/null
@@ -1,677 +0,0 @@
-#include <kio/global.h>
-#include <kio/authinfo.h>
-#include <qdebug.h>
-
-#define KIOSMTP_COMPARATORS // for TransactionState::operator==
-#include "fakesession.h"
-#include "command.h"
-#include "response.h"
-#include "transactionstate.h"
-#include "common.h"
-#include "smtp_debug.h"
-#include <assert.h>
-
-using namespace KioSMTP;
-
-static const char *foobarbaz = ".Foo bar baz";
-static const unsigned int foobarbaz_len = qstrlen(foobarbaz);
-
-static const char *foobarbaz_dotstuffed = "..Foo bar baz";
-static const unsigned int foobarbaz_dotstuffed_len = qstrlen(foobarbaz_dotstuffed);
-
-static const char *foobarbaz_lf = ".Foo bar baz\n";
-static const unsigned int foobarbaz_lf_len = qstrlen(foobarbaz_lf);
-
-static const char *foobarbaz_crlf = "..Foo bar baz\r\n";
-static const unsigned int foobarbaz_crlf_len = qstrlen(foobarbaz_crlf);
-
-static void checkSuccessfulTransferCommand(bool, bool, bool, bool, bool);
-
-int main(int, char **)
-{
-
- if (!initSASL()) {
- exit(-1);
- }
-
- FakeSession smtp;
- Response r;
- TransactionState ts, ts2;
-
- //
- // EHLO / HELO
- //
-
- smtp.clear();
- EHLOCommand ehlo(&smtp, QStringLiteral("mail.example.com"));
- // flags
- assert(ehlo.closeConnectionOnError());
- assert(ehlo.mustBeLastInPipeline());
- assert(!ehlo.mustBeFirstInPipeline());
-
- // initial state
- assert(!ehlo.isComplete());
- assert(!ehlo.doNotExecute(0));
- assert(!ehlo.needsResponse());
-
- // dynamics 1: EHLO succeeds
- assert(ehlo.nextCommandLine(0) == "EHLO mail.example.com\r\n");
- assert(!ehlo.isComplete()); // EHLO may fail and we then try HELO
- assert(ehlo.needsResponse());
- r.clear();
- r.parseLine("250-mail.example.net\r\n");
- r.parseLine("250-PIPELINING\r\n");
- r.parseLine("250 8BITMIME\r\n");
- assert(ehlo.processResponse(r, 0) == true);
- assert(ehlo.isComplete());
- assert(!ehlo.needsResponse());
- assert(smtp.lastErrorCode == 0);
- assert(smtp.lastErrorMessage.isNull());
-
- // dynamics 2: EHLO fails with "unknown command"
- smtp.clear();
- EHLOCommand ehlo2(&smtp, QStringLiteral("mail.example.com"));
- ehlo2.nextCommandLine(0);
- r.clear();
- r.parseLine("500 unknown command\r\n");
- assert(ehlo2.processResponse(r, 0) == true);
- assert(!ehlo2.isComplete());
- assert(!ehlo2.needsResponse());
- assert(ehlo2.nextCommandLine(0) == "HELO mail.example.com\r\n");
- assert(ehlo2.isComplete());
- assert(ehlo2.needsResponse());
- r.clear();
- r.parseLine("250 mail.example.net\r\n");
- assert(ehlo2.processResponse(r, 0) == true);
- assert(!ehlo2.needsResponse());
- assert(smtp.lastErrorCode == 0);
- assert(smtp.lastErrorMessage.isNull());
-
- // dynamics 3: EHLO fails with unknown response code
- smtp.clear();
- EHLOCommand ehlo3(&smtp, QStringLiteral("mail.example.com"));
- ehlo3.nextCommandLine(0);
- r.clear();
- r.parseLine("545 you don't know me\r\n");
- assert(ehlo3.processResponse(r, 0) == false);
- assert(ehlo3.isComplete());
- assert(!ehlo3.needsResponse());
- assert(smtp.lastErrorCode == KIO::ERR_UNKNOWN);
-
- // dynamics 4: EHLO _and_ HELO fail with "command unknown"
- smtp.clear();
- EHLOCommand ehlo4(&smtp, QStringLiteral("mail.example.com"));
- ehlo4.nextCommandLine(0);
- r.clear();
- r.parseLine("500 unknown command\r\n");
- ehlo4.processResponse(r, 0);
- ehlo4.nextCommandLine(0);
- r.clear();
- r.parseLine("500 unknown command\r\n");
- assert(ehlo4.processResponse(r, 0) == false);
- assert(ehlo4.isComplete());
- assert(!ehlo4.needsResponse());
- assert(smtp.lastErrorCode == KIO::ERR_INTERNAL_SERVER);
-
- //
- // STARTTLS
- //
-
- smtp.clear();
- StartTLSCommand tls(&smtp);
- // flags
- assert(tls.closeConnectionOnError());
- assert(tls.mustBeLastInPipeline());
- assert(!tls.mustBeFirstInPipeline());
-
- // initial state
- assert(!tls.isComplete());
- assert(!tls.doNotExecute(0));
- assert(!tls.needsResponse());
-
- // dynamics 1: ok from server, TLS negotiation successful
- ts.clear();
- ts2 = ts;
- assert(tls.nextCommandLine(&ts) == "STARTTLS\r\n");
- assert(ts == ts2);
- assert(tls.isComplete());
- assert(tls.needsResponse());
- r.clear();
- r.parseLine("220 Go ahead");
- smtp.startTLSReturnCode = true;
- assert(tls.processResponse(r, &ts) == true);
- assert(!tls.needsResponse());
- assert(smtp.lastErrorCode == 0);
-
- // dynamics 2: NAK from server
- smtp.clear();
- StartTLSCommand tls2(&smtp);
- ts.clear();
- tls2.nextCommandLine(&ts);
- r.clear();
- r.parseLine("454 TLS temporarily disabled");
- smtp.startTLSReturnCode = true;
- assert(tls2.processResponse(r, &ts) == false);
- assert(!tls2.needsResponse());
- assert(smtp.lastErrorCode == KIO::ERR_SERVICE_NOT_AVAILABLE);
-
- // dynamics 3: ok from server, TLS negotiation unsuccessful
- smtp.clear();
- StartTLSCommand tls3(&smtp);
- ts.clear();
- tls3.nextCommandLine(&ts);
- r.clear();
- r.parseLine("220 Go ahead");
- smtp.startTLSReturnCode = false;
- assert(tls.processResponse(r, &ts) == false);
- assert(!tls.needsResponse());
-
- //
- // AUTH
- //
-
- smtp.clear();
- QStringList mechs;
- mechs.append(QStringLiteral("PLAIN"));
- smtp.saslMethod = QStringLiteral("PLAIN");
- KIO::AuthInfo authInfo;
- authInfo.username = QStringLiteral("user");
- authInfo.password = QStringLiteral("pass");
- AuthCommand auth(&smtp, "PLAIN", QStringLiteral("mail.example.com"), authInfo);
- // flags
- assert(auth.closeConnectionOnError());
- assert(auth.mustBeLastInPipeline());
- assert(!auth.mustBeFirstInPipeline());
-
- // initial state
- assert(!auth.isComplete());
- assert(!auth.doNotExecute(0));
- assert(!auth.needsResponse());
-
- // dynamics 1: TLS, so AUTH should include initial-response:
- smtp.usesTLS = true;
- ts.clear();
- ts2 = ts;
- assert(auth.nextCommandLine(&ts) == "AUTH PLAIN dXNlcgB1c2VyAHBhc3M=\r\n");
- assert(auth.isComplete());
- assert(auth.needsResponse());
- assert(ts == ts2);
- r.clear();
- r.parseLine("250 OK");
-
- // dynamics 2: No TLS, so AUTH should not include initial-response:
- /* FIXME fails since nothing evaluates useTLS = false anywhere...
- smtp.clear();
- smtp.saslMethod = "PLAIN";
- smtp.usesTLS = false;
- authInfo = KIO::AuthInfo();
- authInfo.username = "user";
- authInfo.password = "pass";
- AuthCommand auth2( &smtp, "PLAIN", "mail.example.com", authInfo );
- ts.clear();
- assert( auth2.nextCommandLine( &ts ) == "AUTH PLAIN\r\n" );
- assert( !auth2.isComplete() );
- assert( auth2.needsResponse() );
- r.clear();
- r.parseLine( "334 Go on" );
- assert( auth2.processResponse( r, &ts ) == true );
- assert( auth2.nextCommandLine( &ts ) == "dXNlcgB1c2VyAHBhc3M=\r\n" );
- assert( auth2.isComplete() );
- assert( auth2.needsResponse() );*/
-
- // dynamics 3: LOGIN
- smtp.clear();
- smtp.saslMethod = QStringLiteral("LOGIN");
- mechs.clear();
- mechs.append(QStringLiteral("LOGIN"));
- authInfo = KIO::AuthInfo();
- authInfo.username = QStringLiteral("user");
- authInfo.password = QStringLiteral("pass");
- AuthCommand auth3(&smtp, "LOGIN", QStringLiteral("mail.example.com"), authInfo);
- ts.clear();
- ts2 = ts;
- assert(auth3.nextCommandLine(&ts) == "AUTH LOGIN\r\n");
- assert(!auth3.isComplete());
- assert(auth3.needsResponse());
- r.clear();
- r.parseLine("334 VXNlcm5hbWU6");
- assert(auth3.processResponse(r, &ts) == true);
- assert(!auth3.needsResponse());
- assert(auth3.nextCommandLine(&ts) == "dXNlcg==\r\n");
- assert(!auth3.isComplete());
- assert(auth3.needsResponse());
- r.clear();
- r.parseLine("334 go on");
- assert(auth3.processResponse(r, &ts) == true);
- assert(!auth3.needsResponse());
- assert(auth3.nextCommandLine(&ts) == "cGFzcw==\r\n");
- assert(auth3.isComplete());
- assert(auth3.needsResponse());
- r.clear();
- r.parseLine("250 OK");
- assert(auth3.processResponse(r, &ts) == true);
- assert(!auth3.needsResponse());
- assert(!smtp.lastErrorCode);
- assert(ts == ts2);
-
- //
- // MAIL FROM:
- //
-
- smtp.clear();
- MailFromCommand mail(&smtp, "joe at user.org");
- // flags
- assert(!mail.closeConnectionOnError());
- assert(!mail.mustBeLastInPipeline());
- assert(!mail.mustBeFirstInPipeline());
-
- // initial state
- assert(!mail.isComplete());
- assert(!mail.doNotExecute(0));
- assert(!mail.needsResponse());
-
- // dynamics: success, no size, no 8bit
- ts.clear();
- ts2 = ts;
- assert(mail.nextCommandLine(&ts) == "MAIL FROM:<joe at user.org>\r\n");
- assert(ts2 == ts);
- assert(mail.isComplete());
- assert(mail.needsResponse());
- r.clear();
- r.parseLine("250 Ok");
- assert(mail.processResponse(r, &ts) == true);
- assert(!mail.needsResponse());
- assert(ts == ts2);
- assert(smtp.lastErrorCode == 0);
-
- // dynamics: success, size, 8bit, but no SIZE, 8BITMIME caps
- smtp.clear();
- MailFromCommand mail2(&smtp, "joe at user.org", true, 500);
- ts.clear();
- ts2 = ts;
- assert(mail2.nextCommandLine(&ts) == "MAIL FROM:<joe at user.org>\r\n");
- assert(ts == ts2);
-
- // dynamics: success, size, 8bit, SIZE, 8BITMIME caps
- smtp.clear();
- MailFromCommand mail3(&smtp, "joe at user.org", true, 500);
- ts.clear();
- ts2 = ts;
- smtp.caps << QStringLiteral("SIZE") << QStringLiteral("8BITMIME");
- assert(mail3.nextCommandLine(&ts) == "MAIL FROM:<joe at user.org> BODY=8BITMIME SIZE=500\r\n");
- assert(ts == ts2);
-
- // dynamics: failure
- smtp.clear();
- MailFromCommand mail4(&smtp, "joe at user.org");
- ts.clear();
- mail4.nextCommandLine(&ts);
- r.clear();
- r.parseLine("503 Bad sequence of commands");
- assert(mail4.processResponse(r, &ts) == false);
- assert(mail4.isComplete());
- assert(!mail4.needsResponse());
- assert(ts.failed());
- assert(!ts.failedFatally());
- assert(smtp.lastErrorCode == 0);
-
- //
- // RCPT TO:
- //
-
- smtp.clear();
- RcptToCommand rcpt(&smtp, "joe at user.org");
- // flags
- assert(!rcpt.closeConnectionOnError());
- assert(!rcpt.mustBeLastInPipeline());
- assert(!rcpt.mustBeFirstInPipeline());
-
- // initial state
- assert(!rcpt.isComplete());
- assert(!rcpt.doNotExecute(0));
- assert(!rcpt.needsResponse());
-
- // dynamics: success
- ts.clear();
- ts2 = ts;
- assert(rcpt.nextCommandLine(&ts) == "RCPT TO:<joe at user.org>\r\n");
- assert(ts == ts2);
- assert(rcpt.isComplete());
- assert(rcpt.needsResponse());
- r.clear();
- r.parseLine("250 Ok");
- assert(rcpt.processResponse(r, &ts) == true);
- assert(!rcpt.needsResponse());
- assert(ts.atLeastOneRecipientWasAccepted());
- assert(!ts.haveRejectedRecipients());
- assert(!ts.failed());
- assert(!ts.failedFatally());
- assert(smtp.lastErrorCode == 0);
-
- // dynamics: failure
- smtp.clear();
- RcptToCommand rcpt2(&smtp, "joe at user.org");
- ts.clear();
- rcpt2.nextCommandLine(&ts);
- r.clear();
- r.parseLine("530 5.7.1 Relaying not allowed!");
- assert(rcpt2.processResponse(r, &ts) == false);
- assert(rcpt2.isComplete());
- assert(!rcpt2.needsResponse());
- assert(!ts.atLeastOneRecipientWasAccepted());
- assert(ts.haveRejectedRecipients());
- assert(ts.rejectedRecipients().count() == 1);
- assert(ts.rejectedRecipients().front().recipient == QLatin1String("joe at user.org"));
- assert(ts.failed());
- assert(!ts.failedFatally());
- assert(smtp.lastErrorCode == 0);
-
- // dynamics: success and failure combined
- smtp.clear();
- RcptToCommand rcpt3(&smtp, "info at example.com");
- RcptToCommand rcpt4(&smtp, "halloween at microsoft.com");
- RcptToCommand rcpt5(&smtp, "joe at user.org");
- ts.clear();
- rcpt3.nextCommandLine(&ts);
- r.clear();
- r.parseLine("530 5.7.1 Relaying not allowed!");
- rcpt3.processResponse(r, &ts);
-
- rcpt4.nextCommandLine(&ts);
- r.clear();
- r.parseLine("250 Ok");
- rcpt4.processResponse(r, &ts);
-
- rcpt5.nextCommandLine(&ts);
- r.clear();
- r.parseLine("250 Ok");
- assert(ts.failed());
- assert(!ts.failedFatally());
- assert(ts.haveRejectedRecipients());
- assert(ts.atLeastOneRecipientWasAccepted());
- assert(smtp.lastErrorCode == 0);
-
- //
- // DATA (init)
- //
-
- smtp.clear();
- DataCommand data(&smtp);
- // flags
- assert(!data.closeConnectionOnError());
- assert(data.mustBeLastInPipeline());
- assert(!data.mustBeFirstInPipeline());
-
- // initial state
- assert(!data.isComplete());
- assert(!data.doNotExecute(0));
- assert(!data.needsResponse());
-
- // dynamics: success
- ts.clear();
- assert(data.nextCommandLine(&ts) == "DATA\r\n");
- assert(data.isComplete());
- assert(data.needsResponse());
- assert(ts.dataCommandIssued());
- assert(!ts.dataCommandSucceeded());
- r.clear();
- r.parseLine("354 Send data, end in <CR><LF>.<CR><LF>");
- assert(data.processResponse(r, &ts) == true);
- assert(!data.needsResponse());
- assert(ts.dataCommandSucceeded());
- assert(ts.dataResponse() == r);
- assert(smtp.lastErrorCode == 0);
-
- // dynamics: failure
- smtp.clear();
- DataCommand data2(&smtp);
- ts.clear();
- data2.nextCommandLine(&ts);
- r.clear();
- r.parseLine("551 No valid recipients");
- assert(data2.processResponse(r, &ts) == false);
- assert(!data2.needsResponse());
- assert(!ts.dataCommandSucceeded());
- assert(ts.dataResponse() == r);
- assert(smtp.lastErrorCode == 0);
-
- //
- // DATA (transfer)
- //
-
- TransferCommand xfer(&smtp, 0);
- // flags
- assert(!xfer.closeConnectionOnError());
- assert(!xfer.mustBeLastInPipeline());
- assert(xfer.mustBeFirstInPipeline());
-
- // initial state
- assert(!xfer.isComplete());
- assert(!xfer.needsResponse());
-
- // dynamics 1: DATA command failed
- ts.clear();
- r.clear();
- r.parseLine("551 no valid recipients");
- ts.setDataCommandIssued(true);
- ts.setDataCommandSucceeded(false, r);
- assert(xfer.doNotExecute(&ts));
-
- // dynamics 2: some recipients rejected, but not all
- smtp.clear();
- TransferCommand xfer2(&smtp, 0);
- ts.clear();
- ts.setRecipientAccepted();
- ts.addRejectedRecipient(QStringLiteral("joe at user.org"), QStringLiteral("No relaying allowed"));
- ts.setDataCommandIssued(true);
- r.clear();
- r.parseLine("354 go on");
- ts.setDataCommandSucceeded(true, r);
- // ### will change with allow-partial-delivery option:
- assert(xfer.doNotExecute(&ts));
-
- // successful dynamics with all combinations of:
- enum {
- EndInLF = 1,
- PerformDotStuff = 2,
- UngetLast = 4,
- Preloading = 8,
- Error = 16,
- EndOfOptions = 32
- };
- for (unsigned int i = 0; i < EndOfOptions; ++i)
- checkSuccessfulTransferCommand(i & Error, i & Preloading, i & UngetLast,
- i & PerformDotStuff, i & EndInLF);
-
- //
- // NOOP
- //
-
- smtp.clear();
- NoopCommand noop(&smtp);
- // flags
- assert(!noop.closeConnectionOnError());
- assert(noop.mustBeLastInPipeline());
- assert(!noop.mustBeFirstInPipeline());
-
- // initial state
- assert(!noop.isComplete());
- assert(!noop.doNotExecute(&ts));
- assert(!noop.needsResponse());
-
- // dynamics: success (failure is tested with RSET)
- assert(noop.nextCommandLine(0) == "NOOP\r\n");
- assert(noop.isComplete());
- assert(noop.needsResponse());
- r.clear();
- r.parseLine("250 Ok");
- assert(noop.processResponse(r, 0) == true);
- assert(noop.isComplete());
- assert(!noop.needsResponse());
- assert(smtp.lastErrorCode == 0);
- assert(smtp.lastErrorMessage.isNull());
-
- //
- // RSET
- //
-
- smtp.clear();
- RsetCommand rset(&smtp);
- // flags
- assert(rset.closeConnectionOnError());
- assert(!rset.mustBeLastInPipeline());
- assert(!rset.mustBeFirstInPipeline());
-
- // initial state
- assert(!rset.isComplete());
- assert(!rset.doNotExecute(&ts));
- assert(!rset.needsResponse());
-
- // dynamics: failure (success is tested with NOOP/QUIT)
- assert(rset.nextCommandLine(0) == "RSET\r\n");
- assert(rset.isComplete());
- assert(rset.needsResponse());
- r.clear();
- r.parseLine("502 command not implemented");
- assert(rset.processResponse(r, 0) == false);
- assert(rset.isComplete());
- assert(!rset.needsResponse());
- assert(smtp.lastErrorCode == 0); // an RSET failure isn't worth it, is it?
- assert(smtp.lastErrorMessage.isNull());
-
- //
- // QUIT
- //
-
- smtp.clear();
- QuitCommand quit(&smtp);
- // flags
- assert(quit.closeConnectionOnError());
- assert(quit.mustBeLastInPipeline());
- assert(!quit.mustBeFirstInPipeline());
-
- // initial state
- assert(!quit.isComplete());
- assert(!quit.doNotExecute(0));
- assert(!quit.needsResponse());
-
- // dynamics 1: success
- assert(quit.nextCommandLine(0) == "QUIT\r\n");
- assert(quit.isComplete());
- assert(quit.needsResponse());
- r.clear();
- r.parseLine("221 Goodbye");
- assert(quit.processResponse(r, 0) == true);
- assert(quit.isComplete());
- assert(!quit.needsResponse());
- assert(smtp.lastErrorCode == 0);
- assert(smtp.lastErrorMessage.isNull());
-
- // dynamics 2: success
- smtp.clear();
- QuitCommand quit2(&smtp);
- quit2.nextCommandLine(0);
- r.clear();
- r.parseLine("500 unknown command");
- assert(quit2.processResponse(r, 0) == false);
- assert(quit2.isComplete());
- assert(!quit2.needsResponse());
- assert(smtp.lastErrorCode == 0); // an QUIT failure isn't worth it, is it?
- assert(smtp.lastErrorMessage.isNull());
-
- return 0;
-}
-
-void checkSuccessfulTransferCommand(bool error, bool preload, bool ungetLast,
- bool slaveDotStuff, bool mailEndsInNewline)
-{
- qDebug() << " ===== checkTransferCommand( "
- << error << ", "
- << preload << ", "
- << ungetLast << ", "
- << slaveDotStuff << ", "
- << mailEndsInNewline << " ) =====" << endl;
-
- FakeSession smtp;
- if (slaveDotStuff) {
- smtp.lf2crlfAndDotStuff = true;
- }
-
- Response r;
-
- const char *s_pre = slaveDotStuff ?
- mailEndsInNewline ? foobarbaz_lf : foobarbaz
- :
- mailEndsInNewline ? foobarbaz_crlf : foobarbaz_dotstuffed;
- const unsigned int s_pre_len = qstrlen(s_pre);
-
- const char *s_post = mailEndsInNewline ? foobarbaz_crlf : foobarbaz_dotstuffed;
- //const unsigned int s_post_len = qstrlen( s_post );
-
- TransferCommand xfer(&smtp, preload ? s_post : 0);
-
- TransactionState ts;
- ts.setRecipientAccepted();
- ts.setDataCommandIssued(true);
- r.clear();
- r.parseLine("354 ok");
- ts.setDataCommandSucceeded(true, r);
- assert(!xfer.doNotExecute(&ts));
- if (preload) {
- assert(xfer.nextCommandLine(&ts) == s_post);
- assert(!xfer.isComplete());
- assert(!xfer.needsResponse());
- assert(!ts.failed());
- assert(smtp.lastErrorCode == 0);
- }
- smtp.nextData = QByteArray(s_pre, s_pre_len);
- smtp.nextDataReturnCode = s_pre_len;
- assert(xfer.nextCommandLine(&ts) == s_post);
- assert(!xfer.isComplete());
- assert(!xfer.needsResponse());
- assert(!ts.failed());
- assert(smtp.lastErrorCode == 0);
- smtp.nextData.resize(0);
- smtp.nextDataReturnCode = 0;
- if (ungetLast) {
- xfer.ungetCommandLine(xfer.nextCommandLine(&ts), &ts);
- assert(!xfer.isComplete());
- assert(!xfer.needsResponse());
- assert(!ts.complete());
- smtp.nextDataReturnCode = -1; // double read -> error
- }
- if (mailEndsInNewline) {
- assert(xfer.nextCommandLine(&ts) == ".\r\n");
- } else {
- assert(xfer.nextCommandLine(&ts) == "\r\n.\r\n");
- }
- assert(xfer.isComplete());
- assert(xfer.needsResponse());
- assert(!ts.complete());
- assert(!ts.failed());
- assert(smtp.lastErrorCode == 0);
- r.clear();
- if (error) {
- r.parseLine("552 Exceeded storage allocation");
- assert(xfer.processResponse(r, &ts) == false);
- assert(!xfer.needsResponse());
- assert(ts.complete());
- assert(ts.failed());
- assert(smtp.lastErrorCode == KIO::ERR_DISK_FULL);
- } else {
- r.parseLine("250 Message accepted");
- assert(xfer.processResponse(r, &ts) == true);
- assert(!xfer.needsResponse());
- assert(ts.complete());
- assert(!ts.failed());
- assert(smtp.lastErrorCode == 0);
- }
-}
-
-#ifndef NDEBUG
-# define NDEBUG
-#endif
-
-#include "command.cpp"
-#include "response.cpp"
-#include "transactionstate.cpp"
diff --git a/kioslave/src/smtp/tests/test_headergeneration.cpp b/kioslave/src/smtp/tests/test_headergeneration.cpp
deleted file mode 100644
index 9a55b8c..0000000
--- a/kioslave/src/smtp/tests/test_headergeneration.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "../request.h"
-
-#include <iostream>
-
-//using std::cout;
-//using std::endl;
-
-int main(int, char **)
-{
- static QByteArray expected =
- "From: mutz at kde.org\r\n"
- "Subject: missing subject\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n"
- "From: Marc Mutz <mutz at kde.org>\r\n"
- "Subject: missing subject\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n"
- "From: \"Mutz, Marc\" <mutz at kde.org>\r\n"
- "Subject: missing subject\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n"
- "From: =?utf-8?b?TWFyYyBNw7Z0eg==?= <mutz at kde.org>\r\n"
- "Subject: missing subject\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n"
- "From: mutz at kde.org\r\n"
- "Subject: =?utf-8?b?QmzDtmRlcyBTdWJqZWN0?=\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n"
- "From: Marc Mutz <mutz at kde.org>\r\n"
- "Subject: =?utf-8?b?QmzDtmRlcyBTdWJqZWN0?=\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n"
- "From: \"Mutz, Marc\" <mutz at kde.org>\r\n"
- "Subject: =?utf-8?b?QmzDtmRlcyBTdWJqZWN0?=\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n"
- "From: =?utf-8?b?TWFyYyBNw7Z0eg==?= <mutz at kde.org>\r\n"
- "Subject: =?utf-8?b?QmzDtmRlcyBTdWJqZWN0?=\r\n"
- "To: joe at user.org,\r\n"
- "\tvalentine at 14th.february.org\r\n"
- "Cc: boss at example.com\r\n"
- "\n";
-
- KioSMTP::Request request;
- QByteArray result;
-
- request.setEmitHeaders(true);
- request.setFromAddress(QStringLiteral("mutz at kde.org"));
- request.addTo(QStringLiteral("joe at user.org"));
- request.addTo(QStringLiteral("valentine at 14th.february.org"));
- request.addCc(QStringLiteral("boss at example.com"));
-
- result += request.headerFields() + '\n';
- result += request.headerFields(QStringLiteral("Marc Mutz")) + '\n';
- result += request.headerFields(QStringLiteral("Mutz, Marc")) + '\n';
- result += request.headerFields(QString::fromUtf8("Marc Mötz")) + '\n';
-
- request.setSubject(QString::fromUtf8("Blödes Subject"));
-
- result += request.headerFields() + '\n';
- result += request.headerFields(QStringLiteral("Marc Mutz")) + '\n';
- result += request.headerFields(QStringLiteral("Mutz, Marc")) + '\n';
- result += request.headerFields(QString::fromUtf8("Marc Mötz")) + '\n';
-
- if (result != expected) {
- std::cout << "Result:\n" << result.data() << std::endl;
- std::cout << "Expected:\n" << expected.data() << std::endl;
- }
-
- return result == expected ? 0 : 1;
-}
-
-#include "../request.cpp"
-
diff --git a/kioslave/src/smtp/tests/test_responseparser.cpp b/kioslave/src/smtp/tests/test_responseparser.cpp
deleted file mode 100644
index 3d449e5..0000000
--- a/kioslave/src/smtp/tests/test_responseparser.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-#include "test_responseparser.h"
-#include "../response.h"
-
-#include <qtest.h>
-#include <assert.h>
-
-QTEST_GUILESS_MAIN(ResponseParserTest)
-
-static const QByteArray singleLineResponseCRLF = "250 OK\r\n";
-static const QByteArray singleLineResponse = "250 OK";
-
-static const QByteArray multiLineResponse[] = {
- "250-ktown.kde.org\r\n",
- "250-STARTTLS\r\n",
- "250-AUTH PLAIN DIGEST-MD5\r\n",
- "250 PIPELINING\r\n"
-};
-static const unsigned int numMultiLineLines = sizeof multiLineResponse / sizeof * multiLineResponse;
-
-void ResponseParserTest::testResponseParser()
-{
- KioSMTP::Response r;
- QVERIFY(r.isValid());
- QVERIFY(r.lines().empty());
- QVERIFY(r.isWellFormed());
- QCOMPARE(r.code(), 0u);
- QVERIFY(r.isUnknown());
- QVERIFY(!r.isComplete());
- QVERIFY(!r.isOk());
- r.parseLine(singleLineResponseCRLF.data(), singleLineResponseCRLF.length());
- QVERIFY(r.isWellFormed());
- QVERIFY(r.isComplete());
- QVERIFY(r.isValid());
- QVERIFY(r.isPositive());
- QVERIFY(r.isOk());
- QCOMPARE(r.code(), 250u);
- QCOMPARE(r.errorCode(), 0);
- QCOMPARE(r.first(), 2u);
- QCOMPARE(r.second(), 5u);
- QCOMPARE(r.third(), 0u);
- QCOMPARE(r.lines().count(), 1);
- QCOMPARE(r.lines().front(), QByteArray("OK"));
- r.parseLine(singleLineResponse.data(), singleLineResponse.length());
- QVERIFY(!r.isValid());
- r.clear();
- QVERIFY(r.isValid());
- QVERIFY(r.lines().empty());
-
- r.parseLine(singleLineResponse.data(), singleLineResponse.length());
- QVERIFY(r.isWellFormed());
- QVERIFY(r.isComplete());
- QVERIFY(r.isValid());
- QVERIFY(r.isPositive());
- QVERIFY(r.isOk());
- QCOMPARE(r.code(), 250u);
- QCOMPARE(r.first(), 2u);
- QCOMPARE(r.second(), 5u);
- QCOMPARE(r.third(), 0u);
- QCOMPARE(r.lines().count(), 1);
- QCOMPARE(r.lines().front(), QByteArray("OK"));
- r.parseLine(singleLineResponse.data(), singleLineResponse.length());
- QVERIFY(!r.isValid());
- r.clear();
- QVERIFY(r.isValid());
-
- for (unsigned int i = 0; i < numMultiLineLines; ++i) {
- r.parseLine(multiLineResponse[i].data(), multiLineResponse[i].length());
- QVERIFY(r.isWellFormed());
- if (i < numMultiLineLines - 1) {
- QVERIFY(!r.isComplete());
- } else {
- QVERIFY(r.isComplete());
- }
- QVERIFY(r.isValid());
- QVERIFY(r.isPositive());
- QCOMPARE(r.code(), 250u);
- QCOMPARE(r.first(), 2u);
- QCOMPARE(r.second(), 5u);
- QCOMPARE(r.third(), 0u);
- QCOMPARE(r.lines().count(), (int)i + 1);
- }
- QCOMPARE(r.lines().back(), QByteArray("PIPELINING"));
-
- r.clear();
- r.parseLine("230", 3);
- QVERIFY(r.isValid());
- QVERIFY(r.isWellFormed()); // even though it isn't ;-)
- QCOMPARE(r.code(), 230u);
- QCOMPARE(r.lines().count(), 1);
- QVERIFY(r.lines().front().isNull());
-
- r.clear();
- r.parseLine("230\r\n", 5);
- QVERIFY(r.isValid());
- QVERIFY(r.isWellFormed()); // even though it isn't ;-)
- QCOMPARE(r.code(), 230u);
- QCOMPARE(r.lines().count(), 1);
- QVERIFY(r.lines().front().isNull());
-
- r.clear();
- r.parseLine(" 23 ok", 6);
- QVERIFY(!r.isValid());
- QVERIFY(!r.isWellFormed());
-}
-
-#include "../response.cpp"
diff --git a/kioslave/src/smtp/tests/test_responseparser.h b/kioslave/src/smtp/tests/test_responseparser.h
deleted file mode 100644
index 789a45f..0000000
--- a/kioslave/src/smtp/tests/test_responseparser.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright (c) 2006 Volker Krause <vkrause at kde.org>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#ifndef RESPONSEPARSER_TEST_H
-#define RESPONSEPARSER_TEST_H
-
-#include <QtCore/QObject>
-
-class ResponseParserTest : public QObject
-{
- Q_OBJECT
-private Q_SLOTS:
- void testResponseParser();
-};
-
-#endif
diff --git a/kioslave/src/smtp/transactionstate.cpp b/kioslave/src/smtp/transactionstate.cpp
deleted file mode 100644
index 58910df..0000000
--- a/kioslave/src/smtp/transactionstate.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- c++ -*-
- transactionstate.cc
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#include "transactionstate.h"
-
-#include <kio/global.h>
-#include <KLocalizedString>
-
-namespace KioSMTP
-{
-
-void TransactionState::setFailedFatally(int code, const QString &msg)
-{
- mFailed = mFailedFatally = true;
- mErrorCode = code;
- mErrorMessage = msg;
-}
-
-void TransactionState::setMailFromFailed(const QString &addr, const Response &r)
-{
- setFailed();
- mErrorCode = KIO::ERR_NO_CONTENT;
- if (addr.isEmpty()) {
- mErrorMessage = i18n("The server did not accept a blank sender address.\n"
- "%1", r.errorMessage());
- } else {
- mErrorMessage = i18n("The server did not accept the sender address \"%1\".\n"
- "%2", addr, r.errorMessage());
- }
-}
-
-void TransactionState::addRejectedRecipient(const RecipientRejection &r)
-{
- mRejectedRecipients.push_back(r);
- if (mRcptToDenyIsFailure) {
- setFailed();
- }
-}
-
-void TransactionState::setDataCommandSucceeded(bool succeeded, const Response &r)
-{
- mDataCommandSucceeded = succeeded;
- mDataResponse = r;
- if (!succeeded) {
- setFailed();
- } else if (failed()) {
- // can happen with pipelining: the server accepts the DATA, but
- // we don't want to send the data, so force a connection
- // shutdown:
- setFailedFatally();
- }
-}
-
-int TransactionState::errorCode() const
-{
- if (!failed()) {
- return 0;
- }
- if (mErrorCode) {
- return mErrorCode;
- }
- if (haveRejectedRecipients() || !dataCommandSucceeded()) {
- return KIO::ERR_NO_CONTENT;
- }
- // ### what else?
- return KIO::ERR_INTERNAL;
-}
-
-QString TransactionState::errorMessage() const
-{
- if (!failed()) {
- return QString();
- }
-
- if (!mErrorMessage.isEmpty()) {
- return mErrorMessage;
- }
-
- if (haveRejectedRecipients()) {
- QStringList recip;
- recip.reserve(mRejectedRecipients.count());
- for (RejectedRecipientList::const_iterator it = mRejectedRecipients.begin();
- it != mRejectedRecipients.end(); ++it) {
- recip.push_back((*it).recipient + QLatin1String(" (") + (*it).reason + QLatin1Char(')'));
- }
- return i18n("Message sending failed since the following recipients were rejected by the server:\n"
- "%1", recip.join(QStringLiteral("\n")));
- }
-
- if (!dataCommandSucceeded()) {
- return i18n("The attempt to start sending the message content failed.\n"
- "%1", mDataResponse.errorMessage());
- }
-
- // ### what else?
- return i18n("Unhandled error condition. Please send a bug report.");
-}
-
-}
diff --git a/kioslave/src/smtp/transactionstate.h b/kioslave/src/smtp/transactionstate.h
deleted file mode 100644
index ffad510..0000000
--- a/kioslave/src/smtp/transactionstate.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -*- c++ -*-
- transactionstate.h
-
- This file is part of kio_smtp, the KDE SMTP kioslave.
- Copyright (c) 2003 Marc Mutz <mutz at kde.org>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License, version 2, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-*/
-
-#ifndef __KIOSMTP_TRANSACTIONSTATE_H__
-#define __KIOSMTP_TRANSACTIONSTATE_H__
-
-#include "response.h"
-
-#include <QString>
-
-namespace KioSMTP
-{
-
-/**
- @short A class modelling an SMTP transaction's state
-
- This class models SMTP transaction state, ie. the collective
- result of the MAIL FROM:, RCPT TO: and DATA commands. This is
- needed since e.g. a single failed RCPT TO: command does not
- necessarily fail the whole transaction (servers are free to
- accept delivery for some recipients, but not for others).
-
- The class can operate in two modes, which differ in the way
- failed recipients are handled. If @p rcptToDenyIsFailure is true
- (the default), then any failing RCPT TO: will cause the
- transaction to fail. Since at the point of RCPT TO: failure
- detection, the DATA command may have already been sent
- (pipelining), the only way to cancel the transaction is to take
- down the connection hard (ie. without proper quit).
-
- Since that is not very nice behaviour, a second mode that is more
- to the spirit of SMTP is provided that can cope with partially
- failed RCPT TO: commands.
-*/
-class TransactionState
-{
-public:
- struct RecipientRejection {
- RecipientRejection(const QString &who = QString(),
- const QString &why = QString())
- : recipient(who)
- , reason(why)
- {
- }
- QString recipient;
- QString reason;
-#ifdef KIOSMTP_COMPARATORS
- bool operator==(const RecipientRejection &other) const
- {
- return recipient == other.recipient && reason == other.reason;
- }
-#endif
- };
- typedef QList<RecipientRejection> RejectedRecipientList;
-
- TransactionState(bool rcptToDenyIsFailure = true)
- : mErrorCode(0)
- , mRcptToDenyIsFailure(rcptToDenyIsFailure)
- , mAtLeastOneRecipientWasAccepted(false)
- , mDataCommandIssued(false)
- , mDataCommandSucceeded(false)
- , mFailed(false)
- , mFailedFatally(false)
- , mComplete(false)
- {
- }
-
- /**
- * @return whether the transaction failed (e.g. the server
- * rejected all recipients. Graceful failure is handled after
- * transaction ends.
- */
- bool failed() const
- {
- return mFailed || mFailedFatally;
- }
- void setFailed()
- {
- mFailed = true;
- }
-
- /**
- * @return whether the failure was so grave that an immediate
- * untidy connection shutdown is in order (ie. @ref
- * smtp_close(false)). Fatal failure is handled immediately
- */
- bool failedFatally() const
- {
- return mFailedFatally;
- }
- void setFailedFatally(int code = 0, const QString &msg = QString());
-
- /** @return whether the transaction was completed successfully */
- bool complete() const
- {
- return mComplete;
- }
- void setComplete()
- {
- mComplete = true;
- }
-
- /**
- * @return an appropriate KIO error code in case the transaction
- * failed, or 0 otherwise
- */
- int errorCode() const;
-
- /**
- * @return an appropriate error message in case the transaction
- * failed or QString() otherwise
- */
- QString errorMessage() const;
-
- void setMailFromFailed(const QString &addr, const Response &r);
-
- bool dataCommandIssued() const
- {
- return mDataCommandIssued;
- }
- void setDataCommandIssued(bool issued)
- {
- mDataCommandIssued = issued;
- }
-
- bool dataCommandSucceeded() const
- {
- return mDataCommandIssued && mDataCommandSucceeded;
- }
- void setDataCommandSucceeded(bool succeeded, const Response &r);
-
- Response dataResponse() const
- {
- return mDataResponse;
- }
-
- bool atLeastOneRecipientWasAccepted() const
- {
- return mAtLeastOneRecipientWasAccepted;
- }
- void setRecipientAccepted()
- {
- mAtLeastOneRecipientWasAccepted = true;
- }
-
- bool haveRejectedRecipients() const
- {
- return !mRejectedRecipients.empty();
- }
- RejectedRecipientList rejectedRecipients() const
- {
- return mRejectedRecipients;
- }
- void addRejectedRecipient(const RecipientRejection &r);
- void addRejectedRecipient(const QString &who, const QString &why)
- {
- addRejectedRecipient(RecipientRejection(who, why));
- }
-
- void clear()
- {
- mRejectedRecipients.clear();
- mDataResponse.clear();
- mAtLeastOneRecipientWasAccepted
- = mDataCommandIssued
- = mDataCommandSucceeded
- = mFailed = mFailedFatally
- = mComplete = false;
- }
-
-#ifdef KIOSMTP_COMPARATORS
- bool operator==(const TransactionState &other) const
- {
- return
- mAtLeastOneRecipientWasAccepted == other.mAtLeastOneRecipientWasAccepted &&
- mDataCommandIssued == other.mDataCommandIssued &&
- mDataCommandSucceeded == other.mDataCommandSucceeded &&
- mFailed == other.mFailed &&
- mFailedFatally == other.mFailedFatally &&
- mComplete == other.mComplete &&
- mDataResponse.code() == other.mDataResponse.code() &&
- mRejectedRecipients == other.mRejectedRecipients;
- }
-#endif
-
-private:
- RejectedRecipientList mRejectedRecipients;
- Response mDataResponse;
- QString mErrorMessage;
- int mErrorCode;
- bool mRcptToDenyIsFailure;
- bool mAtLeastOneRecipientWasAccepted;
- bool mDataCommandIssued;
- bool mDataCommandSucceeded;
- bool mFailed;
- bool mFailedFatally;
- bool mComplete;
-};
-
-} // namespace KioSMTP
-
-#endif // __KIOSMTP_TRANSACTIONSTATE_H__
More information about the kde-doc-english
mailing list