author | zautrix <zautrix> | 2005-03-16 15:51:58 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2005-03-16 15:51:58 (UTC) |
commit | fcfb235c813d3cfcf23ab905fe2fb159647bc911 (patch) (side-by-side diff) | |
tree | 424721fc576e2b41ea22274e792e977fb54e52c4 /kmicromail/libmailwrapper | |
parent | b90787b3fd6cf859c80ddce0f1a2272c7565eec3 (diff) | |
download | kdepimpi-fcfb235c813d3cfcf23ab905fe2fb159647bc911.zip kdepimpi-fcfb235c813d3cfcf23ab905fe2fb159647bc911.tar.gz kdepimpi-fcfb235c813d3cfcf23ab905fe2fb159647bc911.tar.bz2 |
smtp fix
-rw-r--r-- | kmicromail/libmailwrapper/abstractmail.cpp | 3 | ||||
-rw-r--r-- | kmicromail/libmailwrapper/smtpwrapper.cpp | 7 |
2 files changed, 8 insertions, 2 deletions
diff --git a/kmicromail/libmailwrapper/abstractmail.cpp b/kmicromail/libmailwrapper/abstractmail.cpp index ed5c898..870985e 100644 --- a/kmicromail/libmailwrapper/abstractmail.cpp +++ b/kmicromail/libmailwrapper/abstractmail.cpp @@ -1,279 +1,282 @@ // CHANGED 2004-09-31 Lutz Rogowski #include "abstractmail.h" #include "imapwrapper.h" #include "pop3wrapper.h" #include "nntpwrapper.h" #include "mhwrapper.h" #include "mailtypes.h" #include <qpe/global.h> #include <qprogressbar.h> #include <qapplication.h> #include <qmessagebox.h> #include <klocale.h> #include <kdecore/kstandarddirs.h> #include <qfile.h> #include <qtextstream.h> #include <stdlib.h> #include <libetpan/mailmime_content.h> #include <libetpan/mailmime.h> using namespace Opie::Core; AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) { return new IMAPwrapper(a); } AbstractMail* AbstractMail::getWrapper(POP3account *a) { return new POP3wrapper(a); } AbstractMail* AbstractMail::getWrapper(NNTPaccount *a) { return new NNTPwrapper(a); } AbstractMail* AbstractMail::getWrapper(const QString&a,const QString&name) { return new MHwrapper(a,name); } AbstractMail* AbstractMail::getWrapper(Account*a) { if (!a) return 0; switch (a->getType()) { case MAILLIB::A_IMAP: return new IMAPwrapper((IMAPaccount*)a); break; case MAILLIB::A_POP3: return new POP3wrapper((POP3account*)a); break; case MAILLIB::A_NNTP: return new NNTPwrapper((NNTPaccount*)a); break; default: return 0; } } encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) { // odebug << "Decode string start" << oendl; char*result_text; size_t index = 0; /* reset for recursive use! */ size_t target_length = 0; result_text = 0; int mimetype = MAILMIME_MECHANISM_7BIT; if (enc.lower()=="quoted-printable") { mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; } else if (enc.lower()=="base64") { mimetype = MAILMIME_MECHANISM_BASE64; } else if (enc.lower()=="8bit") { mimetype = MAILMIME_MECHANISM_8BIT; } else if (enc.lower()=="binary") { mimetype = MAILMIME_MECHANISM_BINARY; } int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, &result_text,&target_length); encodedString* result = new encodedString(); if (err == MAILIMF_NO_ERROR) { result->setContent(result_text,target_length); } //odebug << "Decode string finished" << oendl; return result; } QString AbstractMail::convert_String(const char*text) { size_t index = 0; char*res = 0; int err = MAILIMF_NO_ERROR; QString result(text); //qDebug("convert_String %s ", text); //err = mailmime_encoded_phrase_parse("iso-8859-1", // text, strlen(text),&index, "iso-8859-1",&res); err = mailmime_encoded_phrase_parse("iso-8859-1", text, strlen(text),&index, "utf-8",&res); if (err == MAILIMF_NO_ERROR && res && strlen(res)) { result = QString::fromUtf8(res); } //qDebug("convert_String:%s ",result.latin1() ); if (res) free(res); return result; } /* cp & paste from launcher */ QString AbstractMail::gen_attachment_id() { QFile file( "/proc/sys/kernel/random/uuid" ); if (!file.open(IO_ReadOnly ) ) return QString::null; QTextStream stream(&file); return "{" + stream.read().stripWhiteSpace() + "}"; } int AbstractMail::createMbox(const QString&,const FolderP&,const QString& ,bool) { return 0; } QString AbstractMail::defaultLocalfolder() { // QString f = getenv( "HOME" ); QString f = locateLocal( "data", "kopiemail/localmail"); // f += "/Applications/opiemail/localmail"; return f; } QString AbstractMail::draftFolder() { return QString("Drafts"); } /* temporary - will be removed when implemented in all classes */ void AbstractMail::deleteMails(const QString &,const QValueList<Opie::Core::OSmartPointer<RecMail> > &) { } void AbstractMail::deleteMailList(const QValueList<RecMailP>&target) { //qDebug("AbstractMail::deleteMailList:: Please reimplement! "); // this is currently re-implemented in pop3wrapper and imapwrapper int iii = 0; int count = target.count(); QProgressBar wid ( count ); wid.setCaption( i18n("Deleting ...")); wid.show(); while (iii < count ) { Global::statusMessage(i18n("Delete message %1 of %2").arg(iii).arg(count)); wid.setProgress( iii ); wid.raise(); qApp->processEvents(); RecMailP mail = (*target.at( iii )); deleteMail(mail); ++iii; } } void AbstractMail::downloadNewMails(const FolderP&fromFolder, AbstractMail*targetMail ) { //qDebug("AbstractMail::downloadNewMails %s ", fromFolder->getName().latin1()); // get local folder Account * acc = getAccount(); if ( !acc ) return; QString lfName = acc->getLocalFolder(); if ( lfName.isEmpty() ) lfName = acc->getAccountName(); // create local folder if ( !targetMail->createMbox(lfName)) { QMessageBox::critical(0,i18n("Error creating new Folder"), i18n("Error while creating new folder\n%1\n\nCancelling action.").arg(lfName)); return; } QValueList<RecMailP> t; listMessages(fromFolder->getName(),t,acc->getMaxMailSize() ); if ( t.count() == 0 ) { qDebug("There are no new messages %s", fromFolder->getName().latin1()); Global::statusMessage(i18n("There are no new messages")); return; } + Global::statusMessage(i18n("%1 :Downloading mails..."). arg(acc->getAccountName())); + qDebug(i18n("%1 :Downloading mails..."). arg(acc->getAccountName())); + qApp->processEvents(); QValueList<RecMailP> e; targetMail->listMessages(lfName,e,acc->getMaxMailSize() ); //qDebug("target has mails %d ", e.count()); QValueList<RecMailP> n; int iii = 0; int count = t.count(); while (iii < count ) { RecMailP r = (*t.at( iii )); bool found = false; int jjj = 0; int countE = e.count(); while (jjj < countE ) { RecMailP re = (*e.at( jjj )); if ( re->isEqual(r) ) { found = true; break; } ++jjj; } if ( !found ) { //qDebug("AAAdate *%s* ", r->isodate.latin1() ); n.append( r ); } ++iii; } qDebug("Downloaded %d messages ",n.count() ); if ( n.count() == 0 ) { Global::statusMessage(i18n("There are no new messages")); return; } mvcpMailList( n,lfName,targetMail,!acc->getLeaveOnServer()); Global::statusMessage(i18n("Downloaded %1 messages").arg(n.count())); #if 0 QValueList<RecMailP> t; listMessages(fromFolder->getName(),t, maxSizeInKb); mvcpMailList( t,targetFolder,targetWrapper,moveit); #endif } void AbstractMail::mvcpAllMails(const FolderP&fromFolder, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit, int maxSizeInKb) { QValueList<RecMailP> t; listMessages(fromFolder->getName(),t, maxSizeInKb); mvcpMailList( t,targetFolder,targetWrapper,moveit); } void AbstractMail::mvcpMailList(const QValueList<RecMailP>& t, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { encodedString*st = 0; int iii = 0; int count = t.count(); if ( count == 0 ) return; // wel, processevents is qite strange, we need a widget for getting // Global::statusMessage(i18n("Copy2 message %1").arg(iii)); displaye QProgressBar wid ( count ); wid.setCaption( i18n("Copying...")); wid.show(); while (iii < count ) { Global::statusMessage(i18n("Copy message %1 of %2").arg(iii).arg(count)); wid.setProgress( iii ); wid.raise(); qApp->processEvents(); RecMailP r = (*t.at( iii )); st = fetchRawBody(r); if (st) { targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); delete st; } ++iii; } if (moveit) { deleteMailList( t ); //deleteAllMail(fromFolder); } } void AbstractMail::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { encodedString*st = 0; st = fetchRawBody(mail); if (st) { targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); delete st; } if (moveit) { deleteMail(mail); } } diff --git a/kmicromail/libmailwrapper/smtpwrapper.cpp b/kmicromail/libmailwrapper/smtpwrapper.cpp index 845c71c..448a2e9 100644 --- a/kmicromail/libmailwrapper/smtpwrapper.cpp +++ b/kmicromail/libmailwrapper/smtpwrapper.cpp @@ -1,487 +1,490 @@ #include "smtpwrapper.h" #include "mailwrapper.h" #include "abstractmail.h" #include "logindialog.h" #include "mailtypes.h" #include "sendmailprogress.h" //#include <opie2/odebug.h> //#include <qt.h> #include <qapplication.h> #include <qmessagebox.h> #include <stdlib.h> #ifndef DESKTOP_VERSION //#include <qpe/config.h> #include <qpe/qcopenvelope_qws.h> #endif #include <libetpan/libetpan.h> #include <klocale.h> #include <kglobal.h> #include <kconfig.h> using namespace Opie::Core; progressMailSend*SMTPwrapper::sendProgress = 0; SMTPwrapper::SMTPwrapper(SMTPaccount * aSmtp ) : Generatemail() { m_SmtpAccount = aSmtp; KConfig cfg( locateLocal("config", "kopiemailrc" ) ); cfg.setGroup( "Status" ); m_queuedMail = cfg.readNumEntry( "outgoing", 0 ); emit queuedMails( m_queuedMail ); connect( this, SIGNAL( queuedMails(int) ), this, SLOT( emitQCop(int) ) ); m_smtp = 0; } SMTPwrapper::~SMTPwrapper() { disc_server(); } void SMTPwrapper::emitQCop( int queued ) { #ifndef DESKTOP_VERSION // LR : not used in kde-pim //QCopEnvelope env( "QPE/Pim", "outgoingMails(int)" ); //env << queued; #endif } QString SMTPwrapper::mailsmtpError( int errnum ) { switch ( errnum ) { case MAILSMTP_NO_ERROR: return i18n( "No error" ); case MAILSMTP_ERROR_UNEXPECTED_CODE: return i18n( "Unexpected error code" ); case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE: return i18n( "Service not available" ); case MAILSMTP_ERROR_STREAM: return i18n( "Stream error" ); case MAILSMTP_ERROR_HOSTNAME: return i18n( "gethostname() failed" ); case MAILSMTP_ERROR_NOT_IMPLEMENTED: return i18n( "Not implemented" ); case MAILSMTP_ERROR_ACTION_NOT_TAKEN: return i18n( "Error, action not taken" ); case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION: return i18n( "Data exceeds storage allocation" ); case MAILSMTP_ERROR_IN_PROCESSING: return i18n( "Error in processing" ); case MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED: return i18n( "Starttls not supported" ); // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE: // return i18n( "Insufficient system storage" ); case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE: return i18n( "Mailbox unavailable" ); case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED: return i18n( "Mailbox name not allowed" ); case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND: return i18n( "Bad command sequence" ); case MAILSMTP_ERROR_USER_NOT_LOCAL: return i18n( "User not local" ); case MAILSMTP_ERROR_TRANSACTION_FAILED: return i18n( "Transaction failed" ); case MAILSMTP_ERROR_MEMORY: return i18n( "Memory error" ); case MAILSMTP_ERROR_CONNECTION_REFUSED: return i18n( "Connection refused" ); default: return i18n( "Unknown error code" ); } } void SMTPwrapper::progress( size_t current, size_t maximum ) { if (SMTPwrapper::sendProgress) { SMTPwrapper::sendProgress->setSingleMail(current, maximum ); qApp->processEvents(); } } void SMTPwrapper::storeMail(const char*mail, size_t length, const QString&box) { if (!mail) return; QString localfolders = AbstractMail::defaultLocalfolder(); AbstractMail*wrap = AbstractMail::getWrapper(localfolders); wrap->createMbox(box); wrap->storeMessage(mail,length,box); delete wrap; } bool SMTPwrapper::smtpSend( mailmime *mail,bool later) { clist *rcpts = 0; char *from, *data; size_t size; from = data = 0; mailmessage * msg = 0; msg = mime_message_init(mail); mime_message_set_tmpdir(msg,getenv( "HOME" )); int r = mailmessage_fetch(msg,&data,&size); mime_message_detach_mime(msg); mailmessage_free(msg); if (r != MAIL_NO_ERROR || !data) { if (data) free(data); qDebug("Error fetching mime... "); return false; } msg = 0; if (later) { storeMail(data,size,"Outgoing"); if (data) free( data ); KConfig cfg( locateLocal("config", "kopiemailrc" ) ); cfg.setGroup( "Status" ); cfg.writeEntry( "outgoing", ++m_queuedMail ); emit queuedMails( m_queuedMail ); return true; } from = getFrom( mail ); rcpts = createRcptList( mail->mm_data.mm_message.mm_fields ); bool result = smtpSend(from,rcpts,data,size); if (data) { free(data); } if (from) { free(from); } if (rcpts) smtp_address_list_free( rcpts ); return result; } void SMTPwrapper::storeFailedMail(const char*data,unsigned int size, const char*failuremessage) { if (data) { storeMail(data,size,"Sendfailed"); } if (failuremessage) { QMessageBox::critical(0,i18n("Error sending mail"), failuremessage); } } int SMTPwrapper::start_smtp_tls() { if (!m_smtp) { return MAILSMTP_ERROR_IN_PROCESSING; } int err = mailesmtp_starttls(m_smtp); if (err != MAILSMTP_NO_ERROR) return err; mailstream_low * low; mailstream_low * new_low; low = mailstream_get_low(m_smtp->stream); if (!low) { return MAILSMTP_ERROR_IN_PROCESSING; } int fd = mailstream_low_get_fd(low); if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) { mailstream_low_free(low); mailstream_set_low(m_smtp->stream, new_low); } else { return MAILSMTP_ERROR_IN_PROCESSING; } return err; } void SMTPwrapper::connect_server() { QString server, user, pass; bool ssl; uint16_t port; ssl = false; bool try_tls = false; bool force_tls=false; QString failuretext = ""; if (m_smtp || !m_SmtpAccount) { return; } server = m_SmtpAccount->getServer(); if ( m_SmtpAccount->ConnectionType() == 3 ) { ssl = true; try_tls = false; } else if (m_SmtpAccount->ConnectionType() == 2) { force_tls = true; + try_tls = true; } else if (m_SmtpAccount->ConnectionType() == 1) { try_tls = true; } int result = 1; port = m_SmtpAccount->getPort().toUInt(); m_smtp = mailsmtp_new( 20, &progress ); if ( m_smtp == NULL ) { /* no failure message cause this happens when problems with memory - than we we can not display any messagebox */ return; } int err = MAILSMTP_NO_ERROR; ; // odebug << "Servername " << server << " at port " << port << "" << oendl; if ( ssl ) { qDebug("smtp: ssl_connect "); err = mailsmtp_ssl_connect( m_smtp, server.latin1(), port ); } else { ; // odebug << "No SSL session" << oendl; err = mailsmtp_socket_connect( m_smtp, server.latin1(), port ); } if ( err != MAILSMTP_NO_ERROR ) { qDebug("Error init SMTP connection" ); failuretext = i18n("Error init SMTP connection:\n%1").arg(mailsmtpError(err)); result = 0; } qDebug("SMTP connection inited "); /* switch to tls after init 'cause there it will send the ehlo */ if (result) { err = mailsmtp_init( m_smtp ); if (err != MAILSMTP_NO_ERROR) { result = 0; qDebug("Error init SMTP connection "); failuretext = i18n("Error init SMTP connection:\n%1").arg(mailsmtpError(err)); } } if (result && try_tls) { - qDebug("Smpt: Try tls "); + qDebug("Smpt: Try TLS... "); err = start_smtp_tls(); if (err != MAILSMTP_NO_ERROR) { try_tls = false; - qDebug("no tls "); + qDebug("Smpt: No TLS possible "); } else { err = mailesmtp_ehlo(m_smtp); if ( err != MAILSMTP_NO_ERROR ) result = 0; + else + qDebug("Smpt: Using TLS "); } } //qDebug("mailesmtp_ehlo %d ",err ); if (!try_tls && force_tls) { result = 0; failuretext = i18n("Error init SMTP tls:%1").arg(mailsmtpError(err)); } if (result==1 && m_SmtpAccount->getLogin() ) { ; // odebug << "smtp with auth" << oendl; if ( m_SmtpAccount->getUser().isEmpty() || m_SmtpAccount->getPassword().isEmpty() ) { // get'em LoginDialog login( m_SmtpAccount->getUser(), m_SmtpAccount->getPassword(), NULL, 0, true ); login.show(); if ( QDialog::Accepted == login.exec() ) { // ok user = login.getUser(); pass = login.getPassword(); } else { result = 0; failuretext=i18n("Login aborted - \nstoring mail to localfolder"); } } else { user = m_SmtpAccount->getUser(); pass = m_SmtpAccount->getPassword(); } ; // odebug << "session->auth: " << m_smtp->auth << "" << oendl; if (result) { err = mailsmtp_auth( m_smtp, (char*)user.latin1(), (char*)pass.latin1() ); if ( err == MAILSMTP_NO_ERROR ) { qDebug("Smtp authentification ok "); } else { failuretext = i18n("Authentification failed"); result = 0; } } } if ( result == 0 ) { mailsmtp_free(m_smtp); m_smtp = 0; } } void SMTPwrapper::disc_server() { if (m_smtp) { mailsmtp_quit( m_smtp ); mailsmtp_free( m_smtp ); m_smtp = 0; } } int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size ) { int err,result; QString failuretext = ""; connect_server(); result = 1; if (m_smtp) { err = mailsmtp_send( m_smtp, from, rcpts, data, size ); if ( err != MAILSMTP_NO_ERROR ) { qDebug("Error sending mail"); failuretext=i18n("Error sending mail:\n%1").arg(mailsmtpError(err)); result = 0; } } else { result = 0; } if (!result) { storeFailedMail(data,size,failuretext); } else { ; // odebug << "Mail sent." << oendl; storeMail(data,size,"Sent"); } return result; } bool SMTPwrapper::sendMail(const Opie::Core::OSmartPointer<Mail>&mail,bool later ) { mailmime * mimeMail; bool result = true; mimeMail = createMimeMail(mail ); if ( mimeMail == 0 ) { qDebug("SMTP wrapper:Error creating mail! "); return false; } else { sendProgress = new progressMailSend(); sendProgress->show(); sendProgress->setMaxMails(1); result = smtpSend( mimeMail,later); ; // odebug << "Clean up done" << oendl; sendProgress->hide(); delete sendProgress; sendProgress = 0; mailmime_free( mimeMail ); if ( m_smtp ) { mailsmtp_free(m_smtp); m_smtp = 0; } } return result; } int SMTPwrapper::sendQueuedMail(AbstractMail*wrap,const RecMailP&which) { size_t curTok = 0; mailimf_fields *fields = 0; mailimf_field*ffrom = 0; clist *rcpts = 0; char*from = 0; int res = 0; encodedString * data = wrap->fetchRawBody(which); if (!data) return 0; int err = mailimf_fields_parse( data->Content(), data->Length(), &curTok, &fields ); if (err != MAILIMF_NO_ERROR) { delete data; delete wrap; return 0; } rcpts = createRcptList( fields ); ffrom = getField(fields, MAILIMF_FIELD_FROM ); from = getFrom(ffrom); if (rcpts && from) { res = smtpSend(from,rcpts,data->Content(),data->Length()); } if (fields) { mailimf_fields_free(fields); fields = 0; } if (data) { delete data; } if (from) { free(from); } if (rcpts) { smtp_address_list_free( rcpts ); } return res; } /* this is a special fun */ bool SMTPwrapper::flushOutbox() { bool returnValue = true; ; // odebug << "Sending the queue" << oendl; if (!m_SmtpAccount) { ; // odebug << "No smtp account given" << oendl; return false; } bool reset_user_value = false; QString localfolders = AbstractMail::defaultLocalfolder(); AbstractMail*wrap = AbstractMail::getWrapper(localfolders); if (!wrap) { ; // odebug << "memory error" << oendl; return false; } QString oldPw, oldUser; QValueList<RecMailP> mailsToSend; QValueList<RecMailP> mailsToRemove; QString mbox("Outgoing"); wrap->listMessages(mbox,mailsToSend); if (mailsToSend.count()==0) { delete wrap; ; // odebug << "No mails to send" << oendl; return false; } oldPw = m_SmtpAccount->getPassword(); oldUser = m_SmtpAccount->getUser(); if (m_SmtpAccount->getLogin() && (m_SmtpAccount->getUser().isEmpty() || m_SmtpAccount->getPassword().isEmpty()) ) { // get'em QString user,pass; LoginDialog login( m_SmtpAccount->getUser(), m_SmtpAccount->getPassword(), NULL, 0, true ); login.show(); if ( QDialog::Accepted == login.exec() ) { // ok user = login.getUser().latin1(); pass = login.getPassword().latin1(); reset_user_value = true; m_SmtpAccount->setUser(user); m_SmtpAccount->setPassword(pass); } else { return true; } } sendProgress = new progressMailSend(); sendProgress->show(); sendProgress->setMaxMails(mailsToSend.count()); while (returnValue && mailsToSend.count()>0) { if (sendQueuedMail(wrap, (*mailsToSend.begin()))==0) { QMessageBox::critical(0,i18n("Error sending mail"), i18n("Error sending queued mail.\nBreaking.")); returnValue = false; } mailsToRemove.append((*mailsToSend.begin())); mailsToSend.remove(mailsToSend.begin()); sendProgress->setCurrentMails(mailsToRemove.count()); } if (reset_user_value) { m_SmtpAccount->setUser(oldUser); m_SmtpAccount->setPassword(oldPw); } KConfig cfg( locateLocal("config", "kopiemailrc" ) ); cfg.setGroup( "Status" ); m_queuedMail = mailsToSend.count(); cfg.writeEntry( "outgoing", m_queuedMail ); emit queuedMails( m_queuedMail ); sendProgress->hide(); delete sendProgress; sendProgress = 0; wrap->deleteMails(mbox,mailsToRemove); delete wrap; if ( m_smtp ) { mailsmtp_free(m_smtp); m_smtp = 0; } return returnValue; } |