mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
228 lines
5 KiB
C++
228 lines
5 KiB
C++
/*
|
|
Copyright (C) 2006-2007 KovoKs <info@kovoks.nl>
|
|
|
|
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.
|
|
*/
|
|
|
|
// Uncomment the next line for full comm debug
|
|
// #define comm_debug
|
|
|
|
// Own
|
|
#include "socket.h"
|
|
|
|
// Qt
|
|
#include <QByteArray>
|
|
#include <QSslSocket>
|
|
|
|
// KDE
|
|
#include <KDebug>
|
|
#include <ksocketfactory.h>
|
|
|
|
using namespace MailTransport;
|
|
|
|
namespace MailTransport {
|
|
|
|
class SocketPrivate
|
|
{
|
|
public:
|
|
SocketPrivate( Socket *s );
|
|
Socket *const q;
|
|
QSslSocket *socket;
|
|
QString server;
|
|
QString protocol;
|
|
int port;
|
|
bool secure;
|
|
|
|
// slots
|
|
void slotConnected();
|
|
void slotStateChanged( QAbstractSocket::SocketState state );
|
|
void slotModeChanged( QSslSocket::SslMode state );
|
|
void slotSocketRead();
|
|
void slotSslErrors( const QList<QSslError> &errors );
|
|
|
|
private:
|
|
QString m_msg;
|
|
};
|
|
|
|
}
|
|
|
|
SocketPrivate::SocketPrivate( Socket *s ) : q( s )
|
|
{
|
|
}
|
|
|
|
void SocketPrivate::slotConnected()
|
|
{
|
|
kDebug();
|
|
|
|
if ( !secure ) {
|
|
kDebug() << "normal connect";
|
|
emit q->connected();
|
|
} else {
|
|
kDebug() << "encrypted connect";
|
|
socket->startClientEncryption();
|
|
}
|
|
}
|
|
|
|
void SocketPrivate::slotStateChanged( QAbstractSocket::SocketState state )
|
|
{
|
|
#ifdef comm_debug
|
|
kDebug() << "State is now:" << ( int ) state;
|
|
#endif
|
|
if ( state == QAbstractSocket::UnconnectedState ) {
|
|
emit q->failed();
|
|
}
|
|
}
|
|
|
|
void SocketPrivate::slotModeChanged( QSslSocket::SslMode state )
|
|
{
|
|
#ifdef comm_debug
|
|
kDebug() << "Mode is now:" << state;
|
|
#endif
|
|
if ( state == QSslSocket::SslClientMode ) {
|
|
emit q->tlsDone();
|
|
}
|
|
}
|
|
|
|
void SocketPrivate::slotSocketRead()
|
|
{
|
|
kDebug();
|
|
|
|
if ( !socket ) {
|
|
return;
|
|
}
|
|
|
|
m_msg += QLatin1String( socket->readAll() );
|
|
|
|
if ( !m_msg.endsWith( QLatin1Char( '\n' ) ) ) {
|
|
return;
|
|
}
|
|
|
|
#ifdef comm_debug
|
|
kDebug() << socket->isEncrypted() << m_msg.trimmed();
|
|
#endif
|
|
|
|
emit q->data( m_msg );
|
|
m_msg.clear();
|
|
}
|
|
|
|
void SocketPrivate::slotSslErrors( const QList<QSslError> & )
|
|
{
|
|
kDebug();
|
|
/* We can safely ignore the errors, we are only interested in the
|
|
capabilities. We're not sending auth info. */
|
|
socket->ignoreSslErrors();
|
|
emit q->connected();
|
|
}
|
|
|
|
// ------------------ end private ---------------------------//
|
|
|
|
Socket::Socket( QObject *parent )
|
|
: QObject( parent ), d( new SocketPrivate( this ) )
|
|
{
|
|
d->socket = 0;
|
|
d->port = 0;
|
|
d->secure = false;
|
|
kDebug();
|
|
}
|
|
|
|
Socket::~Socket()
|
|
{
|
|
kDebug();
|
|
delete d;
|
|
}
|
|
|
|
void Socket::reconnect()
|
|
{
|
|
kDebug() << "Connecting to:" << d->server << ":" << d->port;
|
|
|
|
#ifdef comm_debug
|
|
// kDebug() << d->protocol;
|
|
#endif
|
|
|
|
if ( d->socket ) {
|
|
return;
|
|
}
|
|
|
|
d->socket =
|
|
static_cast<QSslSocket *>( KSocketFactory::connectToHost( d->protocol, d->server,
|
|
d->port, this ) );
|
|
|
|
d->socket->setProtocol( QSsl::AnyProtocol );
|
|
|
|
connect( d->socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
|
SLOT(slotStateChanged(QAbstractSocket::SocketState)) );
|
|
connect( d->socket, SIGNAL(modeChanged(QSslSocket::SslMode)),
|
|
SLOT(slotModeChanged(QSslSocket::SslMode)) );
|
|
connect( d->socket, SIGNAL(connected()), SLOT(slotConnected()) );
|
|
connect( d->socket, SIGNAL(readyRead()), SLOT(slotSocketRead()) );
|
|
connect( d->socket, SIGNAL(encrypted()), SIGNAL(connected()) );
|
|
connect( d->socket, SIGNAL(sslErrors(QList<QSslError>)),
|
|
SLOT(slotSslErrors(QList<QSslError>)) );
|
|
}
|
|
|
|
void Socket::write( const QString &text )
|
|
{
|
|
// kDebug();
|
|
// Eat things in the queue when there is no connection. We need
|
|
// to get a connection first don't we...
|
|
if ( !d->socket || !available() ) {
|
|
return;
|
|
}
|
|
|
|
QByteArray cs = ( text + QLatin1String( "\r\n" ) ).toLatin1();
|
|
|
|
#ifdef comm_debug
|
|
kDebug() << "C :" << cs;
|
|
#endif
|
|
|
|
d->socket->write( cs.data(), cs.size() );
|
|
}
|
|
|
|
bool Socket::available()
|
|
{
|
|
// kDebug();
|
|
bool ok = d->socket && d->socket->state() == QAbstractSocket::ConnectedState;
|
|
return ok;
|
|
}
|
|
|
|
void Socket::startTLS()
|
|
{
|
|
kDebug() << objectName();
|
|
d->socket->setProtocol( QSsl::TlsV1 );
|
|
d->socket->startClientEncryption();
|
|
}
|
|
|
|
void Socket::setProtocol( const QString &proto )
|
|
{
|
|
d->protocol = proto;
|
|
}
|
|
|
|
void Socket::setServer( const QString &server )
|
|
{
|
|
d->server = server;
|
|
}
|
|
|
|
void Socket::setPort( int port )
|
|
{
|
|
d->port = port;
|
|
}
|
|
|
|
void Socket::setSecure( bool what )
|
|
{
|
|
d->secure = what;
|
|
}
|
|
|
|
#include "moc_socket.cpp"
|