File indexing completed on 2024-05-12 05:17:26

0001 /**
0002   * This file is part of the KDE project
0003   * Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
0004   * Copyright (C) 2009 Andras Mantia <amantia@kde.org>
0005   * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
0006   *
0007   * This library is free software; you can redistribute it and/or
0008   * modify it under the terms of the GNU Library General Public
0009   * License as published by the Free Software Foundation; either
0010   * version 2 of the License, or (at your option) any later version.
0011   *
0012   * This library is distributed in the hope that it will be useful,
0013   * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015   * Library General Public License for more details.
0016   *
0017   * You should have received a copy of the GNU Library General Public License
0018   * along with this library; see the file COPYING.LIB.  If not, write to
0019   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020   * Boston, MA 02110-1301, USA.
0021   */
0022 
0023 #include <qdebug.h>
0024 #include <qtcpsocket.h>
0025 #include <QCoreApplication>
0026 #include <qsignalspy.h>
0027 
0028 #include "acl.h"
0029 #include "session.h"
0030 #include "appendjob.h"
0031 #include "capabilitiesjob.h"
0032 #include "fetchjob.h"
0033 #include "listjob.h"
0034 #include "loginjob.h"
0035 #include "logoutjob.h"
0036 #include "selectjob.h"
0037 #include "closejob.h"
0038 #include "expungejob.h"
0039 #include "createjob.h"
0040 #include "deletejob.h"
0041 #include "namespacejob.h"
0042 #include "subscribejob.h"
0043 #include "unsubscribejob.h"
0044 #include "renamejob.h"
0045 #include "storejob.h"
0046 #include "setacljob.h"
0047 #include "getacljob.h"
0048 #include "deleteacljob.h"
0049 #include "myrightsjob.h"
0050 #include "listrightsjob.h"
0051 #include "setmetadatajob.h"
0052 #include "getmetadatajob.h"
0053 #include "searchjob.h"
0054 
0055 using namespace KIMAP2;
0056 int main(int argc, char **argv)
0057 {
0058     QCoreApplication::setApplicationName(QStringLiteral("ImapCmd"));
0059 
0060     if (argc < 4) {
0061         qCritical() << "Not enough parameters, expecting: <server> <user> <password>";
0062         return -1;
0063     }
0064 
0065     QString server = QString::fromLocal8Bit(argv[1]);
0066     int port = 993;
0067     if (server.count(QLatin1Char(':')) == 1) {
0068         port = server.split(QLatin1Char(':')).last().toInt();
0069         server = server.split(QLatin1Char(':')).first();
0070     }
0071     QString user = QString::fromLocal8Bit(argv[2]);
0072     QString password = QString::fromLocal8Bit(argv[3]);
0073 
0074     qInfo() << "Querying:" << server << port << user << password;
0075     qInfo();
0076 
0077     QCoreApplication app(argc, argv);
0078     Session session(server, port);
0079 
0080     QObject::connect(&session, &KIMAP2::Session::sslErrors, [&session](const QList<QSslError> &errors) {
0081         qWarning() << "Got ssl error: " << errors;
0082         session.ignoreErrors(errors);
0083     });
0084 
0085     qInfo() << "Logging in...";
0086     LoginJob *login = new LoginJob(&session);
0087     login->setEncryptionMode( QSsl::AnyProtocol, false );
0088     login->setAuthenticationMode( LoginJob::Plain );
0089     login->setUserName(user);
0090     login->setPassword(password);
0091     login->exec();
0092     qInfo();
0093 
0094     /*if (login->encryptionMode() == LoginJob::Unencrypted)
0095     {
0096       qInfo() << "Encrypted login not possible, try to log in without encryption";
0097       login = new LoginJob( &session );
0098       login->setUserName( user );
0099       login->setPassword( password );
0100       login->exec();
0101       Q_ASSERT_X( login->error() == 0, "LoginJob", login->errorString().toLocal8Bit().constData() );
0102       Q_ASSERT( session.state() == Session::Authenticated );
0103       qInfo();
0104 
0105     }*/
0106 
0107     qInfo() << "Server greeting:" << session.serverGreeting();
0108 
0109     qInfo() << "Asking for capabilities:";
0110     CapabilitiesJob *capabilities = new CapabilitiesJob(&session);
0111     capabilities->exec();
0112     Q_ASSERT_X(capabilities->error() == 0, "CapabilitiesJob", capabilities->errorString().toLocal8Bit().constData());
0113     Q_ASSERT(session.state() == Session::Authenticated);
0114     qInfo() << capabilities->capabilities();
0115     qInfo();
0116 
0117     qInfo() << "Asking for namespaces:";
0118     NamespaceJob *namespaces = new NamespaceJob(&session);
0119     namespaces->exec();
0120     Q_ASSERT_X(namespaces->error() == 0, "CapabilitiesJob", namespaces->errorString().toLocal8Bit().constData());
0121     Q_ASSERT(session.state() == Session::Authenticated);
0122 
0123     qInfo() << "Contains empty namespace:" << namespaces->containsEmptyNamespace();
0124 
0125     qInfo() << "Personal:";
0126     foreach (MailBoxDescriptor ns, namespaces->personalNamespaces()) {
0127         qInfo() << ns.separator << ns.name;
0128     }
0129 
0130     qInfo() << "User:    ";
0131     foreach (MailBoxDescriptor ns, namespaces->userNamespaces()) {
0132         qInfo() << ns.separator << ns.name;
0133     }
0134 
0135     qInfo() << "Shared:  ";
0136     foreach (MailBoxDescriptor ns, namespaces->sharedNamespaces()) {
0137         qInfo() << ns.separator << ns.name;
0138     }
0139     qInfo();
0140 
0141     qInfo() << "Selecting INBOX:";
0142     SelectJob *select = new SelectJob(&session);
0143     select->setMailBox(QLatin1String("INBOX"));
0144     select->exec();
0145     Q_ASSERT_X(select->error() == 0, "SelectJob", select->errorString().toLocal8Bit().constData());
0146     Q_ASSERT(session.state() == Session::Selected);
0147     qInfo() << "Flags:" << select->flags();
0148     qInfo() << "Permanent flags:" << select->permanentFlags();
0149     qInfo() << "Total Number of Messages:" << select->messageCount();
0150     qInfo() << "Number of recent Messages:" << select->recentCount();
0151     qInfo() << "First Unseen Message Index:" << select->firstUnseenIndex();
0152     qInfo() << "UID validity:" << select->uidValidity();
0153     qInfo() << "Next UID:" << select->nextUid();
0154     qInfo() << "Highest modseq:" << select->highestModSequence();
0155     qInfo();
0156 
0157     QString command = QString::fromLocal8Bit(argv[4]);
0158     QTime time;
0159     time.start();
0160     if (command == "search") {
0161         auto searchJob = new SearchJob(&session);
0162         searchJob->setTerm(Term(Term::Uid, ImapSet::fromImapSequenceSet("1:*")));
0163         searchJob->setUidBased(true);
0164         searchJob->exec();
0165         qInfo() << "Search result: " << searchJob->results();
0166     } else if (command == "list") {
0167         auto job = new ListJob(&session);
0168         job->setOption(ListJob::IncludeUnsubscribed);
0169         QObject::connect(job, &ListJob::resultReceived, [](const MailBoxDescriptor &descriptor, const QList<QByteArray> &flags) {
0170             qInfo() << "* " << descriptor.name
0171                     <<  "flags " << flags;
0172         });
0173         job->exec();
0174     } else if (command == "flags") {
0175         qInfo() << "Fetching flags";
0176         auto job = new FetchJob(&session);
0177         FetchJob::FetchScope scope;
0178         scope.mode = FetchJob::FetchScope::Flags;
0179         job->setScope(scope);
0180         job->setUidBased(true);
0181         QObject::connect(job, &KIMAP2::FetchJob::resultReceived, [](const KIMAP2::FetchJob::Result &result) {
0182             qInfo() << "* " << result.sequenceNumber
0183                     << "uid " << result.uid
0184                     <<  "flags " << result.flags;
0185         });
0186         job->setSequenceSet(ImapSet::fromImapSequenceSet("1:*"));
0187         job->exec();
0188     } else if (command == "fetch") {
0189         qInfo() << "Fetching content";
0190         if (argc < 6) {
0191             qInfo() << "Usage: fetch 1:* [full|headers] ";
0192             return -1;
0193         }
0194         auto job = new FetchJob(&session);
0195         FetchJob::FetchScope scope;
0196         if (argc >= 7) {
0197             if (QByteArray(argv[6]).toLower() == "full") {
0198                 scope.mode = FetchJob::FetchScope::Full;
0199             } else if (QByteArray(argv[6]).toLower() == "headers") {
0200                 scope.mode = FetchJob::FetchScope::Headers;
0201             } else {
0202                 scope.mode = FetchJob::FetchScope::Full;
0203             }
0204         }
0205         job->setScope(scope);
0206         job->setUidBased(true);
0207         if (argc >= 6) {
0208             job->setSequenceSet(ImapSet::fromImapSequenceSet(QByteArray(argv[5])));
0209         } else {
0210             job->setSequenceSet(ImapSet::fromImapSequenceSet("1:*"));
0211         }
0212         QObject::connect(job, &KIMAP2::FetchJob::resultReceived, [](const KIMAP2::FetchJob::Result &result) {
0213             qInfo() << "* " << result.sequenceNumber
0214                     << "uid " << result.uid
0215                     <<  "size " << result.size
0216                     <<  "message size " << result.message->encodedContent().size();
0217         });
0218         job->exec();
0219     }
0220 
0221     qInfo() << "Command took: " << time.elapsed() << "ms";
0222 
0223     qInfo() << "Logging out...";
0224     LogoutJob *logout = new LogoutJob(&session);
0225     logout->exec();
0226     Q_ASSERT_X(logout->error() == 0, "LogoutJob", logout->errorString().toLocal8Bit().constData());
0227     // Q_ASSERT(session.state() == Session::Disconnected);
0228 
0229     return 0;
0230 }