mailtransport
socket.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "socket.h"
00025
00026
00027 #include <QRegExp>
00028 #include <QByteArray>
00029 #include <QSslSocket>
00030
00031
00032 #include <KDebug>
00033 #include <KLocalizedString>
00034 #include <ksocketfactory.h>
00035
00036 using namespace MailTransport;
00037
00038 namespace MailTransport
00039 {
00040 class SocketPrivate
00041 {
00042 public:
00043 SocketPrivate( Socket *s );
00044 Socket *const q;
00045 QSslSocket *socket;
00046 QString server;
00047 QString protocol;
00048 int port;
00049 bool secure;
00050
00051
00052 void slotConnected();
00053 void slotStateChanged( QAbstractSocket::SocketState state );
00054 void slotModeChanged( QSslSocket::SslMode state );
00055 void slotSocketRead();
00056 void slotSslErrors( const QList<QSslError> &errors );
00057 private:
00058 QString m_msg;
00059 };
00060 }
00061
00062 SocketPrivate::SocketPrivate( Socket *s ) : q( s )
00063 {
00064 }
00065
00066 void SocketPrivate::slotConnected()
00067 {
00068 kDebug() ;
00069
00070 if ( !secure ) {
00071 kDebug() << "normal connect";
00072 emit q->connected();
00073 } else {
00074 kDebug() << "encrypted connect";
00075 socket->startClientEncryption();
00076 }
00077 }
00078
00079 void SocketPrivate::slotStateChanged( QAbstractSocket::SocketState state )
00080 {
00081 #ifdef comm_debug
00082 kDebug() << "State is now:" << ( int ) state;
00083 #endif
00084 if ( state == QAbstractSocket::UnconnectedState ) {
00085 emit q->failed();
00086 }
00087 }
00088
00089 void SocketPrivate::slotModeChanged( QSslSocket::SslMode state )
00090 {
00091 #ifdef comm_debug
00092 kDebug() << "Mode is now:" << state;
00093 #endif
00094 if ( state == QSslSocket::SslClientMode ) {
00095 emit q->tlsDone();
00096 }
00097 }
00098
00099 void SocketPrivate::slotSocketRead()
00100 {
00101 kDebug();
00102
00103 if ( !socket ) {
00104 return;
00105 }
00106
00107 m_msg += QLatin1String( socket->readAll() );
00108
00109 if ( !m_msg.endsWith( QLatin1Char( '\n' ) ) ) {
00110 return;
00111 }
00112
00113 #ifdef comm_debug
00114 kDebug() << socket->isEncrypted() << m_msg.trimmed();
00115 #endif
00116
00117 emit q->data( m_msg );
00118 m_msg.clear();
00119 }
00120
00121 void SocketPrivate::slotSslErrors( const QList<QSslError> & )
00122 {
00123 kDebug();
00124
00125
00126 socket->ignoreSslErrors();
00127 emit q->connected();
00128 }
00129
00130
00131
00132 Socket::Socket( QObject *parent )
00133 : QObject( parent ), d( new SocketPrivate( this ) )
00134 {
00135 d->socket = 0;
00136 d->port = 0;
00137 d->secure = false;
00138 kDebug();
00139 }
00140
00141 Socket::~Socket()
00142 {
00143 kDebug();
00144 delete d;
00145 }
00146
00147 void Socket::reconnect()
00148 {
00149 kDebug() << "Connecting to:" << d->server << ":" << d->port;
00150
00151 #ifdef comm_debug
00152
00153 #endif
00154
00155 if ( d->socket ) {
00156 return;
00157 }
00158
00159 d->socket =
00160 static_cast<QSslSocket *>( KSocketFactory::connectToHost( d->protocol, d->server,
00161 d->port, this ) );
00162
00163 d->socket->setProtocol( QSsl::AnyProtocol );
00164
00165 connect( d->socket, SIGNAL( stateChanged( QAbstractSocket::SocketState ) ),
00166 SLOT( slotStateChanged( QAbstractSocket::SocketState ) ) );
00167 connect( d->socket, SIGNAL( modeChanged( QSslSocket::SslMode ) ),
00168 SLOT( slotModeChanged( QSslSocket::SslMode ) ) );
00169 connect( d->socket, SIGNAL( connected() ), SLOT( slotConnected() ) );
00170 connect( d->socket, SIGNAL( readyRead() ), SLOT( slotSocketRead() ) );
00171 connect( d->socket, SIGNAL( encrypted() ), SIGNAL( connected() ) );
00172 connect( d->socket, SIGNAL( sslErrors( const QList<QSslError> & ) ),
00173 SLOT( slotSslErrors( const QList<QSslError>& ) ) );
00174 }
00175
00176 void Socket::write( const QString &text )
00177 {
00178
00179
00180
00181 if ( !d->socket || !available() ) {
00182 return;
00183 }
00184
00185 QByteArray cs = ( text + QLatin1String( "\r\n" ) ).toLatin1();
00186
00187 #ifdef comm_debug
00188 kDebug() << "C :" << cs;
00189 #endif
00190
00191 d->socket->write( cs.data(), cs.size() );
00192 }
00193
00194 bool Socket::available()
00195 {
00196
00197 bool ok = d->socket && d->socket->state() == QAbstractSocket::ConnectedState;
00198 return ok;
00199 }
00200
00201 void Socket::startTLS()
00202 {
00203 kDebug() << objectName();
00204 d->socket->setProtocol( QSsl::TlsV1 );
00205 d->socket->startClientEncryption();
00206 }
00207
00208 void Socket::setProtocol( const QString &proto )
00209 {
00210 d->protocol = proto;
00211 }
00212
00213 void Socket::setServer( const QString &server )
00214 {
00215 d->server = server;
00216 }
00217
00218 void Socket::setPort( int port )
00219 {
00220 d->port = port;
00221 }
00222
00223 void Socket::setSecure( bool what )
00224 {
00225 d->secure = what;
00226 }
00227
00228 #include "socket.moc"