kmail

kmacctlocal.cpp

Go to the documentation of this file.
00001 // kmacctlocal.cpp
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 #include "kmacctlocal.h"
00008 #include "kmfoldermbox.h"
00009 #include "kmacctfolder.h"
00010 #include "broadcaststatus.h"
00011 using KPIM::BroadcastStatus;
00012 #include "progressmanager.h"
00013 using KPIM::ProgressManager;
00014 
00015 #include "kmfoldermgr.h"
00016 
00017 #include <kapplication.h>
00018 #include <klocale.h>
00019 #include <kmessagebox.h>
00020 #include <kdebug.h>
00021 #include <kconfig.h>
00022 
00023 #include <qfileinfo.h>
00024 #include <qstylesheet.h>
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <errno.h>
00029 #include <assert.h>
00030 
00031 //-----------------------------------------------------------------------------
00032 KMAcctLocal::KMAcctLocal(AccountManager* aOwner, const QString& aAccountName, uint id):
00033   KMAccount(aOwner, aAccountName, id), mHasNewMail( false ),
00034   mAddedOk( true ), mNumMsgs( 0 ),
00035   mMsgsFetched( 0 ), mMailFolder( 0 )
00036 {
00037   mLock = procmail_lockfile;
00038 }
00039 
00040 
00041 //-----------------------------------------------------------------------------
00042 KMAcctLocal::~KMAcctLocal()
00043 {
00044 }
00045 
00046 
00047 //-----------------------------------------------------------------------------
00048 QString KMAcctLocal::type(void) const
00049 {
00050   return "local";
00051 }
00052 
00053 
00054 //-----------------------------------------------------------------------------
00055 void KMAcctLocal::init() {
00056   KMAccount::init();
00057 }
00058 
00059 
00060 //-----------------------------------------------------------------------------
00061 void KMAcctLocal::pseudoAssign( const KMAccount * a )
00062 {
00063   KMAccount::pseudoAssign( a );
00064 
00065   const KMAcctLocal * l = dynamic_cast<const KMAcctLocal*>( a );
00066   if ( !l ) return;
00067 
00068   setLocation( l->location() );
00069   setLockType( l->lockType() );
00070   setProcmailLockFileName( l->procmailLockFileName() );
00071 }
00072 
00073 //-----------------------------------------------------------------------------
00074 void KMAcctLocal::processNewMail(bool)
00075 {
00076   mHasNewMail = false;
00077 
00078   if ( !preProcess() ) {
00079     return;
00080   }
00081 
00082   QTime t;
00083   t.start();
00084 
00085   for ( mMsgsFetched = 0; mMsgsFetched < mNumMsgs; ++mMsgsFetched )
00086   {
00087     if ( !fetchMsg() )
00088       break;
00089 
00090     if (t.elapsed() >= 200) { //hardwired constant
00091       kapp->processEvents();
00092       t.start();
00093     }
00094   }
00095 
00096   postProcess();
00097 }
00098 
00099 
00100 //-----------------------------------------------------------------------------
00101 bool KMAcctLocal::preProcess()
00102 {
00103   if ( precommand().isEmpty() ) {
00104     QFileInfo fi( location() );
00105     if ( fi.size() == 0 ) {
00106       BroadcastStatus::instance()->setStatusMsgTransmissionCompleted( mName, 0 );
00107       checkDone( mHasNewMail, CheckOK );
00108       return false;
00109     }
00110   }
00111 
00112   mMailFolder = new KMFolder( 0, location(), KMFolderTypeMbox,
00113                               false /* no index */, false /* don't export sernums */ );
00114   KMFolderMbox* mboxStorage =
00115     static_cast<KMFolderMbox*>(mMailFolder->storage());
00116   mboxStorage->setLockType( mLock );
00117   if ( mLock == procmail_lockfile)
00118     mboxStorage->setProcmailLockFileName( mProcmailLockFileName );
00119 
00120   if (!mFolder) {
00121     checkDone( mHasNewMail, CheckError );
00122     BroadcastStatus::instance()->setStatusMsg( i18n( "Transmission failed." ));
00123     return false;
00124   }
00125 
00126   //BroadcastStatus::instance()->reset();
00127   BroadcastStatus::instance()->setStatusMsg(
00128         i18n("Preparing transmission from \"%1\"...").arg(mName));
00129 
00130 
00131   Q_ASSERT( !mMailCheckProgressItem );
00132   QString escapedName = QStyleSheet::escape( mName );
00133   mMailCheckProgressItem = KPIM::ProgressManager::createProgressItem(
00134     "MailCheck" + mName,
00135     escapedName,
00136     i18n("Preparing transmission from \"%1\"...").arg( escapedName ),
00137     false, // cannot be canceled
00138     false ); // no tls/ssl
00139 
00140   // run the precommand
00141   if (!runPrecommand(precommand()))
00142   {
00143     kdDebug(5006) << "cannot run precommand " << precommand() << endl;
00144     checkDone( mHasNewMail, CheckError );
00145     BroadcastStatus::instance()->setStatusMsg( i18n( "Running precommand failed." ));
00146     return false;
00147   }
00148 
00149   const int rc = mMailFolder->open("acctlocalMail");
00150   if ( rc != 0 ) {
00151     QString aStr;
00152     aStr = i18n("Cannot open file:");
00153     aStr += mMailFolder->path()+"/"+mMailFolder->name();
00154     KMessageBox::sorry(0, aStr);
00155     kdDebug(5006) << "cannot open file " << mMailFolder->path() << "/"
00156       << mMailFolder->name() << endl;
00157     checkDone( mHasNewMail, CheckError );
00158     BroadcastStatus::instance()->setStatusMsg( i18n( "Transmission failed." ));
00159     return false;
00160   }
00161 
00162   if (!mboxStorage->isLocked()) {
00163     kdDebug(5006) << "mailFolder could not be locked" << endl;
00164     mMailFolder->close("acctlocalMail");
00165     checkDone( mHasNewMail, CheckError );
00166     QString errMsg = i18n( "Transmission failed: Could not lock %1." )
00167       .arg( mMailFolder->location() );
00168     BroadcastStatus::instance()->setStatusMsg( errMsg );
00169     return false;
00170   }
00171 
00172   mFolder->open("acctlocalFold");
00173 
00174   mNumMsgs = mMailFolder->count();
00175 
00176   mMailCheckProgressItem->setTotalItems( mNumMsgs );
00177 
00178   // prepare the static parts of the status message:
00179   mStatusMsgStub = i18n("Moving message %3 of %2 from %1.")
00180     .arg(mMailFolder->location()).arg( mNumMsgs );
00181 
00182   //BroadcastStatus::instance()->setStatusProgressEnable( "L" + mName, true );
00183   return true;
00184 }
00185 
00186 
00187 //-----------------------------------------------------------------------------
00188 bool KMAcctLocal::fetchMsg()
00189 {
00190   KMMessage* msg;
00191 
00192   /* This causes mail eating
00193   if (kmkernel->mailCheckAborted()) break; */
00194 
00195   const QString statusMsg = mStatusMsgStub.arg( mMsgsFetched );
00196   //BroadcastStatus::instance()->setStatusMsg( statusMsg );
00197   mMailCheckProgressItem->incCompletedItems();
00198   mMailCheckProgressItem->updateProgress();
00199   mMailCheckProgressItem->setStatus( statusMsg );
00200 
00201   msg = mMailFolder->take(0);
00202   if (msg)
00203   {
00204 #if 0
00205     // debug code, don't remove
00206     QFile fileD0( "testdat_xx-0-0" );
00207     if( fileD0.open( IO_WriteOnly ) ) {
00208       QCString s = msg->asString();
00209       uint l = s.length();
00210       if ( l > 0 ) {
00211         QDataStream ds( &fileD0 );
00212         ds.writeRawBytes( s.data(), l );
00213       }
00214       fileD0.close();  // If data is 0 we just create a zero length file.
00215     }
00216 #endif
00217     msg->setStatus(msg->headerField("Status").latin1(),
00218       msg->headerField("X-Status").latin1());
00219     msg->setEncryptionStateChar( msg->headerField( "X-KMail-EncryptionState" ).at(0) );
00220     msg->setSignatureStateChar( msg->headerField( "X-KMail-SignatureState" ).at(0));
00221     msg->setComplete(true);
00222     msg->updateAttachmentState();
00223 
00224     mAddedOk = processNewMsg(msg);
00225 
00226     if (mAddedOk)
00227       mHasNewMail = true;
00228 
00229     return mAddedOk;
00230   }
00231   return true;
00232 }
00233 
00234 
00235 //-----------------------------------------------------------------------------
00236 void KMAcctLocal::postProcess()
00237 {
00238   if (mAddedOk)
00239   {
00240     kmkernel->folderMgr()->syncAllFolders();
00241     const int rc = mMailFolder->expunge();
00242     if ( rc != 0 ) {
00243       KMessageBox::queuedMessageBox( 0, KMessageBox::Information,
00244                                      i18n( "<qt>Cannot remove mail from "
00245                                            "mailbox <b>%1</b>:<br>%2</qt>" )
00246                                      .arg( mMailFolder->location() )
00247                                      .arg( strerror( rc ) ) );
00248     }
00249 
00250     if( mMailCheckProgressItem ) { // do this only once...
00251       BroadcastStatus::instance()->setStatusMsgTransmissionCompleted( mName, mNumMsgs );
00252       mMailCheckProgressItem->setStatus(
00253         i18n( "Fetched 1 message from mailbox %1.",
00254               "Fetched %n messages from mailbox %1.",
00255               mNumMsgs ).arg( mMailFolder->location() ) );
00256       mMailCheckProgressItem->setComplete();
00257       mMailCheckProgressItem = 0;
00258     }
00259   }
00260   // else warning is written already
00261 
00262   mMailFolder->close("acctlocalMail");
00263   delete mMailFolder; mMailFolder = 0;
00264 
00265   mFolder->close("acctlocalFold");
00266 
00267   checkDone( mHasNewMail, CheckOK );
00268 }
00269 
00270 
00271 //-----------------------------------------------------------------------------
00272 void KMAcctLocal::readConfig(KConfig& config)
00273 {
00274   KMAccount::readConfig(config);
00275   mLocation = config.readPathEntry("Location", mLocation);
00276   QString locktype = config.readEntry("LockType", "procmail_lockfile" );
00277 
00278   if( locktype == "procmail_lockfile" ) {
00279     mLock = procmail_lockfile;
00280     mProcmailLockFileName = config.readEntry("ProcmailLockFile",
00281       mLocation + ".lock");
00282   } else if( locktype == "mutt_dotlock" )
00283     mLock = mutt_dotlock;
00284   else if( locktype == "mutt_dotlock_privileged" )
00285     mLock = mutt_dotlock_privileged;
00286   else if( locktype == "none" )
00287     mLock = lock_none;
00288   else mLock = FCNTL;
00289 }
00290 
00291 
00292 //-----------------------------------------------------------------------------
00293 void KMAcctLocal::writeConfig(KConfig& config)
00294 {
00295   KMAccount::writeConfig(config);
00296 
00297   config.writePathEntry("Location", mLocation);
00298 
00299   QString st = "fcntl";
00300   if (mLock == procmail_lockfile) st = "procmail_lockfile";
00301   else if (mLock == mutt_dotlock) st = "mutt_dotlock";
00302   else if (mLock == mutt_dotlock_privileged) st = "mutt_dotlock_privileged";
00303   else if (mLock == lock_none) st = "none";
00304   config.writeEntry("LockType", st);
00305 
00306   if (mLock == procmail_lockfile) {
00307     config.writeEntry("ProcmailLockFile", mProcmailLockFileName);
00308   }
00309 
00310 }
00311 
00312 
00313 //-----------------------------------------------------------------------------
00314 void KMAcctLocal::setLocation(const QString& aLocation)
00315 {
00316     mLocation = aLocation;
00317 }
00318 
00319 void KMAcctLocal::setProcmailLockFileName(const QString& s)
00320 {
00321     mProcmailLockFileName = s;
00322 }