[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    Re: kio_smtp
From:       "Aaron J. Seigo" <aseigo () mountlinux ! com>
Date:       2001-07-16 14:19:07
[Download RAW message or body]

hi..

this email was sent using kmail w/kio_smtp ...  =))

> However, if I specify a port in the URL (localhost:25), the slave seems to
> crash.

turns out it wasn't the port, it was the fact that i was using 
msg->headerField("From"), for MAIL FROM and i needed to pass it through 
KMMessage::getEmailAddr() first to strip just the email address out of it. =))

the KMail source is rather complex and takes some time to get used to.

> Authentication is completely untested, since I switched it to the new SASL
> library.

i'm not there yet.. one step at a time =)

now that i have kio_smtp apparently working (w/out auth) here are some 
patches for comment... once i've got some comments (or none) back, i have 
changes to the settings dialog and the identity objects (to add smtp 
username/passwords) that i want to review once more and then i'll submit 
those as patches, and then i'll work on making sure auth works... once all of 
that has been given the thumb up, i'll make the entire thing one big patch 
and maintain it through to the next release. that's the plan anyways =)  if 
these patches are ok (they are working for me, but i'm sure i've missed 
SOMETHING)

the kmail patch applies to kmsender.cpp/h, and the kio_smtp patch applies to 
kdebase/kioslave/smtp and adds another field to the URL so that the From: 
header field works properly.

-- 
Aaron Seigo


["kmail.patch" (text/x-diff)]

Index: kmsender.cpp
===================================================================
RCS file: /home/projects/kdecvs/cvsroot/kdenetwork/kmail/kmsender.cpp,v
retrieving revision 1.111
diff -u -3 -d -p -r1.111 kmsender.cpp
--- kmsender.cpp	2001/06/29 18:18:21	1.111
+++ kmsender.cpp	2001/07/16 23:15:40
@@ -16,6 +16,9 @@
 
 #include <kdebug.h>
 #include <kconfig.h>
+#include <kio/global.h>
+#include <kio/job.h>
+#include <kio/scheduler.h>
 #include <kprocess.h>
 #include <kapp.h>
 #include <kmessagebox.h>
@@ -51,7 +54,9 @@ KMSender::KMSender()
   mMsgSendProc = NULL;
   mSendProcStarted = FALSE;
   mSendInProgress = FALSE;
+  mUseSSL = FALSE;
   mCurrentMsg = NULL;
+  mSendInfoChanged = FALSE;
   labelDialog = 0;
   readConfig();
   quitOnDone = false;
@@ -63,7 +68,8 @@ KMSender::KMSender()
 KMSender::~KMSender()
 {
   writeConfig(FALSE);
-  if (mSendProc) delete mSendProc;
+  delete mSendProc;
+  delete labelDialog;
 }
 
 //-----------------------------------------------------------------------------
@@ -89,11 +95,16 @@ void KMSender::readConfig(void)
   mSmtpHost = config->readEntry("Smtp Host", "localhost");
   mSmtpPort = config->readNumEntry("Smtp Port", 25);
   mPrecommand = config->readEntry("Precommand", "");
-
+  mUsername = config->readEntry("Smtp Username", "");
+  mPassword = config->readEntry("Smtp Password", "");
+  mUseSSL = (bool) config->readNumEntry("SSL", FALSE);
+  
   str = config->readEntry("Method");
   if (str=="mail") mMethod = smMail;
   else if (str=="smtp") mMethod = smSMTP;
   else mMethod = smUnknown;
+  
+  mSendInfoChanged = true;
 }
 
 
