• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KIMAP Library

session.cpp

00001 /*
00002     Copyright (c) 2009 Kevin Ottens <ervin@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #include "session.h"
00021 #include "session_p.h"
00022 #include "sessionuiproxy.h"
00023 
00024 #include <QtCore/QDebug>
00025 #include <QtCore/QTimer>
00026 
00027 #include <KDE/KMessageBox>
00028 #include <KDE/KLocale>
00029 
00030 #include "job.h"
00031 #include "message_p.h"
00032 #include "sessionthread_p.h"
00033 #include "rfccodecs.h"
00034 
00035 Q_DECLARE_METATYPE(KTcpSocket::SslVersion)
00036 Q_DECLARE_METATYPE(QSslSocket::SslMode)
00037 static const int _kimap_sslVersionId = qRegisterMetaType<KTcpSocket::SslVersion>();
00038 
00039 using namespace KIMAP;
00040 
00041 Session::Session( const QString &hostName, quint16 port, QObject *parent)
00042   : QObject(parent), d(new SessionPrivate(this))
00043 {
00044   d->state = Disconnected;
00045   d->jobRunning = false;
00046 
00047   d->thread = new SessionThread(hostName, port, this);
00048   connect(d->thread, SIGNAL(encryptionNegotiationResult(bool)), d, SIGNAL(encryptionNegotiationResult(bool)));
00049   connect(d->thread, SIGNAL(sslError(const KSslErrorUiData&)), this, SLOT(handleSslError(const KSslErrorUiData&)));
00050 
00051   d->thread->start();
00052 }
00053 
00054 Session::~Session()
00055 {
00056   delete d->thread;
00057 }
00058 
00059 void Session::setUiProxy(SessionUiProxy *proxy)
00060 {
00061   d->uiProxy = proxy;
00062 }
00063 
00064 QString Session::hostName() const
00065 {
00066   return d->thread->hostName();
00067 }
00068 
00069 quint16 Session::port() const
00070 {
00071   return d->thread->port();
00072 }
00073 
00074 Session::State Session::state() const
00075 {
00076   return d->state;
00077 }
00078 
00079 void SessionPrivate::handleSslError(const KSslErrorUiData& errorData)
00080 {
00081   if (uiProxy && uiProxy->ignoreSslError(errorData)) {
00082     QMetaObject::invokeMethod( thread, "sslErrorHandlerResponse", Q_ARG(bool, true) );
00083   } else {
00084     QMetaObject::invokeMethod( thread, "sslErrorHandlerResponse", Q_ARG(bool, false) );
00085   }
00086 }
00087 
00088 SessionPrivate::SessionPrivate( Session *session )
00089   : q(session),
00090     uiProxy(0),
00091     currentJob(0),
00092     tagCount(0)
00093 {
00094 }
00095 
00096 void SessionPrivate::addJob(Job *job)
00097 {
00098   queue.append(job);
00099 
00100   QObject::connect( job, SIGNAL(result(KJob*)), q, SLOT(jobDone(KJob*)) );
00101   QObject::connect( job, SIGNAL(destroyed(QObject*)), q, SLOT(jobDestroyed(QObject*)) );
00102 
00103   startNext();
00104 }
00105 
00106 void SessionPrivate::startNext()
00107 {
00108   QTimer::singleShot( 0, q, SLOT(doStartNext()) );
00109 }
00110 
00111 void SessionPrivate::doStartNext()
00112 {
00113   if ( queue.isEmpty() || jobRunning || state==Session::Disconnected ) {
00114     return;
00115   }
00116 
00117   jobRunning = true;
00118 
00119   currentJob = queue.dequeue();
00120   currentJob->doStart();
00121 }
00122 
00123 void SessionPrivate::jobDone( KJob *job )
00124 {
00125   Q_ASSERT( job == currentJob );
00126 
00127   jobRunning = false;
00128   currentJob = 0;
00129   startNext();
00130 }
00131 
00132 void SessionPrivate::jobDestroyed( QObject *job )
00133 {
00134   queue.removeAll( static_cast<KIMAP::Job*>( job ) );
00135   if ( currentJob == job )
00136     currentJob = 0;
00137 }
00138 
00139 void SessionPrivate::responseReceived( const Message &response )
00140 {
00141   QByteArray tag;
00142   QByteArray code;
00143 
00144   if ( response.content.size()>=1 ) {
00145     tag = response.content[0].toString();
00146   }
00147 
00148   if ( response.content.size()>=2 ) {
00149     code = response.content[1].toString();
00150   }
00151 
00152   switch ( state ) {
00153   case Session::Disconnected:
00154     if ( code=="OK" ) {
00155       state = Session::NotAuthenticated;
00156       startNext();
00157     } else if ( code=="PREAUTH" ) {
00158       state = Session::Authenticated;
00159       startNext();
00160     } else {
00161       thread->closeSocket();
00162       QTimer::singleShot( 1000, thread, SLOT( reconnect() ) );
00163     }
00164     return;
00165   case Session::NotAuthenticated:
00166     if ( code=="OK" && tag==authTag ) {
00167       state = Session::Authenticated;
00168     }
00169     break;
00170   case Session::Authenticated:
00171     if ( code=="OK" && tag==selectTag ) {
00172       state = Session::Selected;
00173       currentMailBox = upcomingMailBox;
00174     }
00175     break;
00176   case Session::Selected:
00177     if ( ( code=="OK" && tag==closeTag )
00178       || ( code!="OK" && tag==selectTag) ) {
00179       state = Session::Authenticated;
00180       currentMailBox = QByteArray();
00181     } else if ( code=="OK" && tag==selectTag ) {
00182       currentMailBox = upcomingMailBox;
00183     }
00184     break;
00185   }
00186 
00187   if (tag==authTag) authTag.clear();
00188   if (tag==selectTag) selectTag.clear();
00189   if (tag==closeTag) closeTag.clear();
00190 
00191   // If a job is running forward it the response
00192   if ( currentJob!=0 ) {
00193     currentJob->handleResponse( response );
00194   } else {
00195     qWarning() << "A message was received from the server with no job to handle it";
00196   }
00197 }
00198 
00199 QByteArray SessionPrivate::sendCommand( const QByteArray &command, const QByteArray &args )
00200 {
00201   QByteArray tag = "A" + QByteArray::number(++tagCount).rightJustified(6, '0');
00202 
00203   QByteArray payload = tag+' '+command;
00204   if ( !args.isEmpty() ) {
00205     payload+= ' '+args;
00206   }
00207   payload+="\r\n";
00208 
00209   thread->sendData(payload);
00210 
00211   if ( command=="LOGIN" || command=="AUTHENTICATE" ) {
00212     authTag = tag;
00213   } else if ( command=="SELECT" || command=="EXAMINE" ) {
00214     selectTag = tag;
00215     upcomingMailBox = args;
00216     upcomingMailBox.remove( 0, 1 );
00217     upcomingMailBox.chop( 1 );
00218     upcomingMailBox = KIMAP::decodeImapFolderName( upcomingMailBox );
00219   } else if ( command=="CLOSE" ) {
00220     closeTag = tag;
00221   }
00222 
00223   return tag;
00224 }
00225 
00226 void SessionPrivate::sendData( const QByteArray &data )
00227 {
00228   thread->sendData(data+"\r\n");
00229 }
00230 
00231 void SessionPrivate::socketConnected()
00232 {
00233   state = Session::NotAuthenticated;
00234   startNext();
00235 }
00236 
00237 void SessionPrivate::socketDisconnected()
00238 {
00239   state = Session::Disconnected;
00240   thread->closeSocket();
00241 
00242   if ( currentJob ) {
00243     currentJob->connectionLost();
00244   }
00245 }
00246 
00247 void SessionPrivate::socketError()
00248 {
00249   //qWarning() << "Socket error occurred:" << socket->errorString();
00250   socketDisconnected();
00251 }
00252 
00253 void SessionPrivate::startSsl(const KTcpSocket::SslVersion &version)
00254 {
00255   QMetaObject::invokeMethod( thread, "startSsl", Qt::QueuedConnection, Q_ARG(KTcpSocket::SslVersion, version) );
00256 }
00257 
00258 QString SessionPrivate::selectedMailBox() const
00259 {
00260   return QString::fromUtf8( currentMailBox );
00261 }
00262 
00263 #include "session.moc"
00264 #include "session_p.moc"

KIMAP Library

Skip menu "KIMAP Library"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal