Version: 0.2.0-rc1 (using KDE 3.5.5, Kubuntu (edgy) 4:3.5.5-0ubuntu3) Compiler: Target: powerpc-linux-gnu OS: Linux (ppc) release 2.6.17-10-powerpc mailody crashes -after- sending message with SMTP+TLS. Backtrace: (no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". (no debugging symbols found) (no debugging symbols found) [Thread debugging using libthread_db enabled] [New Thread 805477056 (LWP 31581)] [KCrash handler] #5 0x1003ca04 in QValueListPrivate<QString>::remove () #6 0x10055be8 in QMap<QString, QString>::clear () #7 0x1005b140 in QMap<QString, QString>::clear () #8 0x0e45c53c in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #9 0x0e45cc88 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #10 0x10050e3c in QMap<QString, QString>::clear () #11 0x1005115c in QMap<QString, QString>::clear () #12 0x10052620 in QMap<QString, QString>::clear () #13 0x0e45c53c in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #14 0x0e45d458 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #15 0x0ff5acac in QCA::TLS::readyRead () from /usr/lib/libqca.so.1 #16 0x0ff57438 in QCA::TLS::update () from /usr/lib/libqca.so.1 #17 0x0ff57670 in QCA::TLS::writeIncoming () from /usr/lib/libqca.so.1 #18 0x10051db0 in QMap<QString, QString>::clear () #19 0x100525b8 in QMap<QString, QString>::clear () #20 0x0e45c53c in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #21 0x0e45d458 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #22 0x0ee64d7c in KNetwork::KClientSocketBase::readyRead (this=0x133ffca0) at ./kclientsocketbase.moc:192 #23 0x0ee64dc0 in KNetwork::KClientSocketBase::slotReadActivity ( this=0x1008f4ec) at /build/buildd/kdelibs-3.5.5/./kdecore/network/kclientsocketbase.cpp:416 #24 0x0ee6d398 in KNetwork::KBufferedSocket::slotReadActivity ( this=0x7ffdff70) at /build/buildd/kdelibs-3.5.5/./kdecore/network/kbufferedsocket.cpp:354 #25 0x0ee7caa0 in KNetwork::KBufferedSocket::qt_invoke (this=0x1008f4ec, _id=8, _o=0x7ffdffc0) at ./kbufferedsocket.moc:97 #26 0x0e45c53c in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #27 0x0e45d1e0 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #28 0x0e9152f4 in QSocketNotifier::activated () from /usr/lib/libqt-mt.so.3 #29 0x0e48c3b4 in QSocketNotifier::event () from /usr/lib/libqt-mt.so.3 #30 0x0e3ca94c in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3 #31 0x0e3cd59c in QApplication::notify () from /usr/lib/libqt-mt.so.3 #32 0x0ee107d8 in KApplication::notify (this=0x7ffe06dc, receiver=0x120e40a8, event=0x7ffe0404) at /build/buildd/kdelibs-3.5.5/./kdecore/kapplication.cpp:550 #33 0x0e333a84 in QApplication::sendEvent () from /usr/lib/libqt-mt.so.3 #34 0x0e3b5fd0 in QEventLoop::activateSocketNotifiers () from /usr/lib/libqt-mt.so.3 #35 0x0e351790 in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3 #36 0x0e3ef584 in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3 #37 0x0e3ef244 in QEventLoop::exec () from /usr/lib/libqt-mt.so.3 #38 0x0e3cd1f4 in QApplication::exec () from /usr/lib/libqt-mt.so.3 #39 0x1001c1e4 in ?? () #40 0x0d81d728 in __libc_init_first () from /lib/libc.so.6 #41 0x0d81d728 in __libc_init_first () from /lib/libc.so.6 #42 0x0d81d728 in __libc_init_first () from /lib/libc.so.6
SVN commit 607540 by toma: Rewritten the smtp part. Should behave a lot better + preparations for auth on smtp. BUG:137698 CCBUG:136360 M +0 -1 TODO M +3 -2 src/Makefile.am M +13 -153 src/composer.cpp M +3 -20 src/composer.h M +1 -0 src/imap.cpp M +1 -1 src/imap.h A src/smtp.cpp [License: GPL (v2+)] A src/smtp.h [License: GPL (v2+)] M +21 -23 src/socketsafe.cpp M +6 -0 src/socketsafe.h --- trunk/playground/pim/mailody/TODO #607539:607540 @@ -38,5 +38,4 @@ Known Bugs: when not correctly logged in, no message. it just waits. Put a timer on that? copy an existing message and paste it in a new message, links are still blue - smtp broken --- trunk/playground/pim/mailody/src/Makefile.am #607539:607540 @@ -2,7 +2,7 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libkmime $(all_includes) # these are the headers for your project -noinst_HEADERS = mainwindow.h db.h imap.h messagedata.h \ +noinst_HEADERS = mainwindow.h db.h imap.h smtp.h messagedata.h \ headerlistview.h mailboxlistview.h messageview.h \ setup.h setupaccount.h sidebar.h colorquotes.h \ socketsafe.h composer.h filebrowser.h global.h \ @@ -24,7 +24,8 @@ bin_PROGRAMS = mailody # the application source, library search path, and link libraries -mailody_SOURCES = main.cpp mainwindow.cpp imap.cpp db.cpp messagedata.cpp \ +mailody_SOURCES = main.cpp mainwindow.cpp imap.cpp smtp.cpp db.cpp m\ + messagedata.cpp \ headerlistview.cpp mailboxlistview.cpp messageview.cpp \ setup.cpp setupaccount.cpp sidebar.cpp colorquotes.cpp \ socketsafe.cpp composer.cpp filebrowser.cpp global.cpp \ --- trunk/playground/pim/mailody/src/composer.cpp #607539:607540 @@ -45,11 +45,11 @@ #include "sidebar.h" #include "imap.h" #include "global.h" -#include "socketsafe.h" #include "filebrowser.h" #include "datalistview.h" #include "addresslineedit.h" #include "composer.h" +#include "smtp.h" namespace Mailody { @@ -58,7 +58,6 @@ : KMainWindow(0), m_lastState(To), m_smtp(0), - m_currentCommand(Connecting), m_close(false), m_dirty(false) { @@ -729,7 +728,7 @@ if (totalSize > 2000000) { - int i = KMessageBox::warningContinueCancel(this, + int i = KMessageBox::warningContinueCancel(this, i18n("The size of the attachments is %1, are you " "sure you want to send it?") .arg( KIO::convertSize(KIO::filesize_t(totalSize))), @@ -748,47 +747,19 @@ // Sending it!!! Yeah! + Imap* t = Imap::instance(); + t->saveMessage(m_mailbox, m->encodedContent( true )); + if (m_smtp) delete m_smtp; - m_currentCommand = Connecting; - - QString server = smtp_server.section(":",0,0); - int port = smtp_server.section(":",1,1).toInt(); - switch(safe) - { - case 0: - if (port == 0) - port = 25; - m_smtp = new SocketSafe(this, server, port, SocketSafe::NONE); - break; - case 1: - if (port == 0) - port = 465; - m_smtp = new SocketSafe(this, server, port, SocketSafe::SSL); - break; - case 2: - if (port == 0) - port = 25; - m_smtp = new SocketSafe(this, server, port, SocketSafe::TLS); - break; - } - - - connect(m_smtp, SIGNAL(data(const QString&)), - SLOT(slotRead(const QString&))); - connect(m_smtp, SIGNAL(connected()), SLOT(slotConnected())); - m_smtp->reconnect(); + m_smtp = new SMTP(this, "SMTP"); connect(m_smtp, SIGNAL(error(const QString&)), SLOT(slotError(const QString&))); - connect(m_smtp, SIGNAL(readyfortls()), - SLOT(slotTLS())); + connect(m_smtp, SIGNAL(done()),SLOT(slotDone())); -} + m_smtp->send(m_tos, m->encodedContent()); -void Composer::slotTLS() -{ - m_smtp->write("starttls"); } void Composer::slotSetDirty() @@ -796,128 +767,17 @@ m_dirty = true; } -void Composer::slotError(const QString& error) +void Composer::slotDone() { - //kdDebug()<< "slotError " << error << endl; - // There is a 10% chance for a crash remaining here - // on a timeout error - // Thiago guarded for that for KDE 3.5.6 - comitted on 2006-10-29 - if (m_smtp) - { - m_smtp->deleteLater(); - m_smtp = 0; - } - - KMessageBox::information(this, error); + m_close = true; + close(); } -void Composer::slotRead(const QString& dataIn) +void Composer::slotError(const QString& error) { - // kdDebug() << "Received: " << dataIn.stripWhiteSpace() - // << " for the command " << m_currentCommand << endl; - - static QString lastEmail; - - if (!m_smtp) - return; - - if (m_currentCommand == Connecting) - { - m_currentCommand = Helo; - m_smtp->write("helo localhost"); - } - else if (m_currentCommand == Helo) - { - m_currentCommand = From; - m_smtp->write("MAIL FROM:" + m->from()->email()); - } - else if (m_currentCommand == From || !m_tos.isEmpty()) - { - // Please remember, this can be the response to hte Helo or to - // a previous RCPT command.... - if (!dataIn.startsWith("250")) - { - if (dataIn.startsWith("501")) - showError(i18n("One of the emailaddress was refused by the " - "server. The refused address is: " + lastEmail)); - else - showError( dataIn ); - return; - } - - m_currentCommand = Rcpt; - QString to = m_tos.first(); - m_tos.pop_front(); - - //only send the actual emailaddress, not the name. - KMime::Headers::AddressField Address; - Address.fromUnicodeString( to,"UTF-8"); - lastEmail = Address.email(); - - m_smtp->write("RCPT TO:" + lastEmail); - } - else if (m_currentCommand == Rcpt ) - { - if (!dataIn.startsWith("250")) - { - if (dataIn.startsWith("501")) - showError(i18n("One of the emailaddress was refused by the " - "server. The refused address is: " + lastEmail)); - else - showError( dataIn ); - return; - } - m_currentCommand = Data; - m_smtp->write("DATA"); - } - else if (m_currentCommand == Data) - { - if (!dataIn.startsWith("250") && !dataIn.startsWith("354")) - { - showError( dataIn ); - return; - } - m_currentCommand = Quit; - m_smtp->write(m->encodedContent()); - m_smtp->write("\r\n."); - } - else if (m_currentCommand == Quit) - { - if (!dataIn.startsWith("250") && !dataIn.startsWith("354")) - { - showError( dataIn ); - return; - } - m_currentCommand = Done; - m_smtp->aboutToClose(); // prevent disconnect message. - m_smtp->write("QUIT"); - } - else if (m_currentCommand == Done) - { - // Time to store the message: - Imap* t = Imap::instance(); - t->saveMessage(m_mailbox, m->encodedContent( true )); - m_close = true; - close(); - } + KMessageBox::information(this, error); } -void Composer::showError(const QString& error) -{ - //kdDebug()<< "showError " << error << endl; - m_currentCommand = NotDone; - m_smtp->aboutToClose(); - m_smtp->write("QUIT"); - m_smtp = 0; - KMessageBox::error(this, i18n("The message can not be send, de server " - "answered:\n\n"+error)); } -void Composer::slotConnected() -{ - kdDebug() << "Connected! " << endl; -} - -} - #include "composer.moc" --- trunk/playground/pim/mailody/src/composer.h #607539:607540 @@ -53,7 +53,7 @@ class AddressLineEdit; class DataListView; -class SocketSafe; +class SMTP; /** * @class Composer @@ -117,17 +117,6 @@ private: - enum Commands{ - None=0, - Connecting, - Helo, - From, - Rcpt, - Data, - Quit, - Done, - NotDone - }; AddressLineEdit *m_edit; DataListView *m_lv; @@ -141,8 +130,7 @@ QSplitter* m_vhsplitter; KLineEdit* m_subject; KTextEdit* m_text; - SocketSafe* m_smtp; - Commands m_currentCommand; + SMTP* m_smtp; KMime::Message* m; QStringList m_tos; QPushButton* m_add; @@ -177,13 +165,8 @@ const QPoint &point); void slotContextMenuAddressList(KListView*, QListViewItem* lvi, const QPoint &point); - - - void slotSend(); - void slotConnected(); - void slotTLS(); - void slotRead(const QString&); + void slotDone(); void slotError(const QString& error); void slotSetDirty(); }; --- trunk/playground/pim/mailody/src/imap.cpp #607539:607540 @@ -751,6 +751,7 @@ connect(m_imap, SIGNAL(data(const QString&)), SLOT(slotRead(const QString&))); + connect(m_imap, SIGNAL(TLSCompleted()), SLOT(slotLogin())); connect(m_imap, SIGNAL(connected()), SLOT(slotLogin())); connect(m_imap, SIGNAL(error(const QString&)), SLOT(slotError(const QString&))); --- trunk/playground/pim/mailody/src/imap.h #607539:607540 @@ -79,7 +79,7 @@ /** * Contructor */ - Imap( QWidget* parent, const char* name ); + explicit Imap( QWidget* parent, const char* name ); /** * Destructor --- trunk/playground/pim/mailody/src/socketsafe.cpp #607539:607540 @@ -326,7 +326,7 @@ << "), but accepted previously... " << endl; } - emit connected(); + emit TLSCompleted(); m_ready = true; } @@ -362,25 +362,32 @@ // The bits received are not crypted. This can happen when // we don't want tls or ssl or when the connection is ready for tls. - if (m_safe == TLS) - { - QString msg = m_socket->readLine(); + static QString received; + uint available = m_socket->bytesAvailable(); + QByteArray buffer(available); + m_socket->readBlock(buffer.data(), buffer.size()); + QCString cs; + cs.resize(buffer.size()+1); + memcpy(cs.data(), buffer.data(), buffer.size()); + QString msg = cs.data(); + #ifdef comm_debug - kdDebug() << "S(0): " << QString(msg).stripWhiteSpace() << endl; + kdDebug() << "S(0): " << msg.stripWhiteSpace() << endl; #endif + if (m_safe == TLS) + { // handle the tls case. + // TODO move intelligence to imap/smtp if (msg.find("a02 OK") != -1 || - msg.find("220 Ready to start TLS") != -1) + msg.find("220 ") < msg.find("TLS") && msg.find("220 ") != -1) { // Request accepted. kdDebug() << "Accepted, starting TLS handshake..." << endl; m_ssl->startClient(m_server); m_crypted=true; } - else if (msg.find("a02 ") != -1 || msg.find("error",0,false) != -1 || - msg.find("500") != -1 || msg.find("503") != -1 || - msg.find("501") != -1 || msg.find("502") != -1) + else if (msg.find("a02 ") != -1) { // request returned, but not ok. KMessageBox::information(0,i18n("TLS was refused:\n\n")+msg); @@ -388,26 +395,17 @@ else { // request tls. - kdDebug() << "Connected, starting request for TLS" << endl; + kdDebug() << "Connected, emitting req. to deal with TLS" << endl; emit readyfortls(); + emit data(msg); } } else { + received.append(msg); + // we don't need any encryption, so gather stuff and emit it. - static QString received; - uint available = m_socket->bytesAvailable(); - QByteArray buffer(available); - m_socket->readBlock(buffer.data(), buffer.size()); - QCString cs; - cs.resize(buffer.size()+1); - memcpy(cs.data(), buffer.data(), buffer.size()); - QString t = cs.data(); - received.append(t); -#ifdef comm_debug - kdDebug() << "S(0): " << t.stripWhiteSpace() << endl; -#endif - QStringList splitted = QStringList::split("\n",t); + QStringList splitted = QStringList::split("\n",msg); if (!m_gather || splitted.grep(QRegExp("^a02")).count() != 0) { emit data(received); --- trunk/playground/pim/mailody/src/socketsafe.h #607539:607540 @@ -122,7 +122,13 @@ */ void connected(); + /** + * emitted when TLS is done + */ + void TLSCompleted(); + + /** * emitted when the dns request is ok (pretty useless, but still). */ void hostFound();