@@ -108,7 +119,20 @@ void KMSender::writeConfig(bool aWithSyn
   config->writeEntry("Mailer", mMailer);
   config->writeEntry("Smtp Host", mSmtpHost);
   config->writeEntry("Smtp Port", (int)mSmtpPort);
-  config->writeEntry("Method", (mMethod==smSMTP) ? "smtp" : "mail");
+  config->writeEntry("Smtp Username", mUsername);
+  config->writeEntry("Smtp Password", mPassword);
+  switch(mMethod)
+  {
+  case smMail:
+    config->writeEntry("Method", "mail");
+    break;
+  case smSMTP:
+    config->writeEntry("Method", "smtp");
+    break;
+  case smUnknown:
+    config->writeEntry("Method", "unknown");
+    break;
+  }  
   config->writeEntry("Precommand", mPrecommand);
 
   if (aWithSync) config->sync();
@@ -229,15 +253,21 @@ bool KMSender::sendQueued(void)
   kernel->sentFolder()->open();
 
 
-  // create a sender
-  if (mSendProc) delete mSendProc;
-  if (mMethod == smMail) mSendProc = new KMSendSendmail(this,mMailer);
-  else if (mMethod == smSMTP) mSendProc = new KMSendSMTP(this,mSmtpHost,mSmtpPort);
-  else mSendProc = NULL;
-  assert(mSendProc != NULL);
-  connect(mSendProc,SIGNAL(idle()),SLOT(slotIdle()));
-  connect(mSendProc,SIGNAL(started(bool)),this,SLOT(sendProcStarted(bool)));
-
+  // create a sender, but only if it isn't already created
+  if (mSendInfoChanged == true || !mSendProc || mSendProc->sendType() != mMethod) 
+  {
+    mSendInfoChanged = false;
+    delete mSendProc;
+    
+    if (mMethod == smMail) mSendProc = new KMSendSendmail(this,mMailer);
+    else if (mMethod == smSMTP) mSendProc = new KMSendSMTP(this);
+    else mSendProc = NULL;
+    
+    assert(mSendProc != NULL);
+    connect(mSendProc,SIGNAL(idle()),SLOT(slotIdle()));
+    connect(mSendProc,SIGNAL(started(bool)),this,SLOT(sendProcStarted(bool)));
+  }
+  
   // start sending the messages
   doSendMsg();
   return TRUE;
@@ -518,6 +548,7 @@ void KMSender::slotIdle()
 void KMSender::setMethod(Method aMethod)
 {
   mMethod = aMethod;
+  mSendInfoChanged = true;
 }
 
 
@@ -539,6 +570,7 @@ void KMSender::setSendQuotedPrintable(bo
 void KMSender::setMailer(const QString& aMailer)
 {
   mMailer = aMailer;
+  mSendInfoChanged = true;
 }
 
 
@@ -546,6 +578,7 @@ void KMSender::setMailer(const QString& 
 void KMSender::setSmtpHost(const QString& aSmtpHost)
 {
   mSmtpHost = aSmtpHost;
+  mSendInfoChanged = true;
 }
 
 
@@ -553,10 +586,25 @@ void KMSender::setSmtpHost(const QString
 void KMSender::setSmtpPort(unsigned short int aSmtpPort)
 {
   mSmtpPort = aSmtpPort;
+  mSendInfoChanged = true;
 }
 
+//-----------------------------------------------------------------------------
+void KMSender::setUsername(const QString& aUsername)
+{
+  mUsername = aUsername;
+  mSendInfoChanged = true;
+}
 
 //-----------------------------------------------------------------------------
+void KMSender::setPassword(const QString& aPassword)
+{
+  mPassword = aPassword;
+  mSendInfoChanged = true;
+}
+
+
+//-----------------------------------------------------------------------------
 KMSendProc* KMSender::createSendProcFromString(QString transport)
 {
   if (transport.left(7) == "smtp://") { // to i18n or not to i18n?
@@ -568,7 +616,7 @@ KMSendProc* KMSender::createSendProcFrom
       server = serverport.left(colon);
       port = serverport.mid(colon + 1);
     }
-    return new KMSendSMTP(this,server,port.toInt());
+    return new KMSendSMTP(this);
   }
   else if (transport.left(7) == "file://") {
     return new KMSendSendmail(this,transport.mid(7));
@@ -914,7 +962,7 @@ void KMSendSendmail::sendmailExited(KPro
 
 
 //-----------------------------------------------------------------------------
-bool KMSendSendmail::addOneRecipient(const QString &aRcpt)
+bool KMSendSendmail::addOneRecipient(const QString& aRcpt)
 {
   assert(mMailerProc!=NULL);
   if (!aRcpt.isEmpty()) *mMailerProc << aRcpt;
@@ -922,143 +970,142 @@ bool KMSendSendmail::addOneRecipient(con
 }
 
 
+
+//-----------------------------------------------------------------------------
 //=============================================================================
 //=============================================================================
-KMSendSMTP::KMSendSMTP(KMSender* aSender, QString smtpHost,
-		       unsigned short int smtpPort ):
-    KMSendSMTPInherited(aSender), mSmtpHost(smtpHost), mSmtpPort(smtpPort)
+KMSendSMTP::KMSendSMTP(KMSender *_sender)
+  : KMSendProc(_sender), 
+    mJob(0)
 {
-  smtp = 0;
+  KIO::Scheduler::connect(SIGNAL(slaveError(KIO::Slave *, int, const QString &)),
+                          this, SLOT(slaveError(KIO::Slave *, int, const QString &)));
 }
 
-//-----------------------------------------------------------------------------
 KMSendSMTP::~KMSendSMTP()
-{
-}
-
-//-----------------------------------------------------------------------------
-void KMSendSMTP::start(void)
-{
-  statusMsg(i18n("connecting to server"));
-  emit started(true);
-}
-
-//-----------------------------------------------------------------------------
-bool KMSendSMTP::finish(bool destructive)
-{
-  if (smtp) {
-    disconnect( smtp, SIGNAL(error(const QString&, const QString&)),
-	        this, SLOT(smtpFailed(const QString&, const QString& )) );
-    disconnect( smtp, SIGNAL(success()),
-		this, SIGNAL(idle()) );
-    smtp->quit();
-  }
-  smtp = 0;
-  if (destructive)
-      delete this;
-  return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-void KMSendSMTP::abort()
 {
-  if (smtp) {
-    disconnect( smtp, SIGNAL(error(const QString&, const QString&)),
-	        this, SLOT(smtpFailed(const QString&, const QString& )) );
-    disconnect( smtp, SIGNAL(success()),
-		this, SIGNAL(idle()) );
-    smtp->quit();
-  }
-  smtp = 0;
-  idle();
+    if (mJob) mJob->kill();
 }
-
 
-//-----------------------------------------------------------------------------
-bool KMSendSMTP::send(KMMessage *msg)
+bool KMSendSMTP::send(KMMessage *aMsg)
 {
-  mSendOk = smtpSend(msg);
-  return mSendOk;
-}
-
+  assert(aMsg != NULL);
 
-//-----------------------------------------------------------------------------
-bool KMSendSMTP::smtpSend(KMMessage* aMsg)
-{
-  QString str, msgStr, bccStr;
   QString idStr = aMsg->headerField("X-KMail-Identity");
   aMsg->removeHeaderField("X-KMail-Identity");
   KMIdentity ident( idStr.isEmpty() ? i18n( "Default" ) : idStr );
   ident.readConfig();
 
-  assert(aMsg != NULL);
-  recipients.clear();
+  // email this is from
+  mQuery = QString("from=%1&showfrom=%2").arg(KMMessage::getEmailAddr(aMsg->from())).arg(aMsg->from());
 
-  if (!addRecipients(aMsg->headerAddrField("To"))) return FALSE;
+  // recipients
+  mQueryField = "&to=";
+  if(!addRecipients(aMsg->headerAddrField("To"))) return FALSE;
 
-  if (!aMsg->cc().isEmpty())
-    if (!addRecipients(aMsg->headerAddrField("Cc"))) return FALSE;
+  if(!aMsg->cc().isEmpty())
+  {
+    mQueryField = "&cc=";
+    if(!addRecipients(aMsg->headerAddrField("Cc"))) return FALSE;
+  }
 
-  bccStr = aMsg->bcc();
-  if (!bccStr.isEmpty())
+  if(!aMsg->bcc().isEmpty())
   {
+    mQueryField = "&bcc=";
     if (!addRecipients(aMsg->headerAddrField("Bcc"))) return FALSE;
     aMsg->removeHeaderField("Bcc");
   }
 
-  msgStr = prepareStr(aMsg->asString(), TRUE );
-  if (!smtp) {
-      smtp = new Smtp( ident.emailAddr(), recipients,
-		       msgStr,
-		       mSmtpHost,
-		       mSmtpPort );
-      connect( smtp, SIGNAL(error(const QString&, const QString&)),
-	       this, SLOT(smtpFailed(const QString&, const QString& )) );
-      connect( smtp, SIGNAL(success()),
-	       this, SIGNAL(idle()) );
-  } else {
-      smtp->send( ident.emailAddr(), recipients, msgStr );
+  if(!aMsg->subject().isEmpty())
+    mQuery += QString("&subject=") + aMsg->subject();
+
+  KURL destination;
+  destination.setProtocol("smtp");
+  
+  if (!mSender->username().isEmpty())
+      destination.setUser(mSender->username());
+  if (!mSender->password().isEmpty())
+      destination.setPass(mSender->password());
+  
+  destination.setHost(mSender->smtpHost());
+  destination.setPort(mSender->smtpPort());
+  destination.setPath("/send");
+  destination.setQuery(mQuery);
+  
+  mQuery = "";
+  
+  mMessage = prepareStr(aMsg->asString(), TRUE);
+  
+  if (mJob = KIO::put(destination, -1, false, false, false))
+  {
+      connect(mJob, SIGNAL(result(KIO::Job *)), this, SLOT(result(KIO::Job *)));
+      connect(mJob, SIGNAL(dataReq(KIO::Job *, QByteArray &)), 
+              this, SLOT(dataReq(KIO::Job *, QByteArray &)));
+      mSendOk = true;
+      return mSendOk;
   }
+  else 
+  {
+    abort();
+    return false;
+  }
+}
 
-  if (!bccStr.isEmpty()) aMsg->setBcc(bccStr);
-  return TRUE;
+void KMSendSMTP::abort()
+{
+  if(mJob)
+  {
+    mJob->kill();
+    mJob = 0;
+  }
+  emit idle();
 }
 
+bool KMSendSMTP::finish(bool b)
+{
+  if(mJob)
+  {
+    mJob->kill();
+    mJob = 0;
+  }
+  return KMSendProc::finish(b);
+}
 
-//-----------------------------------------------------------------------------
-bool KMSendSMTP::addOneRecipient(const QString &aRcpt)
+bool KMSendSMTP::addOneRecipient(const QString& _addr)
 {
-  if (aRcpt.isEmpty()) return TRUE;
+  if(!_addr.isEmpty())
+    mQuery += mQueryField + _addr;
 
-  recipients.append( aRcpt );
-  return TRUE;
+  return true;
 }
 
-
-//-----------------------------------------------------------------------------
-void KMSendSMTP::smtpFailed(const QString &command,
-			    const QString &response)
+void KMSendSMTP::dataReq(KIO::Job *, QByteArray &array)
 {
-  failed( i18n("a SMTP error occured.\n"
-	     "Command: %1\n"
-	     "Response: %2")
-	  .arg(command)
-	  .arg(response) );
-  if (smtp)
-      delete smtp;
-  smtp = 0;
-  idle();
+  if(mMessage.length())
+  {
+    array.duplicate(mMessage);
+    mMessage = "";
+  }
 }
 
-
-//-----------------------------------------------------------------------------
-void KMSendSMTP::smtpInCmd(const char* inCommand)
+void KMSendSMTP::result(KIO::Job *_job)
 {
-  QString str;
-  str = i18n("Sending SMTP command: %1").arg(inCommand);
-  statusMsg(str);
+  mJob = 0;
+
+  if(_job->error())
+  {
+    mSendOk = false;
+    failed(_job->errorString());
+  }
+
+  emit idle();
 }
 
+void KMSendSMTP::slaveError(KIO::Slave *aSlave, int error, const QString &errorMsg)
+{
+  mSendOk = false;
+  failed(errorMsg);
+  abort();
+}
 
-//-----------------------------------------------------------------------------
 #include "kmsender.moc"
Index: kmsender.h
===================================================================
RCS file: /home/projects/kdecvs/cvsroot/kdenetwork/kmail/kmsender.h,v
retrieving revision 1.33
diff -u -3 -d -p -r1.33 kmsender.h
--- kmsender.h	2001/06/29 18:18:21	1.33
+++ kmsender.h	2001/07/16 23:15:40
@@ -7,6 +7,7 @@
 #include <mimelib/smtp.h>
 #include <mimelib/string.h>
 #include <mimelib/utility.h>
+#include <qcstring.h>
 #include <qstring.h>
 #include <qstringlist.h>
 #include <qobject.h>
@@ -24,13 +25,20 @@ class QStrList;
 class KMainWindow;
 class Smtp;
 
+namespace KIO
+{
+  class Job;
+  class Slave;
+  class TransferJob;
+}
+
 class KMSender: public QObject
 {
   Q_OBJECT
   friend class KMSendProc;
 
 public:
-  enum Method { smUnknown=0, smSMTP=1, smMail=2 };
+  enum Method { smUnknown=0, smSMTP=1, smMail=2, smKIOSMTP = 3 };
 
   KMSender();
   virtual ~KMSender();
@@ -79,6 +87,14 @@ public:
   unsigned short int smtpPort(void) const { return mSmtpPort; }
   virtual void setSmtpPort(unsigned short int);
 
+  /** Username to use for loging in if appropriate */
+  QString username(void) const { return mUsername; }
+  virtual void setUsername(const QString&);
+
+  /** Password to use for loging in if appropriate */
+  QString password(void) const { return mPassword; }
+  virtual void setPassword(const QString&);
+
   /** Precommand - command run before sending */
   const QString& precommand(void) const { return mPrecommand; }
   virtual void setPrecommand(const QString& cmd) { mPrecommand = cmd; }
@@ -135,13 +151,18 @@ protected:
 
 private:
   Method mMethod;
-  bool mSendImmediate, mSendQuotedPrintable;
+  bool mSendImmediate;
+  bool mSendQuotedPrintable;
+  bool mUseSSL;
   QString mMailer;
   QString mSmtpHost;
+  QString mUsername;
+  QString mPassword;
   unsigned short int mSmtpPort;
   QString mPrecommand;
 
   bool mSentOk, mSendAborted;
+  bool mSendInfoChanged;
   QString mErrorMsg;
   KMIOStatusDlg* mSendDlg;
   KMSendProc *mSendProc, *mMsgSendProc;
@@ -163,7 +184,8 @@ class KMSendProc: public QObject
 
 public:
   KMSendProc(KMSender*);
-
+  virtual ~KMSendProc() {}
+  
   /** Initialize sending of one or more messages. */
   virtual void start(void);
 
@@ -179,6 +201,9 @@ public:
   /** Abort sending the current message. Sets mSending to false */
   virtual void abort() = 0;
 
+  /** Return the type so we can identify it at run time **/
+  virtual KMSender::Method sendType() { return KMSender::smUnknown; }
+  
   /** Returns TRUE if send was successful, and FALSE otherwise.
       Returns FALSE if sending is still in progress. */
   bool sendOk(void) const { return mSendOk; }
@@ -242,6 +267,7 @@ public:
   virtual bool send(KMMessage* msg);
   virtual bool finish(bool destructive);
   virtual void abort();
+  KMSender::Method sendType() { return KMSender::smMail; }
 
 protected slots:
   void receivedStderr(KProcess*,char*,int);
@@ -259,30 +285,33 @@ protected:
 };
 
 //-----------------------------------------------------------------------------
-#define KMSendSMTPInherited KMSendProc
-class KMSendSMTP: public KMSendProc
+class KMSendSMTP : public KMSendProc
 {
-  Q_OBJECT
+Q_OBJECT
 public:
-  KMSendSMTP(KMSender*,QString,unsigned short int);
-  virtual ~KMSendSMTP();
-  virtual void start(void);
-  virtual bool send(KMMessage* msg);
-  virtual bool finish(bool destructive);
+  KMSendSMTP(KMSender *_sender);
+  ~KMSendSMTP();
+  
+  virtual bool send(KMMessage *);
   virtual void abort();
-
-public slots:
-  virtual void smtpFailed(const QString&, const QString &);
+  virtual bool finish(bool);
+  KMSender::Method sendType() { return KMSender::smSMTP; }
 
 protected:
-  virtual bool smtpSend(KMMessage* msg);
-  virtual void smtpInCmd(const char* inCommand);
   virtual bool addOneRecipient(const QString& aRecipient);
 
-  Smtp *smtp;
-  QStringList recipients;
-  QString mSmtpHost;
-  unsigned short int mSmtpPort;
+private slots:
+  void dataReq(KIO::Job *, QByteArray &);
+  void result(KIO::Job *);
+  void slaveError(KIO::Slave *, int, const QString &);
+
+private:
+  QString mQuery;
+  QString mQueryField;
+  QCString mMessage;
+  
+  KIO::TransferJob *mJob;
+  KIO::Slave *mSlave;
 };
 
 #endif /*kmsender_h*/

["kio_smtp.patch" (text/x-diff)]

? kio_smtp
? kio_smtp.patch
Index: smtp.cc
===================================================================
RCS file: /home/projects/kdecvs/cvsroot/kdebase/kioslave/smtp/smtp.cc,v
retrieving revision 1.66
diff -u -3 -d -p -r1.66 smtp.cc
--- smtp.cc	2001/06/29 06:52:34	1.66
+++ smtp.cc	2001/07/16 23:18:55
@@ -145,6 +145,7 @@ void SMTPProtocol::HandleSMTPWriteError 
 // provided by that profile.  If it's not a profile name, it'll use it as
 // nature intended.
 // One can also specify in the query:
+// showfrom="Username" <emailaddress>
 // to=emailaddress
 // cc=emailaddress
 // bcc=emailaddress
@@ -245,7 +246,12 @@ void SMTPProtocol::put (const KURL &url,
 		HandleSMTPWriteError(open_url);
 	}
 
-	if (mset->getSetting(KEMailSettings::EmailAddress) != QString::null) {
+	GetAddresses(query, ASCII("showfrom="), temp_list);
+        if (temp_list.count()) {
+               from = ASCII("From: %1\r\n").arg(temp_list.last());
+               temp_list.clear();
+        }
+	else if (mset->getSetting(KEMailSettings::EmailAddress) != QString::null) {
 		if (mset->getSetting(KEMailSettings::RealName) != QString::null) {
 			from = ASCII("From: %1 \
<%2>\r\n").arg(mset->getSetting(KEMailSettings::RealName)).arg(mset->getSetting(KEMailSettings::EmailAddress));
  } else {


_______________________________________________
Kmail Developers mailing list
Kmail@master.kde.org
http://master.kde.org/mailman/listinfo/kmail


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic